@signality/core 0.0.1-alpha.2

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 (261) hide show
  1. package/README.md +60 -0
  2. package/browser/battery/index.d.ts +34 -0
  3. package/browser/bluetooth/index.d.ts +56 -0
  4. package/browser/breakpoints/index.d.ts +32 -0
  5. package/browser/broadcast-channel/index.d.ts +42 -0
  6. package/browser/browser-language/index.d.ts +34 -0
  7. package/browser/clipboard/index.d.ts +48 -0
  8. package/browser/device-posture/index.d.ts +18 -0
  9. package/browser/display-media/index.d.ts +80 -0
  10. package/browser/eye-dropper/index.d.ts +47 -0
  11. package/browser/favicon/index.d.ts +39 -0
  12. package/browser/fps/index.d.ts +46 -0
  13. package/browser/gamepad/index.d.ts +28 -0
  14. package/browser/geolocation/index.d.ts +64 -0
  15. package/browser/index.d.ts +29 -0
  16. package/browser/input-modality/index.d.ts +26 -0
  17. package/browser/listener/index.d.ts +61 -0
  18. package/browser/media-query/index.d.ts +36 -0
  19. package/browser/network/index.d.ts +44 -0
  20. package/browser/online/index.d.ts +27 -0
  21. package/browser/page-visibility/index.d.ts +27 -0
  22. package/browser/picture-in-picture/index.d.ts +42 -0
  23. package/browser/pointer-lock-element/index.d.ts +22 -0
  24. package/browser/screen-orientation/index.d.ts +29 -0
  25. package/browser/speech-recognition/index.d.ts +77 -0
  26. package/browser/speech-synthesis/index.d.ts +76 -0
  27. package/browser/storage/index.d.ts +142 -0
  28. package/browser/text-direction/index.d.ts +43 -0
  29. package/browser/vibration/index.d.ts +37 -0
  30. package/browser/wake-lock/index.d.ts +37 -0
  31. package/browser/web-notification/index.d.ts +58 -0
  32. package/browser/web-share/index.d.ts +42 -0
  33. package/browser/web-worker/index.d.ts +52 -0
  34. package/elements/active-element/index.d.ts +27 -0
  35. package/elements/dropzone/index.d.ts +61 -0
  36. package/elements/element-focus/index.d.ts +38 -0
  37. package/elements/element-focus-within/index.d.ts +29 -0
  38. package/elements/element-hover/index.d.ts +27 -0
  39. package/elements/element-size/index.d.ts +40 -0
  40. package/elements/element-visibility/index.d.ts +53 -0
  41. package/elements/index.d.ts +16 -0
  42. package/elements/mouse-position/index.d.ts +64 -0
  43. package/elements/on-click-outside/index.d.ts +42 -0
  44. package/elements/on-disconnect/index.d.ts +45 -0
  45. package/elements/on-long-press/index.d.ts +44 -0
  46. package/elements/pointer-swipe/index.d.ts +58 -0
  47. package/elements/scroll-position/index.d.ts +96 -0
  48. package/elements/swipe/index.d.ts +49 -0
  49. package/elements/text-selection/index.d.ts +39 -0
  50. package/elements/window-size/index.d.ts +46 -0
  51. package/fesm2022/signality-core-browser-battery.mjs +80 -0
  52. package/fesm2022/signality-core-browser-battery.mjs.map +1 -0
  53. package/fesm2022/signality-core-browser-bluetooth.mjs +112 -0
  54. package/fesm2022/signality-core-browser-bluetooth.mjs.map +1 -0
  55. package/fesm2022/signality-core-browser-breakpoints.mjs +51 -0
  56. package/fesm2022/signality-core-browser-breakpoints.mjs.map +1 -0
  57. package/fesm2022/signality-core-browser-broadcast-channel.mjs +74 -0
  58. package/fesm2022/signality-core-browser-broadcast-channel.mjs.map +1 -0
  59. package/fesm2022/signality-core-browser-browser-language.mjs +48 -0
  60. package/fesm2022/signality-core-browser-browser-language.mjs.map +1 -0
  61. package/fesm2022/signality-core-browser-clipboard.mjs +102 -0
  62. package/fesm2022/signality-core-browser-clipboard.mjs.map +1 -0
  63. package/fesm2022/signality-core-browser-device-posture.mjs +40 -0
  64. package/fesm2022/signality-core-browser-device-posture.mjs.map +1 -0
  65. package/fesm2022/signality-core-browser-display-media.mjs +121 -0
  66. package/fesm2022/signality-core-browser-display-media.mjs.map +1 -0
  67. package/fesm2022/signality-core-browser-eye-dropper.mjs +82 -0
  68. package/fesm2022/signality-core-browser-eye-dropper.mjs.map +1 -0
  69. package/fesm2022/signality-core-browser-favicon.mjs +100 -0
  70. package/fesm2022/signality-core-browser-favicon.mjs.map +1 -0
  71. package/fesm2022/signality-core-browser-fps.mjs +103 -0
  72. package/fesm2022/signality-core-browser-fps.mjs.map +1 -0
  73. package/fesm2022/signality-core-browser-gamepad.mjs +93 -0
  74. package/fesm2022/signality-core-browser-gamepad.mjs.map +1 -0
  75. package/fesm2022/signality-core-browser-geolocation.mjs +120 -0
  76. package/fesm2022/signality-core-browser-geolocation.mjs.map +1 -0
  77. package/fesm2022/signality-core-browser-input-modality.mjs +64 -0
  78. package/fesm2022/signality-core-browser-input-modality.mjs.map +1 -0
  79. package/fesm2022/signality-core-browser-listener.mjs +132 -0
  80. package/fesm2022/signality-core-browser-listener.mjs.map +1 -0
  81. package/fesm2022/signality-core-browser-media-query.mjs +55 -0
  82. package/fesm2022/signality-core-browser-media-query.mjs.map +1 -0
  83. package/fesm2022/signality-core-browser-network.mjs +76 -0
  84. package/fesm2022/signality-core-browser-network.mjs.map +1 -0
  85. package/fesm2022/signality-core-browser-online.mjs +49 -0
  86. package/fesm2022/signality-core-browser-online.mjs.map +1 -0
  87. package/fesm2022/signality-core-browser-page-visibility.mjs +47 -0
  88. package/fesm2022/signality-core-browser-page-visibility.mjs.map +1 -0
  89. package/fesm2022/signality-core-browser-picture-in-picture.mjs +93 -0
  90. package/fesm2022/signality-core-browser-picture-in-picture.mjs.map +1 -0
  91. package/fesm2022/signality-core-browser-pointer-lock-element.mjs +43 -0
  92. package/fesm2022/signality-core-browser-pointer-lock-element.mjs.map +1 -0
  93. package/fesm2022/signality-core-browser-screen-orientation.mjs +43 -0
  94. package/fesm2022/signality-core-browser-screen-orientation.mjs.map +1 -0
  95. package/fesm2022/signality-core-browser-speech-recognition.mjs +171 -0
  96. package/fesm2022/signality-core-browser-speech-recognition.mjs.map +1 -0
  97. package/fesm2022/signality-core-browser-speech-synthesis.mjs +146 -0
  98. package/fesm2022/signality-core-browser-speech-synthesis.mjs.map +1 -0
  99. package/fesm2022/signality-core-browser-storage.mjs +261 -0
  100. package/fesm2022/signality-core-browser-storage.mjs.map +1 -0
  101. package/fesm2022/signality-core-browser-text-direction.mjs +62 -0
  102. package/fesm2022/signality-core-browser-text-direction.mjs.map +1 -0
  103. package/fesm2022/signality-core-browser-vibration.mjs +94 -0
  104. package/fesm2022/signality-core-browser-vibration.mjs.map +1 -0
  105. package/fesm2022/signality-core-browser-wake-lock.mjs +149 -0
  106. package/fesm2022/signality-core-browser-wake-lock.mjs.map +1 -0
  107. package/fesm2022/signality-core-browser-web-notification.mjs +137 -0
  108. package/fesm2022/signality-core-browser-web-notification.mjs.map +1 -0
  109. package/fesm2022/signality-core-browser-web-share.mjs +92 -0
  110. package/fesm2022/signality-core-browser-web-share.mjs.map +1 -0
  111. package/fesm2022/signality-core-browser-web-worker.mjs +105 -0
  112. package/fesm2022/signality-core-browser-web-worker.mjs.map +1 -0
  113. package/fesm2022/signality-core-browser.mjs +34 -0
  114. package/fesm2022/signality-core-browser.mjs.map +1 -0
  115. package/fesm2022/signality-core-elements-active-element.mjs +88 -0
  116. package/fesm2022/signality-core-elements-active-element.mjs.map +1 -0
  117. package/fesm2022/signality-core-elements-dropzone.mjs +158 -0
  118. package/fesm2022/signality-core-elements-dropzone.mjs.map +1 -0
  119. package/fesm2022/signality-core-elements-element-focus-within.mjs +56 -0
  120. package/fesm2022/signality-core-elements-element-focus-within.mjs.map +1 -0
  121. package/fesm2022/signality-core-elements-element-focus.mjs +54 -0
  122. package/fesm2022/signality-core-elements-element-focus.mjs.map +1 -0
  123. package/fesm2022/signality-core-elements-element-hover.mjs +48 -0
  124. package/fesm2022/signality-core-elements-element-hover.mjs.map +1 -0
  125. package/fesm2022/signality-core-elements-element-size.mjs +73 -0
  126. package/fesm2022/signality-core-elements-element-size.mjs.map +1 -0
  127. package/fesm2022/signality-core-elements-element-visibility.mjs +76 -0
  128. package/fesm2022/signality-core-elements-element-visibility.mjs.map +1 -0
  129. package/fesm2022/signality-core-elements-mouse-position.mjs +109 -0
  130. package/fesm2022/signality-core-elements-mouse-position.mjs.map +1 -0
  131. package/fesm2022/signality-core-elements-on-click-outside.mjs +97 -0
  132. package/fesm2022/signality-core-elements-on-click-outside.mjs.map +1 -0
  133. package/fesm2022/signality-core-elements-on-disconnect.mjs +99 -0
  134. package/fesm2022/signality-core-elements-on-disconnect.mjs.map +1 -0
  135. package/fesm2022/signality-core-elements-on-long-press.mjs +84 -0
  136. package/fesm2022/signality-core-elements-on-long-press.mjs.map +1 -0
  137. package/fesm2022/signality-core-elements-pointer-swipe.mjs +116 -0
  138. package/fesm2022/signality-core-elements-pointer-swipe.mjs.map +1 -0
  139. package/fesm2022/signality-core-elements-scroll-position.mjs +175 -0
  140. package/fesm2022/signality-core-elements-scroll-position.mjs.map +1 -0
  141. package/fesm2022/signality-core-elements-swipe.mjs +107 -0
  142. package/fesm2022/signality-core-elements-swipe.mjs.map +1 -0
  143. package/fesm2022/signality-core-elements-text-selection.mjs +70 -0
  144. package/fesm2022/signality-core-elements-text-selection.mjs.map +1 -0
  145. package/fesm2022/signality-core-elements-window-size.mjs +81 -0
  146. package/fesm2022/signality-core-elements-window-size.mjs.map +1 -0
  147. package/fesm2022/signality-core-elements.mjs +21 -0
  148. package/fesm2022/signality-core-elements.mjs.map +1 -0
  149. package/fesm2022/signality-core-forms-cva.mjs +140 -0
  150. package/fesm2022/signality-core-forms-cva.mjs.map +1 -0
  151. package/fesm2022/signality-core-forms.mjs +6 -0
  152. package/fesm2022/signality-core-forms.mjs.map +1 -0
  153. package/fesm2022/signality-core-internal.mjs +268 -0
  154. package/fesm2022/signality-core-internal.mjs.map +1 -0
  155. package/fesm2022/signality-core-observers-intersection-observer.mjs +70 -0
  156. package/fesm2022/signality-core-observers-intersection-observer.mjs.map +1 -0
  157. package/fesm2022/signality-core-observers-mutation-observer.mjs +77 -0
  158. package/fesm2022/signality-core-observers-mutation-observer.mjs.map +1 -0
  159. package/fesm2022/signality-core-observers-performance-observer.mjs +84 -0
  160. package/fesm2022/signality-core-observers-performance-observer.mjs.map +1 -0
  161. package/fesm2022/signality-core-observers-resize-observer.mjs +69 -0
  162. package/fesm2022/signality-core-observers-resize-observer.mjs.map +1 -0
  163. package/fesm2022/signality-core-observers.mjs +9 -0
  164. package/fesm2022/signality-core-observers.mjs.map +1 -0
  165. package/fesm2022/signality-core-reactivity-debounced.mjs +27 -0
  166. package/fesm2022/signality-core-reactivity-debounced.mjs.map +1 -0
  167. package/fesm2022/signality-core-reactivity-throttled.mjs +27 -0
  168. package/fesm2022/signality-core-reactivity-throttled.mjs.map +1 -0
  169. package/fesm2022/signality-core-reactivity-watcher.mjs +36 -0
  170. package/fesm2022/signality-core-reactivity-watcher.mjs.map +1 -0
  171. package/fesm2022/signality-core-reactivity.mjs +8 -0
  172. package/fesm2022/signality-core-reactivity.mjs.map +1 -0
  173. package/fesm2022/signality-core-router-fragment.mjs +41 -0
  174. package/fesm2022/signality-core-router-fragment.mjs.map +1 -0
  175. package/fesm2022/signality-core-router-params.mjs +45 -0
  176. package/fesm2022/signality-core-router-params.mjs.map +1 -0
  177. package/fesm2022/signality-core-router-query-params.mjs +67 -0
  178. package/fesm2022/signality-core-router-query-params.mjs.map +1 -0
  179. package/fesm2022/signality-core-router-route-data.mjs +46 -0
  180. package/fesm2022/signality-core-router-route-data.mjs.map +1 -0
  181. package/fesm2022/signality-core-router-router-listener.mjs +50 -0
  182. package/fesm2022/signality-core-router-router-listener.mjs.map +1 -0
  183. package/fesm2022/signality-core-router-title.mjs +54 -0
  184. package/fesm2022/signality-core-router-title.mjs.map +1 -0
  185. package/fesm2022/signality-core-router-url.mjs +53 -0
  186. package/fesm2022/signality-core-router-url.mjs.map +1 -0
  187. package/fesm2022/signality-core-router.mjs +12 -0
  188. package/fesm2022/signality-core-router.mjs.map +1 -0
  189. package/fesm2022/signality-core-scheduling-debounce-callback.mjs +59 -0
  190. package/fesm2022/signality-core-scheduling-debounce-callback.mjs.map +1 -0
  191. package/fesm2022/signality-core-scheduling-interval.mjs +110 -0
  192. package/fesm2022/signality-core-scheduling-interval.mjs.map +1 -0
  193. package/fesm2022/signality-core-scheduling-throttle-callback.mjs +66 -0
  194. package/fesm2022/signality-core-scheduling-throttle-callback.mjs.map +1 -0
  195. package/fesm2022/signality-core-scheduling.mjs +8 -0
  196. package/fesm2022/signality-core-scheduling.mjs.map +1 -0
  197. package/fesm2022/signality-core-types.mjs +4 -0
  198. package/fesm2022/signality-core-types.mjs.map +1 -0
  199. package/fesm2022/signality-core.mjs +13 -0
  200. package/fesm2022/signality-core.mjs.map +1 -0
  201. package/forms/cva/index.d.ts +60 -0
  202. package/forms/index.d.ts +1 -0
  203. package/index.d.ts +8 -0
  204. package/internal/constants/index.d.ts +2 -0
  205. package/internal/constants/mobile-regex.d.ts +1 -0
  206. package/internal/constants/stubs.d.ts +32 -0
  207. package/internal/index.d.ts +4 -0
  208. package/internal/providers/index.d.ts +3 -0
  209. package/internal/providers/is-browser.d.ts +2 -0
  210. package/internal/providers/is-mobile.d.ts +2 -0
  211. package/internal/providers/is-server.d.ts +2 -0
  212. package/internal/types/index.d.ts +2 -0
  213. package/internal/types/timer.d.ts +1 -0
  214. package/internal/types/union.d.ts +1 -0
  215. package/internal/utils/bom/index.d.ts +1 -0
  216. package/internal/utils/bom/is-window.d.ts +1 -0
  217. package/internal/utils/const-signal.d.ts +10 -0
  218. package/internal/utils/context.d.ts +18 -0
  219. package/internal/utils/create-token.d.ts +8 -0
  220. package/internal/utils/dom/get-active-element.d.ts +1 -0
  221. package/internal/utils/dom/get-event-target.d.ts +1 -0
  222. package/internal/utils/dom/get-pip-element.d.ts +1 -0
  223. package/internal/utils/dom/get-shadow-root.d.ts +1 -0
  224. package/internal/utils/dom/index.d.ts +6 -0
  225. package/internal/utils/dom/is-element.d.ts +1 -0
  226. package/internal/utils/dom/is-node-within.d.ts +1 -0
  227. package/internal/utils/index.d.ts +10 -0
  228. package/internal/utils/is-plain-object.d.ts +1 -0
  229. package/internal/utils/is-query-signal.d.ts +10 -0
  230. package/internal/utils/proxy-signal.d.ts +18 -0
  231. package/internal/utils/to-element.d.ts +12 -0
  232. package/internal/utils/to-value.d.ts +6 -0
  233. package/observers/index.d.ts +4 -0
  234. package/observers/intersection-observer/index.d.ts +42 -0
  235. package/observers/mutation-observer/index.d.ts +45 -0
  236. package/observers/performance-observer/index.d.ts +58 -0
  237. package/observers/resize-observer/index.d.ts +40 -0
  238. package/package.json +343 -0
  239. package/reactivity/debounced/index.d.ts +50 -0
  240. package/reactivity/index.d.ts +3 -0
  241. package/reactivity/throttled/index.d.ts +53 -0
  242. package/reactivity/watcher/index.d.ts +68 -0
  243. package/router/fragment/index.d.ts +26 -0
  244. package/router/index.d.ts +7 -0
  245. package/router/params/index.d.ts +28 -0
  246. package/router/query-params/index.d.ts +80 -0
  247. package/router/route-data/index.d.ts +28 -0
  248. package/router/router-listener/index.d.ts +83 -0
  249. package/router/title/index.d.ts +29 -0
  250. package/router/url/index.d.ts +32 -0
  251. package/scheduling/debounce-callback/index.d.ts +28 -0
  252. package/scheduling/index.d.ts +3 -0
  253. package/scheduling/interval/index.d.ts +51 -0
  254. package/scheduling/throttle-callback/index.d.ts +30 -0
  255. package/types/index.d.ts +6 -0
  256. package/types/maybe-element-signal.d.ts +2 -0
  257. package/types/maybe-signal.d.ts +2 -0
  258. package/types/signal-value.d.ts +2 -0
  259. package/types/signal-values.d.ts +5 -0
  260. package/types/unref-element.d.ts +2 -0
  261. package/types/with-injector.d.ts +8 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-observers-mutation-observer.mjs","sources":["../../../projects/core/observers/mutation-observer/index.ts","../../../projects/core/observers/mutation-observer/signality-core-observers-mutation-observer.ts"],"sourcesContent":["import {\n afterRenderEffect,\n type CreateEffectOptions,\n type EffectCleanupRegisterFn,\n} from '@angular/core';\nimport { NOOP_EFFECT_REF, setupContext, toElement, toValue } from '@signality/core/internal';\nimport type { MaybeElementSignal, MaybeSignal } from '@signality/core/types';\n\nexport interface MutationObserverInitOptions\n extends Omit<CreateEffectOptions, 'allowSignalWrites'> {\n readonly childList?: MaybeSignal<boolean>;\n readonly attributes?: MaybeSignal<boolean>;\n readonly characterData?: MaybeSignal<boolean>;\n readonly subtree?: MaybeSignal<boolean>;\n readonly attributeOldValue?: MaybeSignal<boolean>;\n readonly characterDataOldValue?: MaybeSignal<boolean>;\n readonly attributeFilter?: MaybeSignal<string[]>;\n}\n\nexport interface MutationObserverRef {\n readonly destroy: () => void;\n}\n\n/**\n * Low-level utility for observing DOM tree changes using the [MutationObserver API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).\n * Provides fine-grained control over the observation lifecycle.\n *\n * @param target - Element(s) to observe\n * @param callback - Callback function called when DOM mutations occur\n * @param options - Optional configuration (see {@link MutationObserverInitOptions})\n * @returns MutationObserverRef with a `destroy()` method to stop observing the element(s)\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div #container>\n * <p>Children: {{ childCount() }}</p>\n * </div>\n * `\n * })\n * class MutationComponent {\n * readonly container = viewChild<ElementRef>('container');\n * readonly childCount = signal(0);\n *\n * constructor() {\n * mutationObserver(this.container, mutations => {\n * this.childCount.set(mutations[0].target.childNodes.length);\n * }, { childList: true });\n * }\n * }\n * ```\n */\nexport function mutationObserver(\n target: MaybeElementSignal<Element> | MaybeElementSignal<Element>[],\n callback: (mutations: readonly MutationRecord[], observer: MutationObserver) => void,\n options: MutationObserverInitOptions\n): MutationObserverRef {\n const { runInContext } = setupContext(options.injector, mutationObserver);\n\n return runInContext(({ isServer }) => {\n if (isServer) {\n return NOOP_EFFECT_REF;\n }\n\n const targets = Array.isArray(target) ? target : [target];\n\n const setupObserver = (onCleanup: EffectCleanupRegisterFn) => {\n const els = targets.map(toElement).filter(Boolean);\n\n if (!els.length) {\n return;\n }\n\n const childList = toValue(options.childList);\n const attributes = toValue(options.attributes);\n const characterData = toValue(options.characterData);\n const subtree = toValue(options.subtree);\n const attributeOldValue = toValue(options.attributeOldValue);\n const characterDataOldValue = toValue(options.characterDataOldValue);\n const attributeFilter = toValue(options.attributeFilter);\n\n const observer = new MutationObserver(callback);\n\n for (const el of els) {\n observer.observe(el!, {\n childList,\n attributes,\n characterData,\n subtree,\n attributeOldValue,\n characterDataOldValue,\n attributeFilter,\n });\n }\n\n onCleanup(observer.disconnect.bind(observer));\n };\n\n const effectRef = afterRenderEffect({ read: setupObserver }, options);\n\n return { destroy: () => effectRef.destroy() };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BG;SACa,gBAAgB,CAC9B,MAAmE,EACnE,QAAoF,EACpF,OAAoC,EAAA;AAEpC,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC;AAEzE,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAI;QACnC,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,eAAe;QACxB;AAEA,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;AAEzD,QAAA,MAAM,aAAa,GAAG,CAAC,SAAkC,KAAI;AAC3D,YAAA,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAElD,YAAA,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;gBACf;YACF;YAEA,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;YAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;YAC9C,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;YACpD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;YACxC,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;YAC5D,MAAM,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC;YACpE,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC;AAExD,YAAA,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC;AAE/C,YAAA,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE;AACpB,gBAAA,QAAQ,CAAC,OAAO,CAAC,EAAG,EAAE;oBACpB,SAAS;oBACT,UAAU;oBACV,aAAa;oBACb,OAAO;oBACP,iBAAiB;oBACjB,qBAAqB;oBACrB,eAAe;AAChB,iBAAA,CAAC;YACJ;YAEA,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/C,QAAA,CAAC;AAED,QAAA,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC;QAErE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC,OAAO,EAAE,EAAE;AAC/C,IAAA,CAAC,CAAC;AACJ;;ACvGA;;AAEG;;;;"}
@@ -0,0 +1,84 @@
1
+ import { afterRenderEffect } from '@angular/core';
2
+ import { setupContext, NOOP_EFFECT_REF, toValue } from '@signality/core/internal';
3
+
4
+ /**
5
+ * Low-level utility for observing performance measurement events using the [Performance Observer API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver).
6
+ * Provides reactive access to performance entries as they are recorded in the browser's performance timeline.
7
+ *
8
+ * @param callback - Callback function called when performance entries are recorded
9
+ * @param options - Optional configuration (see {@link PerformanceObserverInitOptions})
10
+ * @returns PerformanceObserverRef with a `destroy()` method to stop observing
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * @Component({
15
+ * template: `
16
+ * <div>LCP: {{ lcp() }}ms</div>
17
+ * `
18
+ * })
19
+ * class PerformanceComponent {
20
+ * readonly lcp = signal(0);
21
+ *
22
+ * constructor() {
23
+ * performanceObserver(entries => {
24
+ * const lcpEntry = entries.find(e => e.entryType === 'largest-contentful-paint');
25
+ * if (lcpEntry) {
26
+ * this.lcp.set(Math.round(lcpEntry.startTime));
27
+ * }
28
+ * }, { entryTypes: ['largest-contentful-paint'] });
29
+ * }
30
+ * }
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Track long tasks
36
+ * performanceObserver(entries => {
37
+ * entries.forEach(entry => {
38
+ * console.log('Long task:', entry.duration);
39
+ * });
40
+ * }, { entryTypes: ['longtask'] });
41
+ * ```
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * // Using type (single entry type, legacy API)
46
+ * performanceObserver(entries => {
47
+ * console.log('Navigation timing:', entries[0]);
48
+ * }, { type: 'navigation', buffered: true });
49
+ * ```
50
+ */
51
+ function performanceObserver(callback, options) {
52
+ const { runInContext } = setupContext(options?.injector, performanceObserver);
53
+ return runInContext(({ isServer }) => {
54
+ if (isServer) {
55
+ return NOOP_EFFECT_REF;
56
+ }
57
+ const setupObserver = (onCleanup) => {
58
+ const entryTypes = toValue(options?.entryTypes);
59
+ const type = toValue(options?.type);
60
+ const buffered = toValue(options?.buffered);
61
+ if (!entryTypes && !type) {
62
+ console.warn('[PerformanceObserver] Either entryTypes or type must be provided. ' +
63
+ 'See https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver/observe');
64
+ return;
65
+ }
66
+ const observer = new PerformanceObserver(callback);
67
+ observer.observe({
68
+ entryTypes,
69
+ type,
70
+ buffered,
71
+ });
72
+ onCleanup(observer.disconnect.bind(observer));
73
+ };
74
+ const effectRef = afterRenderEffect({ read: setupObserver }, options);
75
+ return { destroy: () => effectRef.destroy() };
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Generated bundle index. Do not edit.
81
+ */
82
+
83
+ export { performanceObserver };
84
+ //# sourceMappingURL=signality-core-observers-performance-observer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-observers-performance-observer.mjs","sources":["../../../projects/core/observers/performance-observer/index.ts","../../../projects/core/observers/performance-observer/signality-core-observers-performance-observer.ts"],"sourcesContent":["import {\n afterRenderEffect,\n type CreateEffectOptions,\n type EffectCleanupRegisterFn,\n} from '@angular/core';\nimport { NOOP_EFFECT_REF, setupContext, toValue } from '@signality/core/internal';\nimport type { MaybeSignal } from '@signality/core/types';\n\nexport interface PerformanceObserverInitOptions\n extends Omit<CreateEffectOptions, 'allowSignalWrites'> {\n readonly entryTypes?: MaybeSignal<string[]>;\n readonly type?: MaybeSignal<string>;\n readonly buffered?: MaybeSignal<boolean>;\n}\n\nexport interface PerformanceObserverRef {\n readonly destroy: () => void;\n}\n\n/**\n * Low-level utility for observing performance measurement events using the [Performance Observer API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver).\n * Provides reactive access to performance entries as they are recorded in the browser's performance timeline.\n *\n * @param callback - Callback function called when performance entries are recorded\n * @param options - Optional configuration (see {@link PerformanceObserverInitOptions})\n * @returns PerformanceObserverRef with a `destroy()` method to stop observing\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>LCP: {{ lcp() }}ms</div>\n * `\n * })\n * class PerformanceComponent {\n * readonly lcp = signal(0);\n *\n * constructor() {\n * performanceObserver(entries => {\n * const lcpEntry = entries.find(e => e.entryType === 'largest-contentful-paint');\n * if (lcpEntry) {\n * this.lcp.set(Math.round(lcpEntry.startTime));\n * }\n * }, { entryTypes: ['largest-contentful-paint'] });\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Track long tasks\n * performanceObserver(entries => {\n * entries.forEach(entry => {\n * console.log('Long task:', entry.duration);\n * });\n * }, { entryTypes: ['longtask'] });\n * ```\n *\n * @example\n * ```typescript\n * // Using type (single entry type, legacy API)\n * performanceObserver(entries => {\n * console.log('Navigation timing:', entries[0]);\n * }, { type: 'navigation', buffered: true });\n * ```\n */\nexport function performanceObserver(\n callback: PerformanceObserverCallback,\n options?: PerformanceObserverInitOptions\n): PerformanceObserverRef {\n const { runInContext } = setupContext(options?.injector, performanceObserver);\n\n return runInContext(({ isServer }) => {\n if (isServer) {\n return NOOP_EFFECT_REF;\n }\n\n const setupObserver = (onCleanup: EffectCleanupRegisterFn) => {\n const entryTypes = toValue(options?.entryTypes);\n const type = toValue(options?.type);\n const buffered = toValue(options?.buffered);\n\n if (!entryTypes && !type) {\n console.warn(\n '[PerformanceObserver] Either entryTypes or type must be provided. ' +\n 'See https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver/observe'\n );\n return;\n }\n\n const observer = new PerformanceObserver(callback);\n\n observer.observe({\n entryTypes,\n type,\n buffered,\n });\n\n onCleanup(observer.disconnect.bind(observer));\n };\n\n const effectRef = afterRenderEffect({ read: setupObserver }, options);\n\n return { destroy: () => effectRef.destroy() };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CG;AACG,SAAU,mBAAmB,CACjC,QAAqC,EACrC,OAAwC,EAAA;AAExC,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,mBAAmB,CAAC;AAE7E,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAI;QACnC,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,eAAe;QACxB;AAEA,QAAA,MAAM,aAAa,GAAG,CAAC,SAAkC,KAAI;YAC3D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC;YAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;YACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;AAE3C,YAAA,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,EAAE;gBACxB,OAAO,CAAC,IAAI,CACV,oEAAoE;AAClE,oBAAA,kFAAkF,CACrF;gBACD;YACF;AAEA,YAAA,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,QAAQ,CAAC;YAElD,QAAQ,CAAC,OAAO,CAAC;gBACf,UAAU;gBACV,IAAI;gBACJ,QAAQ;AACT,aAAA,CAAC;YAEF,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/C,QAAA,CAAC;AAED,QAAA,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC;QAErE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC,OAAO,EAAE,EAAE;AAC/C,IAAA,CAAC,CAAC;AACJ;;ACzGA;;AAEG;;;;"}
@@ -0,0 +1,69 @@
1
+ import { afterRenderEffect } from '@angular/core';
2
+ import { setupContext, NOOP_EFFECT_REF, toElement, toValue } from '@signality/core/internal';
3
+
4
+ /**
5
+ * Low-level utility for observing element size changes using the [ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
6
+ * Provides fine-grained control over the observation lifecycle.
7
+ *
8
+ * @param target - Element(s) to observe
9
+ * @param callback - Callback function called when element size changes
10
+ * @param options - Optional configuration (see {@link ResizeObserverInitOptions})
11
+ * @returns ResizeObserverRef with a `destroy()` method to stop observing the element(s)
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * @Component({
16
+ * template: `
17
+ * <div #resizable>
18
+ * Size: {{ size().width }} × {{ size().height }}px
19
+ * </div>
20
+ * `
21
+ * })
22
+ * class ResizeComponent {
23
+ * readonly resizable = viewChild<ElementRef>('resizable');
24
+ * readonly size = signal({ width: 0, height: 0 });
25
+ *
26
+ * constructor() {
27
+ * resizeObserver(this.resizable, entries => {
28
+ * const { width, height } = entries[0].contentRect;
29
+ * this.size.set({ width, height });
30
+ * });
31
+ * }
32
+ * }
33
+ * ```
34
+ */
35
+ function resizeObserver(target, callback, options) {
36
+ const { runInContext } = setupContext(options?.injector, resizeObserver);
37
+ return runInContext(({ isServer, onCleanup }) => {
38
+ if (isServer) {
39
+ return NOOP_EFFECT_REF;
40
+ }
41
+ const targets = Array.isArray(target) ? target : [target];
42
+ let observer = null;
43
+ const setupObserver = (onCleanup) => {
44
+ const els = targets.map(toElement).filter(Boolean);
45
+ if (!els.length) {
46
+ return;
47
+ }
48
+ const box = toValue(options?.box);
49
+ observer ??= new ResizeObserver(callback);
50
+ for (const el of els) {
51
+ observer.observe(el, { box });
52
+ }
53
+ onCleanup(() => {
54
+ els.forEach(el => observer?.unobserve(el));
55
+ });
56
+ };
57
+ const destroy = () => observer?.disconnect();
58
+ onCleanup(destroy);
59
+ afterRenderEffect({ read: setupObserver }, options);
60
+ return { destroy };
61
+ });
62
+ }
63
+
64
+ /**
65
+ * Generated bundle index. Do not edit.
66
+ */
67
+
68
+ export { resizeObserver };
69
+ //# sourceMappingURL=signality-core-observers-resize-observer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-observers-resize-observer.mjs","sources":["../../../projects/core/observers/resize-observer/index.ts","../../../projects/core/observers/resize-observer/signality-core-observers-resize-observer.ts"],"sourcesContent":["import {\n afterRenderEffect,\n type CreateEffectOptions,\n type EffectCleanupRegisterFn,\n} from '@angular/core';\nimport { NOOP_EFFECT_REF, setupContext, toElement, toValue } from '@signality/core/internal';\nimport type { MaybeElementSignal, MaybeSignal } from '@signality/core/types';\n\nexport interface ResizeObserverInitOptions extends Omit<CreateEffectOptions, 'allowSignalWrites'> {\n readonly box?: MaybeSignal<ResizeObserverBoxOptions>;\n}\n\nexport interface ResizeObserverRef {\n readonly destroy: () => void;\n}\n\n/**\n * Low-level utility for observing element size changes using the [ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n * Provides fine-grained control over the observation lifecycle.\n *\n * @param target - Element(s) to observe\n * @param callback - Callback function called when element size changes\n * @param options - Optional configuration (see {@link ResizeObserverInitOptions})\n * @returns ResizeObserverRef with a `destroy()` method to stop observing the element(s)\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div #resizable>\n * Size: {{ size().width }} × {{ size().height }}px\n * </div>\n * `\n * })\n * class ResizeComponent {\n * readonly resizable = viewChild<ElementRef>('resizable');\n * readonly size = signal({ width: 0, height: 0 });\n *\n * constructor() {\n * resizeObserver(this.resizable, entries => {\n * const { width, height } = entries[0].contentRect;\n * this.size.set({ width, height });\n * });\n * }\n * }\n * ```\n */\nexport function resizeObserver(\n target: MaybeElementSignal<Element> | MaybeElementSignal<Element>[],\n callback: (entries: readonly ResizeObserverEntry[]) => void,\n options?: ResizeObserverInitOptions\n): ResizeObserverRef {\n const { runInContext } = setupContext(options?.injector, resizeObserver);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return NOOP_EFFECT_REF;\n }\n\n const targets = Array.isArray(target) ? target : [target];\n\n let observer: ResizeObserver | null = null;\n\n const setupObserver = (onCleanup: EffectCleanupRegisterFn) => {\n const els = targets.map(toElement).filter(Boolean);\n\n if (!els.length) {\n return;\n }\n\n const box = toValue(options?.box);\n\n observer ??= new ResizeObserver(callback);\n\n for (const el of els) {\n observer.observe(el!, { box });\n }\n\n onCleanup(() => {\n els.forEach(el => observer?.unobserve(el!));\n });\n };\n\n const destroy = () => observer?.disconnect();\n\n onCleanup(destroy);\n\n afterRenderEffect({ read: setupObserver }, options);\n\n return { destroy };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BG;SACa,cAAc,CAC5B,MAAmE,EACnE,QAA2D,EAC3D,OAAmC,EAAA;AAEnC,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC;IAExE,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAI;QAC9C,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,eAAe;QACxB;AAEA,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;QAEzD,IAAI,QAAQ,GAA0B,IAAI;AAE1C,QAAA,MAAM,aAAa,GAAG,CAAC,SAAkC,KAAI;AAC3D,YAAA,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAElD,YAAA,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;gBACf;YACF;YAEA,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;AAEjC,YAAA,QAAQ,KAAK,IAAI,cAAc,CAAC,QAAQ,CAAC;AAEzC,YAAA,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE;gBACpB,QAAQ,CAAC,OAAO,CAAC,EAAG,EAAE,EAAE,GAAG,EAAE,CAAC;YAChC;YAEA,SAAS,CAAC,MAAK;AACb,gBAAA,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,QAAQ,EAAE,SAAS,CAAC,EAAG,CAAC,CAAC;AAC7C,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,EAAE,UAAU,EAAE;QAE5C,SAAS,CAAC,OAAO,CAAC;QAElB,iBAAiB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC;QAEnD,OAAO,EAAE,OAAO,EAAE;AACpB,IAAA,CAAC,CAAC;AACJ;;AC3FA;;AAEG;;;;"}
@@ -0,0 +1,9 @@
1
+ export * from '@signality/core/observers/intersection-observer';
2
+ export * from '@signality/core/observers/mutation-observer';
3
+ export * from '@signality/core/observers/performance-observer';
4
+ export * from '@signality/core/observers/resize-observer';
5
+
6
+ /**
7
+ * Generated bundle index. Do not edit.
8
+ */
9
+ //# sourceMappingURL=signality-core-observers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-observers.mjs","sources":["../../../projects/core/observers/signality-core-observers.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAAA;;AAEG"}
@@ -0,0 +1,27 @@
1
+ import { signal, isSignal } from '@angular/core';
2
+ import { setupContext, toValue, proxySignal } from '@signality/core/internal';
3
+ import { debounceCallback } from '@signality/core/scheduling/debounce-callback';
4
+ import { watcher } from '@signality/core/reactivity/watcher';
5
+
6
+ function debounced(valueOrSignal, timeMs, options) {
7
+ const { runInContext } = setupContext(options?.injector, debounced);
8
+ return runInContext(() => {
9
+ const initialValue = toValue(valueOrSignal);
10
+ const output = signal(initialValue, options);
11
+ const set = debounceCallback(output.set, timeMs);
12
+ if (isSignal(valueOrSignal)) {
13
+ watcher(valueOrSignal, set);
14
+ return output.asReadonly();
15
+ }
16
+ else {
17
+ return proxySignal(output, { set });
18
+ }
19
+ });
20
+ }
21
+
22
+ /**
23
+ * Generated bundle index. Do not edit.
24
+ */
25
+
26
+ export { debounced };
27
+ //# sourceMappingURL=signality-core-reactivity-debounced.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-reactivity-debounced.mjs","sources":["../../../projects/core/reactivity/debounced/index.ts","../../../projects/core/reactivity/debounced/signality-core-reactivity-debounced.ts"],"sourcesContent":["import {\n type CreateSignalOptions,\n isSignal,\n signal,\n type Signal,\n type WritableSignal,\n} from '@angular/core';\nimport { proxySignal, setupContext, toValue } from '@signality/core/internal';\nimport type { MaybeSignal, SignalValue, WithInjector } from '@signality/core/types';\nimport { debounceCallback } from '@signality/core/scheduling/debounce-callback';\nimport { watcher } from '@signality/core/reactivity/watcher';\n\nexport type DebouncedOptions<T> = CreateSignalOptions<T> & WithInjector;\n\n/**\n * Creates a debounced readonly signal from a source signal.\n * Updates to the source signal are debounced before propagating to the returned signal.\n *\n * @param source - Source signal to debounce\n * @param timeMs - Debounce delay in milliseconds\n * @param options - Optional configuration including signal options and injector\n * @returns A readonly signal that updates after the debounce delay\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input [(ngModel)]=\"query\" />\n * <p>Debounced value: {{ debouncedQuery() }}</p>\n * `\n * })\n * class SearchInput {\n * readonly query = signal('');\n * readonly debouncedQuery = debounced(this.query, 300);\n * }\n * ```\n */\nexport function debounced<S extends Signal<any>>(\n source: S,\n timeMs: MaybeSignal<number>,\n options?: DebouncedOptions<SignalValue<S>>\n): Signal<SignalValue<S>>;\n\n/**\n * Creates a debounced writable signal from an initial value.\n * Both `set()` and `update()` calls are debounced.\n *\n * @param value - Initial value\n * @param timeMs - Debounce delay in milliseconds\n * @param options - Optional configuration including signal options and injector\n * @returns A writable signal where updates are debounced\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input [(ngModel)]=\"query\" />\n * <p>Search results for: {{ query() }}</p>\n * `\n * })\n * class SearchInput {\n * readonly query = debounced('', 300);\n * }\n * ```\n */\nexport function debounced<V>(\n value: V,\n timeMs: MaybeSignal<number>,\n options?: DebouncedOptions<V>\n): WritableSignal<V>;\n\nexport function debounced(\n valueOrSignal: any,\n timeMs: MaybeSignal<number>,\n options?: DebouncedOptions<any>\n) {\n const { runInContext } = setupContext(options?.injector, debounced);\n\n return runInContext(() => {\n const initialValue = toValue(valueOrSignal);\n const output = signal(initialValue, options);\n const set = debounceCallback(output.set, timeMs);\n\n if (isSignal(valueOrSignal)) {\n watcher(valueOrSignal, set);\n return output.asReadonly();\n } else {\n return proxySignal(output, { set });\n }\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;SAuEgB,SAAS,CACvB,aAAkB,EAClB,MAA2B,EAC3B,OAA+B,EAAA;AAE/B,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;IAEnE,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC;QAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC;AAEhD,QAAA,IAAI,QAAQ,CAAC,aAAa,CAAC,EAAE;AAC3B,YAAA,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;AAC3B,YAAA,OAAO,MAAM,CAAC,UAAU,EAAE;QAC5B;aAAO;YACL,OAAO,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC;QACrC;AACF,IAAA,CAAC,CAAC;AACJ;;AC1FA;;AAEG;;;;"}
@@ -0,0 +1,27 @@
1
+ import { signal, isSignal } from '@angular/core';
2
+ import { setupContext, toValue, proxySignal } from '@signality/core/internal';
3
+ import { throttleCallback } from '@signality/core/scheduling/throttle-callback';
4
+ import { watcher } from '@signality/core/reactivity/watcher';
5
+
6
+ function throttled(valueOrSignal, timeMs, options) {
7
+ const { runInContext } = setupContext(options?.injector, throttled);
8
+ return runInContext(() => {
9
+ const initialValue = toValue(valueOrSignal);
10
+ const output = signal(initialValue, options);
11
+ const set = throttleCallback(output.set, timeMs);
12
+ if (isSignal(valueOrSignal)) {
13
+ watcher(valueOrSignal, set);
14
+ return output.asReadonly();
15
+ }
16
+ else {
17
+ return proxySignal(output, { set });
18
+ }
19
+ });
20
+ }
21
+
22
+ /**
23
+ * Generated bundle index. Do not edit.
24
+ */
25
+
26
+ export { throttled };
27
+ //# sourceMappingURL=signality-core-reactivity-throttled.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-reactivity-throttled.mjs","sources":["../../../projects/core/reactivity/throttled/index.ts","../../../projects/core/reactivity/throttled/signality-core-reactivity-throttled.ts"],"sourcesContent":["import {\n type CreateSignalOptions,\n isSignal,\n signal,\n type Signal,\n type WritableSignal,\n} from '@angular/core';\nimport { proxySignal, setupContext, toValue } from '@signality/core/internal';\nimport type { MaybeSignal, SignalValue, WithInjector } from '@signality/core/types';\nimport { throttleCallback } from '@signality/core/scheduling/throttle-callback';\nimport { watcher } from '@signality/core/reactivity/watcher';\n\nexport type ThrottledOptions<T> = CreateSignalOptions<T> & WithInjector;\n\n/**\n * Creates a throttled readonly signal from a source signal.\n * Updates to the source signal are throttled to occur at most once per time interval.\n *\n * @param source - Source signal to throttle\n * @param timeMs - Throttle interval in milliseconds\n * @param options - Optional configuration including signal options and injector\n * @returns A readonly signal that updates at most once per throttle interval\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div (scroll)=\"scrollY.set($event.target.scrollTop)\">\n * <p>Scroll position: {{ scrollY() }}</p>\n * <p>Throttled position: {{ throttledScrollY() }}</p>\n * </div>\n * `\n * })\n * class ScrollTracker {\n * readonly scrollY = signal(0);\n * readonly throttledScrollY = throttled(this.scrollY, 100);\n * }\n * ```\n */\nexport function throttled<S extends Signal<any>>(\n source: S,\n timeMs: MaybeSignal<number>,\n options?: ThrottledOptions<SignalValue<S>>\n): Signal<SignalValue<S>>;\n\n/**\n * Creates a throttled writable signal from an initial value.\n * Both `set()` and `update()` calls are throttled.\n *\n * @param value - Initial value\n * @param timeMs - Throttle interval in milliseconds\n * @param options - Optional configuration including signal options and injector\n * @returns A writable signal where updates are throttled\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div (mousemove)=\"mousePosition.set({ x: $event.clientX, y: $event.clientY })\">\n * <p>Mouse position: X={{ mousePosition().x }}, Y={{ mousePosition().y }}</p>\n * </div>\n * `\n * })\n * class MouseTracker {\n * readonly mousePosition = throttled({ x: 0, y: 0 }, 16);\n * }\n * ```\n */\nexport function throttled<V>(\n value: V,\n timeMs: MaybeSignal<number>,\n options?: ThrottledOptions<V>\n): WritableSignal<V>;\n\nexport function throttled(\n valueOrSignal: any,\n timeMs: MaybeSignal<number>,\n options?: ThrottledOptions<any>\n) {\n const { runInContext } = setupContext(options?.injector, throttled);\n\n return runInContext(() => {\n const initialValue = toValue(valueOrSignal);\n const output = signal(initialValue, options);\n const set = throttleCallback(output.set, timeMs);\n\n if (isSignal(valueOrSignal)) {\n watcher(valueOrSignal, set);\n return output.asReadonly();\n } else {\n return proxySignal(output, { set });\n }\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;SA0EgB,SAAS,CACvB,aAAkB,EAClB,MAA2B,EAC3B,OAA+B,EAAA;AAE/B,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;IAEnE,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC;QAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC;AAEhD,QAAA,IAAI,QAAQ,CAAC,aAAa,CAAC,EAAE;AAC3B,YAAA,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;AAC3B,YAAA,OAAO,MAAM,CAAC,UAAU,EAAE;QAC5B;aAAO;YACL,OAAO,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC;QACrC;AACF,IAAA,CAAC,CAAC;AACJ;;AC7FA;;AAEG;;;;"}
@@ -0,0 +1,36 @@
1
+ import { effect, untracked } from '@angular/core';
2
+ import { setupContext } from '@signality/core/internal';
3
+
4
+ function watcher(sourceOrSources, fn, options) {
5
+ const { runInContext } = setupContext(options?.injector, watcher);
6
+ return runInContext(() => {
7
+ const isArray = Array.isArray(sourceOrSources);
8
+ const deps = isArray ? sourceOrSources : [sourceOrSources];
9
+ const once = options?.once ?? false;
10
+ let isFirstRun = true;
11
+ let prevValues = null;
12
+ const effectRef = effect(onCleanup => {
13
+ const currValues = deps.map(track => track());
14
+ if (isFirstRun) {
15
+ isFirstRun = false;
16
+ prevValues = currValues;
17
+ return;
18
+ }
19
+ const currentValue = isArray ? currValues : currValues[0];
20
+ const previousValue = isArray ? prevValues : prevValues?.[0];
21
+ prevValues = currValues;
22
+ untracked(() => fn(currentValue, previousValue, onCleanup));
23
+ if (once) {
24
+ effectRef.destroy();
25
+ }
26
+ }, options);
27
+ return effectRef;
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Generated bundle index. Do not edit.
33
+ */
34
+
35
+ export { watcher };
36
+ //# sourceMappingURL=signality-core-reactivity-watcher.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-reactivity-watcher.mjs","sources":["../../../projects/core/reactivity/watcher/index.ts","../../../projects/core/reactivity/watcher/signality-core-reactivity-watcher.ts"],"sourcesContent":["import {\n type CreateEffectOptions,\n effect,\n type EffectCleanupRegisterFn,\n type EffectRef,\n type Signal,\n untracked,\n} from '@angular/core';\nimport { setupContext } from '@signality/core/internal';\nimport type { SignalValues } from '@signality/core/types';\n\nexport interface CreateWatcherOptions extends Omit<CreateEffectOptions, 'allowSignalWrites'> {\n /**\n * If `true`, the watcher will automatically destroy itself after the first change.\n * @default false\n */\n readonly once?: boolean;\n}\n\nexport type WatcherRef = EffectRef;\n\n/**\n * Watches a single signal and calls a callback when it changes, skipping the initial call.\n * Unlike `effect()`, this responds to the fact of state change, enabling event-like orchestration of side effects.\n *\n * @param source - Signal to watch\n * @param fn - Callback function called when signal changes. Receives current value, previous value, and cleanup function\n * @param options - Optional configuration including effect options and injector\n * @returns A WatcherRef (alias for EffectRef) that can be used to manually destroy the watcher\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <button (click)=\"count.set(count() + 1)\">Count: {{ count() }}</button>\n * `\n * })\n * class CounterComponent {\n * readonly count = signal(0);\n *\n * constructor() {\n * watcher(this.count, (curr, prev) => {\n * console.log('Count changed from', prev, 'to', curr);\n * });\n * }\n * }\n * ```\n */\nexport function watcher<V>(\n source: Signal<V>,\n fn: (curr: V, prev: V, onCleanup: EffectCleanupRegisterFn) => void,\n options?: CreateWatcherOptions\n): WatcherRef;\n\n/**\n * Watches multiple signals and calls a callback when any of them changes, skipping the initial call.\n * Unlike `effect()`, this responds to the fact of state change, enabling event-like orchestration of side effects.\n *\n * @param sources - Array of signals to watch\n * @param fn - Callback function called when any signal changes. Receives current values array, previous values array, and cleanup function\n * @param options - Optional configuration including effect options and injector\n * @returns A WatcherRef (alias for EffectRef) that can be used to manually destroy the watcher\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input [(ngModel)]=\"name\" />\n * <input [(ngModel)]=\"age\" type=\"number\" />\n * `\n * })\n * class UserComponent {\n * readonly name = signal('John');\n * readonly age = signal(25);\n *\n * constructor() {\n * watcher([this.name, this.age], ([name, age], [prevName, prevAge]) => {\n * console.log('User changed:', { name, age });\n * });\n * }\n * }\n * ```\n */\nexport function watcher<T extends readonly Signal<any>[]>(\n sources: T,\n fn: (curr: SignalValues<T>, prev: SignalValues<T>, onCleanup: EffectCleanupRegisterFn) => void,\n options?: CreateWatcherOptions\n): WatcherRef;\n\nexport function watcher<V, T extends readonly Signal<any>[]>(\n sourceOrSources: Signal<V> | T,\n fn:\n | ((curr: V, prev: V, onCleanup: EffectCleanupRegisterFn) => void)\n | ((curr: SignalValues<T>, prev: SignalValues<T>, onCleanup: EffectCleanupRegisterFn) => void),\n options?: CreateWatcherOptions\n): WatcherRef {\n const { runInContext } = setupContext(options?.injector, watcher);\n\n return runInContext(() => {\n const isArray = Array.isArray(sourceOrSources);\n const deps = isArray ? (sourceOrSources as Signal<any>[]) : [sourceOrSources as Signal<V>];\n const once = options?.once ?? false;\n\n let isFirstRun = true;\n let prevValues: readonly any[] | null = null;\n\n const effectRef = effect(onCleanup => {\n const currValues = deps.map(track => track());\n\n if (isFirstRun) {\n isFirstRun = false;\n prevValues = currValues;\n return;\n }\n\n const currentValue = isArray ? currValues : currValues[0];\n const previousValue = isArray ? prevValues : prevValues?.[0];\n\n prevValues = currValues;\n\n untracked(() => fn(currentValue, previousValue, onCleanup));\n\n if (once) {\n effectRef.destroy();\n }\n }, options);\n\n return effectRef;\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;SAyFgB,OAAO,CACrB,eAA8B,EAC9B,EAEgG,EAChG,OAA8B,EAAA;AAE9B,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC;IAEjE,OAAO,YAAY,CAAC,MAAK;QACvB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC;AAC9C,QAAA,MAAM,IAAI,GAAG,OAAO,GAAI,eAAiC,GAAG,CAAC,eAA4B,CAAC;AAC1F,QAAA,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,KAAK;QAEnC,IAAI,UAAU,GAAG,IAAI;QACrB,IAAI,UAAU,GAA0B,IAAI;AAE5C,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAG;AACnC,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;YAE7C,IAAI,UAAU,EAAE;gBACd,UAAU,GAAG,KAAK;gBAClB,UAAU,GAAG,UAAU;gBACvB;YACF;AAEA,YAAA,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC;AACzD,YAAA,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,CAAC,CAAC;YAE5D,UAAU,GAAG,UAAU;AAEvB,YAAA,SAAS,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;YAE3D,IAAI,IAAI,EAAE;gBACR,SAAS,CAAC,OAAO,EAAE;YACrB;QACF,CAAC,EAAE,OAAO,CAAC;AAEX,QAAA,OAAO,SAAS;AAClB,IAAA,CAAC,CAAC;AACJ;;ACjIA;;AAEG;;;;"}
@@ -0,0 +1,8 @@
1
+ export * from '@signality/core/reactivity/debounced';
2
+ export * from '@signality/core/reactivity/throttled';
3
+ export * from '@signality/core/reactivity/watcher';
4
+
5
+ /**
6
+ * Generated bundle index. Do not edit.
7
+ */
8
+ //# sourceMappingURL=signality-core-reactivity.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-reactivity.mjs","sources":["../../../projects/core/reactivity/signality-core-reactivity.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAAA;;AAEG"}
@@ -0,0 +1,41 @@
1
+ import { inject } from '@angular/core';
2
+ import { ActivatedRoute } from '@angular/router';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { setupContext } from '@signality/core/internal';
5
+
6
+ /**
7
+ * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) URL fragment.
8
+ *
9
+ * @param options - Optional configuration including signal options and injector
10
+ * @returns A signal containing the current URL fragment (without #), or null
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * @Component({
15
+ * template: `
16
+ * @if (currentFragment(); as fragment) {
17
+ * <p>Current section: {{ fragment }}</p>
18
+ * } @else {
19
+ * <p>No fragment in URL</p>
20
+ * }
21
+ * `
22
+ * })
23
+ * class FragmentComponent {
24
+ * readonly currentFragment = fragment();
25
+ * }
26
+ * ```
27
+ */
28
+ function fragment(options) {
29
+ const { runInContext } = setupContext(options?.injector, fragment);
30
+ return runInContext(() => {
31
+ const { fragment: fragmentChanges, snapshot } = inject(ActivatedRoute);
32
+ return toSignal(fragmentChanges, { ...options, initialValue: snapshot.fragment });
33
+ });
34
+ }
35
+
36
+ /**
37
+ * Generated bundle index. Do not edit.
38
+ */
39
+
40
+ export { fragment };
41
+ //# sourceMappingURL=signality-core-router-fragment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-router-fragment.mjs","sources":["../../../projects/core/router/fragment/index.ts","../../../projects/core/router/fragment/signality-core-router-fragment.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, type Signal } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport type FragmentOptions = CreateSignalOptions<string | null> & WithInjector;\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) URL fragment.\n *\n * @param options - Optional configuration including signal options and injector\n * @returns A signal containing the current URL fragment (without #), or null\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * @if (currentFragment(); as fragment) {\n * <p>Current section: {{ fragment }}</p>\n * } @else {\n * <p>No fragment in URL</p>\n * }\n * `\n * })\n * class FragmentComponent {\n * readonly currentFragment = fragment();\n * }\n * ```\n */\nexport function fragment(options?: FragmentOptions): Signal<string | null> {\n const { runInContext } = setupContext(options?.injector, fragment);\n\n return runInContext(() => {\n const { fragment: fragmentChanges, snapshot } = inject(ActivatedRoute);\n\n return toSignal(fragmentChanges, { ...options, initialValue: snapshot.fragment });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAQA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,SAAU,QAAQ,CAAC,OAAyB,EAAA;AAChD,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAElE,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC;AAEtE,QAAA,OAAO,QAAQ,CAAC,eAAe,EAAE,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC;AACnF,IAAA,CAAC,CAAC;AACJ;;ACtCA;;AAEG;;;;"}
@@ -0,0 +1,45 @@
1
+ import { inject } from '@angular/core';
2
+ import { ActivatedRoute } from '@angular/router';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { setupContext } from '@signality/core/internal';
5
+
6
+ /**
7
+ * Reactive wrapper around Angular Router's route parameters.
8
+ * Access route parameters as a signal that updates when navigation occurs.
9
+ *
10
+ * @param options - Optional configuration including signal options and injector
11
+ * @returns A signal containing the current route parameters
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * @Component({
16
+ * template: `
17
+ * <div>
18
+ * <p>User ID: {{ routeParams().id }}</p>
19
+ * <p>Slug: {{ routeParams().slug }}</p>
20
+ * </div>
21
+ * `
22
+ * })
23
+ * class UserComponent {
24
+ * // Route: /user/:id/:slug
25
+ * readonly routeParams = params<{ id: string; slug: string }>();
26
+ * }
27
+ * ```
28
+ */
29
+ function params(options) {
30
+ const { runInContext } = setupContext(options?.injector, params);
31
+ return runInContext(() => {
32
+ const { params: paramsChanges, snapshot } = inject(ActivatedRoute);
33
+ return toSignal(paramsChanges, {
34
+ ...options,
35
+ initialValue: snapshot.params,
36
+ });
37
+ });
38
+ }
39
+
40
+ /**
41
+ * Generated bundle index. Do not edit.
42
+ */
43
+
44
+ export { params };
45
+ //# sourceMappingURL=signality-core-router-params.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-router-params.mjs","sources":["../../../projects/core/router/params/index.ts","../../../projects/core/router/params/signality-core-router-params.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, type Signal } from '@angular/core';\nimport { ActivatedRoute, type Params } from '@angular/router';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport type { Observable } from 'rxjs';\nimport { setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport type ParamsOptions<T extends Params = Params> = CreateSignalOptions<T> & WithInjector;\n\n/**\n * Reactive wrapper around Angular Router's route parameters.\n * Access route parameters as a signal that updates when navigation occurs.\n *\n * @param options - Optional configuration including signal options and injector\n * @returns A signal containing the current route parameters\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <p>User ID: {{ routeParams().id }}</p>\n * <p>Slug: {{ routeParams().slug }}</p>\n * </div>\n * `\n * })\n * class UserComponent {\n * // Route: /user/:id/:slug\n * readonly routeParams = params<{ id: string; slug: string }>();\n * }\n * ```\n */\nexport function params<T extends Params = Params>(options?: ParamsOptions<T>): Signal<T> {\n const { runInContext } = setupContext(options?.injector, params);\n\n return runInContext(() => {\n const { params: paramsChanges, snapshot } = inject(ActivatedRoute);\n\n return toSignal<T, T>(paramsChanges as Observable<T>, {\n ...options,\n initialValue: snapshot.params as T,\n });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AASA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACG,SAAU,MAAM,CAA4B,OAA0B,EAAA;AAC1E,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;IAEhE,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC;QAElE,OAAO,QAAQ,CAAO,aAA8B,EAAE;AACpD,YAAA,GAAG,OAAO;YACV,YAAY,EAAE,QAAQ,CAAC,MAAW;AACnC,SAAA,CAAC;AACJ,IAAA,CAAC,CAAC;AACJ;;AC3CA;;AAEG;;;;"}
@@ -0,0 +1,67 @@
1
+ import { inject, signal, computed } from '@angular/core';
2
+ import { ActivatedRoute } from '@angular/router';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { map } from 'rxjs';
5
+ import { setupContext } from '@signality/core/internal';
6
+
7
+ function queryParams(options) {
8
+ const { runInContext } = setupContext(options?.injector, queryParams);
9
+ return runInContext(() => {
10
+ const { queryParams: paramsChanges, snapshot } = inject(ActivatedRoute);
11
+ const hasSchema = options && 'schema' in options && options.schema !== undefined;
12
+ if (!hasSchema) {
13
+ return toSignal(paramsChanges, {
14
+ ...options,
15
+ initialValue: snapshot.queryParams,
16
+ });
17
+ }
18
+ const schema = options.schema;
19
+ const initialRaw = snapshot.queryParams;
20
+ let initialValue = null;
21
+ let initialError = null;
22
+ try {
23
+ initialValue = schema.parse(initialRaw);
24
+ }
25
+ catch (err) {
26
+ initialError = err;
27
+ }
28
+ const error = signal(initialError, ...(ngDevMode ? [{ debugName: "error" }] : []));
29
+ const isValid = signal(!initialError, ...(ngDevMode ? [{ debugName: "isValid" }] : []));
30
+ const validatedValue = toSignal(paramsChanges.pipe(map(rawParams => {
31
+ try {
32
+ const parsed = schema.parse(rawParams);
33
+ isValid.set(true);
34
+ error.set(null);
35
+ return parsed;
36
+ }
37
+ catch (err) {
38
+ isValid.set(false);
39
+ error.set(err);
40
+ return null;
41
+ }
42
+ })), { initialValue });
43
+ const value = computed(() => {
44
+ const validated = validatedValue();
45
+ const err = error();
46
+ if (err !== null) {
47
+ throw err;
48
+ }
49
+ return validated;
50
+ }, {
51
+ ...options,
52
+ debugName: options.debugName ? `${options.debugName}.value` : undefined,
53
+ });
54
+ return {
55
+ value,
56
+ isValid: isValid.asReadonly(),
57
+ error: error.asReadonly(),
58
+ };
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Generated bundle index. Do not edit.
64
+ */
65
+
66
+ export { queryParams };
67
+ //# sourceMappingURL=signality-core-router-query-params.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-router-query-params.mjs","sources":["../../../projects/core/router/query-params/index.ts","../../../projects/core/router/query-params/signality-core-router-query-params.ts"],"sourcesContent":["import { computed, type CreateSignalOptions, inject, signal, type Signal } from '@angular/core';\nimport { ActivatedRoute, type Params } from '@angular/router';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { map, type Observable } from 'rxjs';\nimport { setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport interface QueryParamsValidator<T> {\n /**\n * Parse and validate data, throwing an error if validation fails.\n */\n parse(data: unknown): T;\n}\n\nexport interface QueryParamsRef<T> {\n /**\n * Signal containing validated query parameters.\n * Throws an error if validation failed. Use `isValid()` to check before reading.\n */\n readonly value: Signal<T>;\n\n /**\n * Signal indicating whether the current query parameters are valid.\n * Returns `true` when validation succeeded, `false` when validation failed.\n */\n readonly isValid: Signal<boolean>;\n\n /** Signal containing validation error, or null if valid */\n readonly error: Signal<unknown | null>;\n}\n\nexport type QueryParamsOptions<T extends Params = Params> = CreateSignalOptions<T> & WithInjector;\n\nexport type QueryParamsWithSchemaOptions<T extends Params = Params> = QueryParamsOptions<T> & {\n /** Validator schema (e.g., Zod schema) */\n readonly schema: QueryParamsValidator<T>;\n};\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) query parameters.\n *\n * @param options - Optional configuration including signal options and injector\n * @returns A signal containing the current query parameters\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <p>Search: {{ searchParams().q }}</p>\n * <p>Sort: {{ searchParams().sort }}</p>\n * </div>\n * `\n * })\n * class SearchComponent {\n * // Route: /search?q=angular&sort=name\n * readonly searchParams = queryParams<{ q: string; sort: string }>();\n * }\n * ```\n */\nexport function queryParams<T extends Params = Params>(options?: QueryParamsOptions<T>): Signal<T>;\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) query parameters with schema validation.\n *\n * @param options - Configuration including schema validator\n * @returns A QueryParamsRef object with value, isValid, and error signals\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * @if (params.isValid()) {\n * <p>Search: {{ params.value().q }}</p>\n * <p>Page: {{ params.value().page }}</p>\n * } @else {\n * <p>Invalid parameters</p>\n * }\n * `\n * })\n * class ValidatedSearchComponent {\n * readonly schema = z.object({\n * q: z.string().min(1).optional(),\n * page: z.coerce.number().int().positive().default(1),\n * });\n *\n * readonly params = queryParams({ schema: this.schema });\n * }\n * ```\n */\nexport function queryParams<T extends Params = Params>(\n options: QueryParamsWithSchemaOptions<T>\n): QueryParamsRef<T>;\n\nexport function queryParams<T extends Params = Params>(\n options?: QueryParamsOptions<T> | QueryParamsWithSchemaOptions<T>\n): Signal<T> | QueryParamsRef<T> {\n const { runInContext } = setupContext(options?.injector, queryParams);\n\n return runInContext(() => {\n const { queryParams: paramsChanges, snapshot } = inject(ActivatedRoute);\n const hasSchema = options && 'schema' in options && options.schema !== undefined;\n\n if (!hasSchema) {\n return toSignal<T, T>(paramsChanges as Observable<T>, {\n ...options,\n initialValue: snapshot.queryParams as T,\n });\n }\n\n const schema = options.schema;\n const initialRaw = snapshot.queryParams as T;\n\n let initialValue: T | null = null;\n let initialError: unknown | null = null;\n\n try {\n initialValue = schema.parse(initialRaw);\n } catch (err) {\n initialError = err;\n }\n\n const error = signal<unknown | null>(initialError);\n const isValid = signal(!initialError);\n\n const validatedValue = toSignal<T | null, T | null>(\n paramsChanges.pipe(\n map(rawParams => {\n try {\n const parsed = schema.parse(rawParams);\n isValid.set(true);\n error.set(null);\n return parsed;\n } catch (err) {\n isValid.set(false);\n error.set(err);\n return null;\n }\n })\n ),\n { initialValue }\n );\n\n const value = computed(\n () => {\n const validated = validatedValue();\n const err = error();\n\n if (err !== null) {\n throw err;\n }\n\n return validated!;\n },\n {\n ...options,\n debugName: options.debugName ? `${options.debugName}.value` : undefined,\n }\n );\n\n return {\n value,\n isValid: isValid.asReadonly(),\n error: error.asReadonly(),\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AA8FM,SAAU,WAAW,CACzB,OAAiE,EAAA;AAEjE,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC;IAErE,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC;AACvE,QAAA,MAAM,SAAS,GAAG,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAEhF,IAAI,CAAC,SAAS,EAAE;YACd,OAAO,QAAQ,CAAO,aAA8B,EAAE;AACpD,gBAAA,GAAG,OAAO;gBACV,YAAY,EAAE,QAAQ,CAAC,WAAgB;AACxC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;AAC7B,QAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAgB;QAE5C,IAAI,YAAY,GAAa,IAAI;QACjC,IAAI,YAAY,GAAmB,IAAI;AAEvC,QAAA,IAAI;AACF,YAAA,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;QACzC;QAAE,OAAO,GAAG,EAAE;YACZ,YAAY,GAAG,GAAG;QACpB;AAEA,QAAA,MAAM,KAAK,GAAG,MAAM,CAAiB,YAAY,iDAAC;AAClD,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,YAAY,mDAAC;AAErC,QAAA,MAAM,cAAc,GAAG,QAAQ,CAC7B,aAAa,CAAC,IAAI,CAChB,GAAG,CAAC,SAAS,IAAG;AACd,YAAA,IAAI;gBACF,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;AACtC,gBAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACjB,gBAAA,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACf,gBAAA,OAAO,MAAM;YACf;YAAE,OAAO,GAAG,EAAE;AACZ,gBAAA,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AAClB,gBAAA,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;AACd,gBAAA,OAAO,IAAI;YACb;AACF,QAAA,CAAC,CAAC,CACH,EACD,EAAE,YAAY,EAAE,CACjB;AAED,QAAA,MAAM,KAAK,GAAG,QAAQ,CACpB,MAAK;AACH,YAAA,MAAM,SAAS,GAAG,cAAc,EAAE;AAClC,YAAA,MAAM,GAAG,GAAG,KAAK,EAAE;AAEnB,YAAA,IAAI,GAAG,KAAK,IAAI,EAAE;AAChB,gBAAA,MAAM,GAAG;YACX;AAEA,YAAA,OAAO,SAAU;AACnB,QAAA,CAAC,EACD;AACE,YAAA,GAAG,OAAO;AACV,YAAA,SAAS,EAAE,OAAO,CAAC,SAAS,GAAG,CAAA,EAAG,OAAO,CAAC,SAAS,CAAA,MAAA,CAAQ,GAAG,SAAS;AACxE,SAAA,CACF;QAED,OAAO;YACL,KAAK;AACL,YAAA,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AAC7B,YAAA,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;SAC1B;AACH,IAAA,CAAC,CAAC;AACJ;;ACtKA;;AAEG;;;;"}
@@ -0,0 +1,46 @@
1
+ import { inject } from '@angular/core';
2
+ import { ActivatedRoute } from '@angular/router';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { setupContext } from '@signality/core/internal';
5
+
6
+ /**
7
+ * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) route data.
8
+ *
9
+ * @param options - Optional configuration including signal options and injector
10
+ * @returns A signal containing the current route data
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * @Component({
15
+ * template: `
16
+ * <div>
17
+ * <h1>{{ data().name }}</h1>
18
+ * @if (data().showBreadcrumbs) {
19
+ * <nav>Breadcrumbs here</nav>
20
+ * }
21
+ * </div>
22
+ * `
23
+ * })
24
+ * class ProductComponent {
25
+ * // Route with data: { name: 'Product Page', showBreadcrumbs: true }
26
+ * readonly data = routeData<{ name: string; showBreadcrumbs: boolean }>();
27
+ * }
28
+ * ```
29
+ */
30
+ function routeData(options) {
31
+ const { runInContext } = setupContext(options?.injector, routeData);
32
+ return runInContext(() => {
33
+ const { data, snapshot } = inject(ActivatedRoute);
34
+ return toSignal(data, {
35
+ ...options,
36
+ initialValue: snapshot.data,
37
+ });
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Generated bundle index. Do not edit.
43
+ */
44
+
45
+ export { routeData };
46
+ //# sourceMappingURL=signality-core-router-route-data.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signality-core-router-route-data.mjs","sources":["../../../projects/core/router/route-data/index.ts","../../../projects/core/router/route-data/signality-core-router-route-data.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, type Signal } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport type { Observable } from 'rxjs';\nimport { setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport type RouteDataOptions<T = unknown> = CreateSignalOptions<T> & WithInjector;\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) route data.\n *\n * @param options - Optional configuration including signal options and injector\n * @returns A signal containing the current route data\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <h1>{{ data().name }}</h1>\n * @if (data().showBreadcrumbs) {\n * <nav>Breadcrumbs here</nav>\n * }\n * </div>\n * `\n * })\n * class ProductComponent {\n * // Route with data: { name: 'Product Page', showBreadcrumbs: true }\n * readonly data = routeData<{ name: string; showBreadcrumbs: boolean }>();\n * }\n * ```\n */\nexport function routeData<T = unknown>(options?: RouteDataOptions<T>): Signal<T> {\n const { runInContext } = setupContext(options?.injector, routeData);\n\n return runInContext(() => {\n const { data, snapshot } = inject(ActivatedRoute);\n\n return toSignal<T, T>(data as Observable<T>, {\n ...options,\n initialValue: snapshot.data as T,\n });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,SAAU,SAAS,CAAc,OAA6B,EAAA;AAClE,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;IAEnE,OAAO,YAAY,CAAC,MAAK;QACvB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC;QAEjD,OAAO,QAAQ,CAAO,IAAqB,EAAE;AAC3C,YAAA,GAAG,OAAO;YACV,YAAY,EAAE,QAAQ,CAAC,IAAS;AACjC,SAAA,CAAC;AACJ,IAAA,CAAC,CAAC;AACJ;;AC5CA;;AAEG;;;;"}