@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.
- package/README.md +60 -0
- package/browser/battery/index.d.ts +34 -0
- package/browser/bluetooth/index.d.ts +56 -0
- package/browser/breakpoints/index.d.ts +32 -0
- package/browser/broadcast-channel/index.d.ts +42 -0
- package/browser/browser-language/index.d.ts +34 -0
- package/browser/clipboard/index.d.ts +48 -0
- package/browser/device-posture/index.d.ts +18 -0
- package/browser/display-media/index.d.ts +80 -0
- package/browser/eye-dropper/index.d.ts +47 -0
- package/browser/favicon/index.d.ts +39 -0
- package/browser/fps/index.d.ts +46 -0
- package/browser/gamepad/index.d.ts +28 -0
- package/browser/geolocation/index.d.ts +64 -0
- package/browser/index.d.ts +29 -0
- package/browser/input-modality/index.d.ts +26 -0
- package/browser/listener/index.d.ts +61 -0
- package/browser/media-query/index.d.ts +36 -0
- package/browser/network/index.d.ts +44 -0
- package/browser/online/index.d.ts +27 -0
- package/browser/page-visibility/index.d.ts +27 -0
- package/browser/picture-in-picture/index.d.ts +42 -0
- package/browser/pointer-lock-element/index.d.ts +22 -0
- package/browser/screen-orientation/index.d.ts +29 -0
- package/browser/speech-recognition/index.d.ts +77 -0
- package/browser/speech-synthesis/index.d.ts +76 -0
- package/browser/storage/index.d.ts +142 -0
- package/browser/text-direction/index.d.ts +43 -0
- package/browser/vibration/index.d.ts +37 -0
- package/browser/wake-lock/index.d.ts +37 -0
- package/browser/web-notification/index.d.ts +58 -0
- package/browser/web-share/index.d.ts +42 -0
- package/browser/web-worker/index.d.ts +52 -0
- package/elements/active-element/index.d.ts +27 -0
- package/elements/dropzone/index.d.ts +61 -0
- package/elements/element-focus/index.d.ts +38 -0
- package/elements/element-focus-within/index.d.ts +29 -0
- package/elements/element-hover/index.d.ts +27 -0
- package/elements/element-size/index.d.ts +40 -0
- package/elements/element-visibility/index.d.ts +53 -0
- package/elements/index.d.ts +16 -0
- package/elements/mouse-position/index.d.ts +64 -0
- package/elements/on-click-outside/index.d.ts +42 -0
- package/elements/on-disconnect/index.d.ts +45 -0
- package/elements/on-long-press/index.d.ts +44 -0
- package/elements/pointer-swipe/index.d.ts +58 -0
- package/elements/scroll-position/index.d.ts +96 -0
- package/elements/swipe/index.d.ts +49 -0
- package/elements/text-selection/index.d.ts +39 -0
- package/elements/window-size/index.d.ts +46 -0
- package/fesm2022/signality-core-browser-battery.mjs +80 -0
- package/fesm2022/signality-core-browser-battery.mjs.map +1 -0
- package/fesm2022/signality-core-browser-bluetooth.mjs +112 -0
- package/fesm2022/signality-core-browser-bluetooth.mjs.map +1 -0
- package/fesm2022/signality-core-browser-breakpoints.mjs +51 -0
- package/fesm2022/signality-core-browser-breakpoints.mjs.map +1 -0
- package/fesm2022/signality-core-browser-broadcast-channel.mjs +74 -0
- package/fesm2022/signality-core-browser-broadcast-channel.mjs.map +1 -0
- package/fesm2022/signality-core-browser-browser-language.mjs +48 -0
- package/fesm2022/signality-core-browser-browser-language.mjs.map +1 -0
- package/fesm2022/signality-core-browser-clipboard.mjs +102 -0
- package/fesm2022/signality-core-browser-clipboard.mjs.map +1 -0
- package/fesm2022/signality-core-browser-device-posture.mjs +40 -0
- package/fesm2022/signality-core-browser-device-posture.mjs.map +1 -0
- package/fesm2022/signality-core-browser-display-media.mjs +121 -0
- package/fesm2022/signality-core-browser-display-media.mjs.map +1 -0
- package/fesm2022/signality-core-browser-eye-dropper.mjs +82 -0
- package/fesm2022/signality-core-browser-eye-dropper.mjs.map +1 -0
- package/fesm2022/signality-core-browser-favicon.mjs +100 -0
- package/fesm2022/signality-core-browser-favicon.mjs.map +1 -0
- package/fesm2022/signality-core-browser-fps.mjs +103 -0
- package/fesm2022/signality-core-browser-fps.mjs.map +1 -0
- package/fesm2022/signality-core-browser-gamepad.mjs +93 -0
- package/fesm2022/signality-core-browser-gamepad.mjs.map +1 -0
- package/fesm2022/signality-core-browser-geolocation.mjs +120 -0
- package/fesm2022/signality-core-browser-geolocation.mjs.map +1 -0
- package/fesm2022/signality-core-browser-input-modality.mjs +64 -0
- package/fesm2022/signality-core-browser-input-modality.mjs.map +1 -0
- package/fesm2022/signality-core-browser-listener.mjs +132 -0
- package/fesm2022/signality-core-browser-listener.mjs.map +1 -0
- package/fesm2022/signality-core-browser-media-query.mjs +55 -0
- package/fesm2022/signality-core-browser-media-query.mjs.map +1 -0
- package/fesm2022/signality-core-browser-network.mjs +76 -0
- package/fesm2022/signality-core-browser-network.mjs.map +1 -0
- package/fesm2022/signality-core-browser-online.mjs +49 -0
- package/fesm2022/signality-core-browser-online.mjs.map +1 -0
- package/fesm2022/signality-core-browser-page-visibility.mjs +47 -0
- package/fesm2022/signality-core-browser-page-visibility.mjs.map +1 -0
- package/fesm2022/signality-core-browser-picture-in-picture.mjs +93 -0
- package/fesm2022/signality-core-browser-picture-in-picture.mjs.map +1 -0
- package/fesm2022/signality-core-browser-pointer-lock-element.mjs +43 -0
- package/fesm2022/signality-core-browser-pointer-lock-element.mjs.map +1 -0
- package/fesm2022/signality-core-browser-screen-orientation.mjs +43 -0
- package/fesm2022/signality-core-browser-screen-orientation.mjs.map +1 -0
- package/fesm2022/signality-core-browser-speech-recognition.mjs +171 -0
- package/fesm2022/signality-core-browser-speech-recognition.mjs.map +1 -0
- package/fesm2022/signality-core-browser-speech-synthesis.mjs +146 -0
- package/fesm2022/signality-core-browser-speech-synthesis.mjs.map +1 -0
- package/fesm2022/signality-core-browser-storage.mjs +261 -0
- package/fesm2022/signality-core-browser-storage.mjs.map +1 -0
- package/fesm2022/signality-core-browser-text-direction.mjs +62 -0
- package/fesm2022/signality-core-browser-text-direction.mjs.map +1 -0
- package/fesm2022/signality-core-browser-vibration.mjs +94 -0
- package/fesm2022/signality-core-browser-vibration.mjs.map +1 -0
- package/fesm2022/signality-core-browser-wake-lock.mjs +149 -0
- package/fesm2022/signality-core-browser-wake-lock.mjs.map +1 -0
- package/fesm2022/signality-core-browser-web-notification.mjs +137 -0
- package/fesm2022/signality-core-browser-web-notification.mjs.map +1 -0
- package/fesm2022/signality-core-browser-web-share.mjs +92 -0
- package/fesm2022/signality-core-browser-web-share.mjs.map +1 -0
- package/fesm2022/signality-core-browser-web-worker.mjs +105 -0
- package/fesm2022/signality-core-browser-web-worker.mjs.map +1 -0
- package/fesm2022/signality-core-browser.mjs +34 -0
- package/fesm2022/signality-core-browser.mjs.map +1 -0
- package/fesm2022/signality-core-elements-active-element.mjs +88 -0
- package/fesm2022/signality-core-elements-active-element.mjs.map +1 -0
- package/fesm2022/signality-core-elements-dropzone.mjs +158 -0
- package/fesm2022/signality-core-elements-dropzone.mjs.map +1 -0
- package/fesm2022/signality-core-elements-element-focus-within.mjs +56 -0
- package/fesm2022/signality-core-elements-element-focus-within.mjs.map +1 -0
- package/fesm2022/signality-core-elements-element-focus.mjs +54 -0
- package/fesm2022/signality-core-elements-element-focus.mjs.map +1 -0
- package/fesm2022/signality-core-elements-element-hover.mjs +48 -0
- package/fesm2022/signality-core-elements-element-hover.mjs.map +1 -0
- package/fesm2022/signality-core-elements-element-size.mjs +73 -0
- package/fesm2022/signality-core-elements-element-size.mjs.map +1 -0
- package/fesm2022/signality-core-elements-element-visibility.mjs +76 -0
- package/fesm2022/signality-core-elements-element-visibility.mjs.map +1 -0
- package/fesm2022/signality-core-elements-mouse-position.mjs +109 -0
- package/fesm2022/signality-core-elements-mouse-position.mjs.map +1 -0
- package/fesm2022/signality-core-elements-on-click-outside.mjs +97 -0
- package/fesm2022/signality-core-elements-on-click-outside.mjs.map +1 -0
- package/fesm2022/signality-core-elements-on-disconnect.mjs +99 -0
- package/fesm2022/signality-core-elements-on-disconnect.mjs.map +1 -0
- package/fesm2022/signality-core-elements-on-long-press.mjs +84 -0
- package/fesm2022/signality-core-elements-on-long-press.mjs.map +1 -0
- package/fesm2022/signality-core-elements-pointer-swipe.mjs +116 -0
- package/fesm2022/signality-core-elements-pointer-swipe.mjs.map +1 -0
- package/fesm2022/signality-core-elements-scroll-position.mjs +175 -0
- package/fesm2022/signality-core-elements-scroll-position.mjs.map +1 -0
- package/fesm2022/signality-core-elements-swipe.mjs +107 -0
- package/fesm2022/signality-core-elements-swipe.mjs.map +1 -0
- package/fesm2022/signality-core-elements-text-selection.mjs +70 -0
- package/fesm2022/signality-core-elements-text-selection.mjs.map +1 -0
- package/fesm2022/signality-core-elements-window-size.mjs +81 -0
- package/fesm2022/signality-core-elements-window-size.mjs.map +1 -0
- package/fesm2022/signality-core-elements.mjs +21 -0
- package/fesm2022/signality-core-elements.mjs.map +1 -0
- package/fesm2022/signality-core-forms-cva.mjs +140 -0
- package/fesm2022/signality-core-forms-cva.mjs.map +1 -0
- package/fesm2022/signality-core-forms.mjs +6 -0
- package/fesm2022/signality-core-forms.mjs.map +1 -0
- package/fesm2022/signality-core-internal.mjs +268 -0
- package/fesm2022/signality-core-internal.mjs.map +1 -0
- package/fesm2022/signality-core-observers-intersection-observer.mjs +70 -0
- package/fesm2022/signality-core-observers-intersection-observer.mjs.map +1 -0
- package/fesm2022/signality-core-observers-mutation-observer.mjs +77 -0
- package/fesm2022/signality-core-observers-mutation-observer.mjs.map +1 -0
- package/fesm2022/signality-core-observers-performance-observer.mjs +84 -0
- package/fesm2022/signality-core-observers-performance-observer.mjs.map +1 -0
- package/fesm2022/signality-core-observers-resize-observer.mjs +69 -0
- package/fesm2022/signality-core-observers-resize-observer.mjs.map +1 -0
- package/fesm2022/signality-core-observers.mjs +9 -0
- package/fesm2022/signality-core-observers.mjs.map +1 -0
- package/fesm2022/signality-core-reactivity-debounced.mjs +27 -0
- package/fesm2022/signality-core-reactivity-debounced.mjs.map +1 -0
- package/fesm2022/signality-core-reactivity-throttled.mjs +27 -0
- package/fesm2022/signality-core-reactivity-throttled.mjs.map +1 -0
- package/fesm2022/signality-core-reactivity-watcher.mjs +36 -0
- package/fesm2022/signality-core-reactivity-watcher.mjs.map +1 -0
- package/fesm2022/signality-core-reactivity.mjs +8 -0
- package/fesm2022/signality-core-reactivity.mjs.map +1 -0
- package/fesm2022/signality-core-router-fragment.mjs +41 -0
- package/fesm2022/signality-core-router-fragment.mjs.map +1 -0
- package/fesm2022/signality-core-router-params.mjs +45 -0
- package/fesm2022/signality-core-router-params.mjs.map +1 -0
- package/fesm2022/signality-core-router-query-params.mjs +67 -0
- package/fesm2022/signality-core-router-query-params.mjs.map +1 -0
- package/fesm2022/signality-core-router-route-data.mjs +46 -0
- package/fesm2022/signality-core-router-route-data.mjs.map +1 -0
- package/fesm2022/signality-core-router-router-listener.mjs +50 -0
- package/fesm2022/signality-core-router-router-listener.mjs.map +1 -0
- package/fesm2022/signality-core-router-title.mjs +54 -0
- package/fesm2022/signality-core-router-title.mjs.map +1 -0
- package/fesm2022/signality-core-router-url.mjs +53 -0
- package/fesm2022/signality-core-router-url.mjs.map +1 -0
- package/fesm2022/signality-core-router.mjs +12 -0
- package/fesm2022/signality-core-router.mjs.map +1 -0
- package/fesm2022/signality-core-scheduling-debounce-callback.mjs +59 -0
- package/fesm2022/signality-core-scheduling-debounce-callback.mjs.map +1 -0
- package/fesm2022/signality-core-scheduling-interval.mjs +110 -0
- package/fesm2022/signality-core-scheduling-interval.mjs.map +1 -0
- package/fesm2022/signality-core-scheduling-throttle-callback.mjs +66 -0
- package/fesm2022/signality-core-scheduling-throttle-callback.mjs.map +1 -0
- package/fesm2022/signality-core-scheduling.mjs +8 -0
- package/fesm2022/signality-core-scheduling.mjs.map +1 -0
- package/fesm2022/signality-core-types.mjs +4 -0
- package/fesm2022/signality-core-types.mjs.map +1 -0
- package/fesm2022/signality-core.mjs +13 -0
- package/fesm2022/signality-core.mjs.map +1 -0
- package/forms/cva/index.d.ts +60 -0
- package/forms/index.d.ts +1 -0
- package/index.d.ts +8 -0
- package/internal/constants/index.d.ts +2 -0
- package/internal/constants/mobile-regex.d.ts +1 -0
- package/internal/constants/stubs.d.ts +32 -0
- package/internal/index.d.ts +4 -0
- package/internal/providers/index.d.ts +3 -0
- package/internal/providers/is-browser.d.ts +2 -0
- package/internal/providers/is-mobile.d.ts +2 -0
- package/internal/providers/is-server.d.ts +2 -0
- package/internal/types/index.d.ts +2 -0
- package/internal/types/timer.d.ts +1 -0
- package/internal/types/union.d.ts +1 -0
- package/internal/utils/bom/index.d.ts +1 -0
- package/internal/utils/bom/is-window.d.ts +1 -0
- package/internal/utils/const-signal.d.ts +10 -0
- package/internal/utils/context.d.ts +18 -0
- package/internal/utils/create-token.d.ts +8 -0
- package/internal/utils/dom/get-active-element.d.ts +1 -0
- package/internal/utils/dom/get-event-target.d.ts +1 -0
- package/internal/utils/dom/get-pip-element.d.ts +1 -0
- package/internal/utils/dom/get-shadow-root.d.ts +1 -0
- package/internal/utils/dom/index.d.ts +6 -0
- package/internal/utils/dom/is-element.d.ts +1 -0
- package/internal/utils/dom/is-node-within.d.ts +1 -0
- package/internal/utils/index.d.ts +10 -0
- package/internal/utils/is-plain-object.d.ts +1 -0
- package/internal/utils/is-query-signal.d.ts +10 -0
- package/internal/utils/proxy-signal.d.ts +18 -0
- package/internal/utils/to-element.d.ts +12 -0
- package/internal/utils/to-value.d.ts +6 -0
- package/observers/index.d.ts +4 -0
- package/observers/intersection-observer/index.d.ts +42 -0
- package/observers/mutation-observer/index.d.ts +45 -0
- package/observers/performance-observer/index.d.ts +58 -0
- package/observers/resize-observer/index.d.ts +40 -0
- package/package.json +343 -0
- package/reactivity/debounced/index.d.ts +50 -0
- package/reactivity/index.d.ts +3 -0
- package/reactivity/throttled/index.d.ts +53 -0
- package/reactivity/watcher/index.d.ts +68 -0
- package/router/fragment/index.d.ts +26 -0
- package/router/index.d.ts +7 -0
- package/router/params/index.d.ts +28 -0
- package/router/query-params/index.d.ts +80 -0
- package/router/route-data/index.d.ts +28 -0
- package/router/router-listener/index.d.ts +83 -0
- package/router/title/index.d.ts +29 -0
- package/router/url/index.d.ts +32 -0
- package/scheduling/debounce-callback/index.d.ts +28 -0
- package/scheduling/index.d.ts +3 -0
- package/scheduling/interval/index.d.ts +51 -0
- package/scheduling/throttle-callback/index.d.ts +30 -0
- package/types/index.d.ts +6 -0
- package/types/maybe-element-signal.d.ts +2 -0
- package/types/maybe-signal.d.ts +2 -0
- package/types/signal-value.d.ts +2 -0
- package/types/signal-values.d.ts +5 -0
- package/types/unref-element.d.ts +2 -0
- package/types/with-injector.d.ts +8 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { inject } from '@angular/core';
|
|
2
|
+
import { Router, Scroll, ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, RouteConfigLoadEnd, RouteConfigLoadStart, ResolveEnd, ResolveStart, GuardsCheckEnd, GuardsCheckStart, RoutesRecognized, NavigationSkipped, NavigationError, NavigationCancel, NavigationEnd, NavigationStart } from '@angular/router';
|
|
3
|
+
import { filter } from 'rxjs';
|
|
4
|
+
import { setupContext } from '@signality/core/internal';
|
|
5
|
+
|
|
6
|
+
function routerListener(event, handler, options) {
|
|
7
|
+
const { runInContext } = setupContext(options?.injector, routerListener);
|
|
8
|
+
return runInContext(({ onCleanup }) => {
|
|
9
|
+
const router = inject(Router);
|
|
10
|
+
const events = Array.isArray(event) ? event : [event];
|
|
11
|
+
const EventClasses = events.map((e) => EVENT_CLASSES[e]);
|
|
12
|
+
const subscription = router.events
|
|
13
|
+
.pipe(filter((routerEvent) => EventClasses.some(EventClass => routerEvent instanceof EventClass)))
|
|
14
|
+
.subscribe(e => {
|
|
15
|
+
handler(e);
|
|
16
|
+
if (options?.once) {
|
|
17
|
+
subscription.unsubscribe();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const destroy = subscription.unsubscribe.bind(subscription);
|
|
21
|
+
onCleanup(destroy);
|
|
22
|
+
return { destroy };
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const EVENT_CLASSES = {
|
|
26
|
+
navigationstart: NavigationStart,
|
|
27
|
+
navigationend: NavigationEnd,
|
|
28
|
+
navigationcancel: NavigationCancel,
|
|
29
|
+
navigationerror: NavigationError,
|
|
30
|
+
navigationskipped: NavigationSkipped,
|
|
31
|
+
routesrecognized: RoutesRecognized,
|
|
32
|
+
guardscheckstart: GuardsCheckStart,
|
|
33
|
+
guardscheckend: GuardsCheckEnd,
|
|
34
|
+
resolvestart: ResolveStart,
|
|
35
|
+
resolveend: ResolveEnd,
|
|
36
|
+
routeconfigloadstart: RouteConfigLoadStart,
|
|
37
|
+
routeconfigloadend: RouteConfigLoadEnd,
|
|
38
|
+
childactivationstart: ChildActivationStart,
|
|
39
|
+
childactivationend: ChildActivationEnd,
|
|
40
|
+
activationstart: ActivationStart,
|
|
41
|
+
activationend: ActivationEnd,
|
|
42
|
+
scroll: Scroll,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Generated bundle index. Do not edit.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
export { routerListener };
|
|
50
|
+
//# sourceMappingURL=signality-core-router-router-listener.mjs.map
|
|
@@ -0,0 +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;;;;"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { inject, linkedSignal } from '@angular/core';
|
|
2
|
+
import { ActivatedRoute } from '@angular/router';
|
|
3
|
+
import { Title } from '@angular/platform-browser';
|
|
4
|
+
import { toSignal } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { filter } from 'rxjs';
|
|
6
|
+
import { setupContext, proxySignal } from '@signality/core/internal';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) route title.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Optional configuration
|
|
12
|
+
* @returns A writable signal containing the current route title (string)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* @Component({
|
|
17
|
+
* template: `
|
|
18
|
+
* <div>
|
|
19
|
+
* <h1>{{ pageTitle() }}</h1>
|
|
20
|
+
* <button (click)="updateTitle()">Update Title</button>
|
|
21
|
+
* </div>
|
|
22
|
+
* `
|
|
23
|
+
* })
|
|
24
|
+
* class PageComponent {
|
|
25
|
+
* readonly pageTitle = title();
|
|
26
|
+
*
|
|
27
|
+
* updateTitle() {
|
|
28
|
+
* this.pageTitle.set('New Page Title');
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function title(options) {
|
|
34
|
+
const { runInContext } = setupContext(options?.injector, title);
|
|
35
|
+
return runInContext(() => {
|
|
36
|
+
const route = inject(ActivatedRoute);
|
|
37
|
+
const html = inject(Title);
|
|
38
|
+
return proxySignal(linkedSignal(toSignal(route.title.pipe(filter(Boolean)), {
|
|
39
|
+
initialValue: route.snapshot.title || html.getTitle(),
|
|
40
|
+
}), { ...options }), {
|
|
41
|
+
set: (value, source) => {
|
|
42
|
+
html.setTitle(value);
|
|
43
|
+
source.set(value);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generated bundle index. Do not edit.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
export { title };
|
|
54
|
+
//# sourceMappingURL=signality-core-router-title.mjs.map
|
|
@@ -0,0 +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;;;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { inject, signal } from '@angular/core';
|
|
2
|
+
import { Router } from '@angular/router';
|
|
3
|
+
import { setupContext, constSignal } from '@signality/core/internal';
|
|
4
|
+
import { routerListener } from '@signality/core/router/router-listener';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) current URL.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Optional configuration
|
|
10
|
+
* @returns A signal containing the current URL
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @Component({
|
|
15
|
+
* template: `
|
|
16
|
+
* <div>
|
|
17
|
+
* <p>Current URL: {{ currentUrl() }}</p>
|
|
18
|
+
* <p>Absolute URL: {{ absoluteUrl() }}</p>
|
|
19
|
+
* </div>
|
|
20
|
+
* `
|
|
21
|
+
* })
|
|
22
|
+
* class UrlComponent {
|
|
23
|
+
* readonly currentUrl = url();
|
|
24
|
+
* readonly absoluteUrl = url({ absolute: true });
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function url(options) {
|
|
29
|
+
const { runInContext } = setupContext(options?.injector, url);
|
|
30
|
+
return runInContext(({ isServer }) => {
|
|
31
|
+
const router = inject(Router);
|
|
32
|
+
if (isServer) {
|
|
33
|
+
return constSignal(router.url);
|
|
34
|
+
}
|
|
35
|
+
const getUrl = () => {
|
|
36
|
+
const relativeUrl = router.url;
|
|
37
|
+
if (options?.absolute) {
|
|
38
|
+
return location.origin + relativeUrl;
|
|
39
|
+
}
|
|
40
|
+
return relativeUrl;
|
|
41
|
+
};
|
|
42
|
+
const result = signal(getUrl(), options);
|
|
43
|
+
routerListener('navigationend', () => result.set(getUrl()));
|
|
44
|
+
return result.asReadonly();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Generated bundle index. Do not edit.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
export { url };
|
|
53
|
+
//# sourceMappingURL=signality-core-router-url.mjs.map
|
|
@@ -0,0 +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;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from '@signality/core/router/params';
|
|
2
|
+
export * from '@signality/core/router/query-params';
|
|
3
|
+
export * from '@signality/core/router/fragment';
|
|
4
|
+
export * from '@signality/core/router/title';
|
|
5
|
+
export * from '@signality/core/router/url';
|
|
6
|
+
export * from '@signality/core/router/route-data';
|
|
7
|
+
export * from '@signality/core/router/router-listener';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generated bundle index. Do not edit.
|
|
11
|
+
*/
|
|
12
|
+
//# sourceMappingURL=signality-core-router.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-router.mjs","sources":["../../../projects/core/router/signality-core-router.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;AAAA;;AAEG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { setupContext, toValue } from '@signality/core/internal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a debounced version of a callback function.
|
|
5
|
+
* The callback will only be executed after the specified wait time has elapsed since the last invocation.
|
|
6
|
+
*
|
|
7
|
+
* @param callback - The function to debounce
|
|
8
|
+
* @param wait - Debounce delay in milliseconds (can be a reactive signal)
|
|
9
|
+
* @param options - Optional configuration including injector
|
|
10
|
+
* @returns A debounced version of the callback function
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @Component({
|
|
15
|
+
* template: `
|
|
16
|
+
* <input (input)="handleInput($event.target.value)" />
|
|
17
|
+
* `,
|
|
18
|
+
* })
|
|
19
|
+
* export class SearchComponent {
|
|
20
|
+
* readonly debounceTime = input(300);
|
|
21
|
+
* readonly searchChange = output<string>();
|
|
22
|
+
*
|
|
23
|
+
* readonly handleInput = debounceCallback(value => {
|
|
24
|
+
* this.searchChange.emit(value);
|
|
25
|
+
* }, this.debounceTime);
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function debounceCallback(callback, wait, options) {
|
|
30
|
+
const { runInContext } = setupContext(options?.injector, debounceCallback);
|
|
31
|
+
return runInContext(({ isServer, onCleanup }) => {
|
|
32
|
+
if (isServer) {
|
|
33
|
+
return callback;
|
|
34
|
+
}
|
|
35
|
+
let timer;
|
|
36
|
+
onCleanup(() => {
|
|
37
|
+
if (timer !== undefined) {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return new Proxy(callback, {
|
|
42
|
+
apply(target, thisArg, args) {
|
|
43
|
+
if (timer !== undefined) {
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
}
|
|
46
|
+
timer = setTimeout(() => {
|
|
47
|
+
target.apply(thisArg, args);
|
|
48
|
+
}, toValue.untracked(wait));
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Generated bundle index. Do not edit.
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
export { debounceCallback };
|
|
59
|
+
//# sourceMappingURL=signality-core-scheduling-debounce-callback.mjs.map
|
|
@@ -0,0 +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;;;;"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { signal, untracked, isSignal } from '@angular/core';
|
|
2
|
+
import { setupContext, NOOP_FN, constSignal, toValue } from '@signality/core/internal';
|
|
3
|
+
import { watcher } from '@signality/core/reactivity/watcher';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a reactive interval that executes a callback function at specified intervals.
|
|
7
|
+
* Automatically handles cleanup and supports reactive interval duration.
|
|
8
|
+
*
|
|
9
|
+
* @param callback - Function to execute on each interval tick, receives current counter value
|
|
10
|
+
* @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
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* @Component({
|
|
17
|
+
* template: `
|
|
18
|
+
* <p>Status: {{ polling.isActive() ? 'Polling' : 'Stopped' }}</p>
|
|
19
|
+
* <button (click)="polling.pause()">Stop</button>
|
|
20
|
+
* <button (click)="polling.resume()">Start</button>
|
|
21
|
+
* `,
|
|
22
|
+
* })
|
|
23
|
+
* export class PeriodicTask {
|
|
24
|
+
* readonly polling = interval(async () => {
|
|
25
|
+
* await this.checkStatus();
|
|
26
|
+
* }, 5000);
|
|
27
|
+
*
|
|
28
|
+
* async checkStatus() {
|
|
29
|
+
* // async operation
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function interval(callback, intervalMs, options) {
|
|
35
|
+
const { runInContext } = setupContext(options?.injector, interval);
|
|
36
|
+
return runInContext(({ isServer, onCleanup }) => {
|
|
37
|
+
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
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const isActive = signal(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
47
|
+
const counter = signal(0, ...(ngDevMode ? [{ debugName: "counter" }] : []));
|
|
48
|
+
let intervalId;
|
|
49
|
+
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);
|
|
81
|
+
};
|
|
82
|
+
if (isSignal(intervalMs)) {
|
|
83
|
+
watcher(intervalMs, newMs => {
|
|
84
|
+
if (isActive() && newMs !== undefined) {
|
|
85
|
+
cleanup();
|
|
86
|
+
start();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
onCleanup(cleanup);
|
|
91
|
+
if (options?.immediate) {
|
|
92
|
+
isActive.set(true);
|
|
93
|
+
start();
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
isActive: isActive.asReadonly(),
|
|
97
|
+
counter: counter.asReadonly(),
|
|
98
|
+
pause,
|
|
99
|
+
resume,
|
|
100
|
+
reset,
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Generated bundle index. Do not edit.
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
export { interval };
|
|
110
|
+
//# sourceMappingURL=signality-core-scheduling-interval.mjs.map
|
|
@@ -0,0 +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;;;;"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { setupContext, toValue } from '@signality/core/internal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a throttled version of a callback function.
|
|
5
|
+
* The callback will be executed at most once per specified wait interval.
|
|
6
|
+
*
|
|
7
|
+
* @param callback - The function to throttle
|
|
8
|
+
* @param wait - Throttle interval in milliseconds (can be a reactive signal)
|
|
9
|
+
* @param options - Optional configuration including injector
|
|
10
|
+
* @returns A throttled version of the callback function
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @Component({
|
|
15
|
+
* template: `
|
|
16
|
+
* <div (scroll)="handleScroll($event)">
|
|
17
|
+
* Scrollable content
|
|
18
|
+
* </div>
|
|
19
|
+
* `,
|
|
20
|
+
* })
|
|
21
|
+
* export class ScrollComponent {
|
|
22
|
+
* readonly throttleTime = input(300);
|
|
23
|
+
* readonly scrollChange = output<Event>();
|
|
24
|
+
*
|
|
25
|
+
* readonly handleScroll = throttleCallback(e => {
|
|
26
|
+
* this.scrollChange.emit(e);
|
|
27
|
+
* }, this.throttleTime);
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function throttleCallback(callback, wait, options) {
|
|
32
|
+
const { runInContext } = setupContext(options?.injector, throttleCallback);
|
|
33
|
+
return runInContext(({ isServer, onCleanup }) => {
|
|
34
|
+
if (isServer) {
|
|
35
|
+
return callback;
|
|
36
|
+
}
|
|
37
|
+
let timer;
|
|
38
|
+
let isThrottled;
|
|
39
|
+
let lastArgs;
|
|
40
|
+
onCleanup(() => {
|
|
41
|
+
if (timer !== undefined) {
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return new Proxy(callback, {
|
|
46
|
+
apply(target, thisArg, args) {
|
|
47
|
+
lastArgs = args;
|
|
48
|
+
if (isThrottled) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
target.apply(thisArg, lastArgs);
|
|
52
|
+
isThrottled = true;
|
|
53
|
+
timer = setTimeout(() => {
|
|
54
|
+
isThrottled = false;
|
|
55
|
+
}, toValue.untracked(wait));
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Generated bundle index. Do not edit.
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
export { throttleCallback };
|
|
66
|
+
//# sourceMappingURL=signality-core-scheduling-throttle-callback.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-scheduling-throttle-callback.mjs","sources":["../../../projects/core/scheduling/throttle-callback/index.ts","../../../projects/core/scheduling/throttle-callback/signality-core-scheduling-throttle-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 throttled version of a callback function.\n * The callback will be executed at most once per specified wait interval.\n *\n * @param callback - The function to throttle\n * @param wait - Throttle interval in milliseconds (can be a reactive signal)\n * @param options - Optional configuration including injector\n * @returns A throttled version of the callback function\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div (scroll)=\"handleScroll($event)\">\n * Scrollable content\n * </div>\n * `,\n * })\n * export class ScrollComponent {\n * readonly throttleTime = input(300);\n * readonly scrollChange = output<Event>();\n *\n * readonly handleScroll = throttleCallback(e => {\n * this.scrollChange.emit(e);\n * }, this.throttleTime);\n * }\n * ```\n */\nexport function throttleCallback<T extends (...args: any[]) => any>(\n callback: T,\n wait: MaybeSignal<number>,\n options?: WithInjector\n): T {\n const { runInContext } = setupContext(options?.injector, throttleCallback);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return callback;\n }\n\n let timer: Timer;\n let isThrottled: boolean;\n let lastArgs: Parameters<T>;\n\n onCleanup(() => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n });\n\n return new Proxy(callback, {\n apply(target, thisArg, args) {\n lastArgs = args as Parameters<T>;\n\n if (isThrottled) {\n return;\n }\n\n target.apply(thisArg, lastArgs);\n isThrottled = true;\n\n timer = setTimeout(() => {\n isThrottled = false;\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;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;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;AAChB,QAAA,IAAI,WAAoB;AACxB,QAAA,IAAI,QAAuB;QAE3B,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;gBACzB,QAAQ,GAAG,IAAqB;gBAEhC,IAAI,WAAW,EAAE;oBACf;gBACF;AAEA,gBAAA,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC;gBAC/B,WAAW,GAAG,IAAI;AAElB,gBAAA,KAAK,GAAG,UAAU,CAAC,MAAK;oBACtB,WAAW,GAAG,KAAK;gBACrB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;AACF,SAAA,CAAC;AACJ,IAAA,CAAC,CAAC;AACJ;;ACtEA;;AAEG;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from '@signality/core/scheduling/debounce-callback';
|
|
2
|
+
export * from '@signality/core/scheduling/interval';
|
|
3
|
+
export * from '@signality/core/scheduling/throttle-callback';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generated bundle index. Do not edit.
|
|
7
|
+
*/
|
|
8
|
+
//# sourceMappingURL=signality-core-scheduling.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-scheduling.mjs","sources":["../../../projects/core/scheduling/signality-core-scheduling.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAAA;;AAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-types.mjs","sources":["../../../projects/core/types/signality-core-types.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAAA;;AAEG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from '@signality/core/reactivity';
|
|
2
|
+
export * from '@signality/core/scheduling';
|
|
3
|
+
export * from '@signality/core/observers';
|
|
4
|
+
export * from '@signality/core/browser';
|
|
5
|
+
export * from '@signality/core/elements';
|
|
6
|
+
export * from '@signality/core/router';
|
|
7
|
+
export * from '@signality/core/forms';
|
|
8
|
+
export * from '@signality/core/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generated bundle index. Do not edit.
|
|
12
|
+
*/
|
|
13
|
+
//# sourceMappingURL=signality-core.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core.mjs","sources":["../../../projects/core/signality-core.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;AAAA;;AAEG"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type Signal, type WritableSignal } from '@angular/core';
|
|
2
|
+
import { type ValidationErrors } from '@angular/forms';
|
|
3
|
+
import type { WithInjector } from '@signality/core/types';
|
|
4
|
+
export type CvaOptions<T> = Omit<Partial<MakeWritable<CvaRef<T>>>, 'value'> & Pick<CvaRef<T>, 'value'> & WithInjector;
|
|
5
|
+
export interface CvaRef<T> {
|
|
6
|
+
readonly value: WritableSignal<T>;
|
|
7
|
+
readonly touched: WritableSignal<boolean>;
|
|
8
|
+
readonly disabled: Signal<boolean>;
|
|
9
|
+
readonly required: Signal<boolean>;
|
|
10
|
+
readonly invalid: Signal<boolean>;
|
|
11
|
+
readonly pending: Signal<boolean>;
|
|
12
|
+
readonly dirty: Signal<boolean>;
|
|
13
|
+
readonly errors: Signal<ValidationErrors | null>;
|
|
14
|
+
readonly reset: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Reactive wrapper around the [Angular Forms](https://angular.dev/guide/forms) Control Value Accessor (CVA) pattern.
|
|
18
|
+
* Integrates seamlessly with both template-driven and reactive forms.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Configuration options including the value signal
|
|
21
|
+
* @returns A CvaRef with reactive form control state signals
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* @Component({
|
|
26
|
+
* selector: 'app-currency-input',
|
|
27
|
+
* template: `
|
|
28
|
+
* <input
|
|
29
|
+
* type="text"
|
|
30
|
+
* [value]="displayValue()"
|
|
31
|
+
* [required]="cva.required()"
|
|
32
|
+
* (input)="handleInput($any($event.target).value)"
|
|
33
|
+
* (blur)="cva.touched.set(true)"
|
|
34
|
+
* />
|
|
35
|
+
* `,
|
|
36
|
+
* })
|
|
37
|
+
* export class CurrencyInput {
|
|
38
|
+
* readonly value = model(0);
|
|
39
|
+
* readonly cva = cva({ value: this.value });
|
|
40
|
+
*
|
|
41
|
+
* readonly displayValue = computed(() => {
|
|
42
|
+
* return this.value()
|
|
43
|
+
* .toFixed(2)
|
|
44
|
+
* .replace(/\B(?=(\d{3})+(?!\d))/g, ','); // Shows "1,234.56"
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* handleInput(input: string) {
|
|
48
|
+
* const num = parseFloat(input.replace(/[^0-9.]/g, ''));
|
|
49
|
+
* if (!isNaN(num)) {
|
|
50
|
+
* this.value.set(num);
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function cva<T>(options: CvaOptions<T>): CvaRef<T>;
|
|
57
|
+
type MakeWritable<T extends object> = {
|
|
58
|
+
[K in keyof T]: T[K] extends Signal<infer U> ? WritableSignal<U> : never;
|
|
59
|
+
};
|
|
60
|
+
export {};
|
package/forms/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@signality/core/forms/cva';
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from '@signality/core/reactivity';
|
|
2
|
+
export * from '@signality/core/scheduling';
|
|
3
|
+
export * from '@signality/core/observers';
|
|
4
|
+
export * from '@signality/core/browser';
|
|
5
|
+
export * from '@signality/core/elements';
|
|
6
|
+
export * from '@signality/core/router';
|
|
7
|
+
export * from '@signality/core/forms';
|
|
8
|
+
export * from '@signality/core/types';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MOBILE_REGEX: RegExp;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Empty synchronous function stub.
|
|
3
|
+
* Used for SSR compatibility when returning method functions in Ref objects that should do nothing on the server.
|
|
4
|
+
*
|
|
5
|
+
* Example: `close: NOOP_FN` in {@link WebNotificationRef}
|
|
6
|
+
*/
|
|
7
|
+
export declare const NOOP_FN: (...args: any[]) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Empty asynchronous function stub that returns a resolved Promise.
|
|
10
|
+
* Used for SSR compatibility when returning async method functions in Ref objects that should do nothing on the server.
|
|
11
|
+
*
|
|
12
|
+
* Example: `share: NOOP_ASYNC_FN` in {@link WebShareRef}
|
|
13
|
+
*/
|
|
14
|
+
export declare const NOOP_ASYNC_FN: () => Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Frozen EffectRef stub with a no-op destroy method.
|
|
17
|
+
* Used for SSR compatibility when returning EffectRef from observer utilities (ResizeObserver, MutationObserver, etc.)
|
|
18
|
+
* that cannot run on the server. Prevents errors when calling destroy() on server-rendered refs.
|
|
19
|
+
*
|
|
20
|
+
* Example: `return NOOP_EFFECT_REF` in {@link resizeObserver}
|
|
21
|
+
*/
|
|
22
|
+
export declare const NOOP_EFFECT_REF: {
|
|
23
|
+
destroy: (...args: any[]) => void;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Equality function that always returns false, forcing signal updates on every change.
|
|
27
|
+
* Used for signals that hold mutable objects (like Selection, Range) where reference equality is not sufficient
|
|
28
|
+
* and we need to detect changes even when the object structure appears the same.
|
|
29
|
+
*
|
|
30
|
+
* Example: `signal<Selection | null>(null, { equal: ALWAYS_FALSE_FN })` in {@link textSelection}
|
|
31
|
+
*/
|
|
32
|
+
export declare const ALWAYS_FALSE_FN: () => boolean;
|