@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,149 @@
|
|
|
1
|
+
import { signal, inject, computed, untracked, effect } from '@angular/core';
|
|
2
|
+
import { setupContext, constSignal, NOOP_ASYNC_FN } from '@signality/core/internal';
|
|
3
|
+
import { setupSync, listener } from '@signality/core/browser/listener';
|
|
4
|
+
import { PAGE_VISIBILITY } from '@signality/core/browser/page-visibility';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Signal-based wrapper around the [Screen Wake Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API).
|
|
8
|
+
*
|
|
9
|
+
* @param options - Optional configuration
|
|
10
|
+
* @returns A WakeLockRef with isSupported, isActive, sentinel signals and control methods
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const wakeLock = wakeLock();
|
|
15
|
+
*
|
|
16
|
+
* if (wakeLock.isSupported()) {
|
|
17
|
+
* await wakeLock.request();
|
|
18
|
+
* // Screen will stay awake
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function wakeLock(options) {
|
|
23
|
+
const { runInContext } = setupContext(options?.injector, wakeLock);
|
|
24
|
+
return runInContext(({ isBrowser, onCleanup, injector }) => {
|
|
25
|
+
const sentinel = signal(null, ...(ngDevMode ? [{ debugName: "sentinel" }] : []));
|
|
26
|
+
const requestedType = signal(false, ...(ngDevMode ? [{ debugName: "requestedType" }] : []));
|
|
27
|
+
const isSupported = constSignal(isBrowser &&
|
|
28
|
+
'wakeLock' in navigator &&
|
|
29
|
+
typeof navigator.wakeLock?.request === 'function');
|
|
30
|
+
if (!isSupported()) {
|
|
31
|
+
return {
|
|
32
|
+
isSupported,
|
|
33
|
+
isActive: constSignal(false),
|
|
34
|
+
sentinel: sentinel.asReadonly(),
|
|
35
|
+
request: NOOP_ASYNC_FN,
|
|
36
|
+
forceRequest: NOOP_ASYNC_FN,
|
|
37
|
+
release: NOOP_ASYNC_FN,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const visibility = inject(PAGE_VISIBILITY);
|
|
41
|
+
const { autoReacquire = true } = options ?? {};
|
|
42
|
+
const isActive = computed(() => {
|
|
43
|
+
const s = sentinel();
|
|
44
|
+
return !!s && !s.released && visibility() === 'visible';
|
|
45
|
+
}, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
46
|
+
let listenerRef = null;
|
|
47
|
+
const forceRequest = async () => {
|
|
48
|
+
try {
|
|
49
|
+
const currentSentinel = untracked(sentinel);
|
|
50
|
+
if (currentSentinel) {
|
|
51
|
+
if (listenerRef) {
|
|
52
|
+
listenerRef.destroy();
|
|
53
|
+
listenerRef = null;
|
|
54
|
+
}
|
|
55
|
+
if (!currentSentinel.released) {
|
|
56
|
+
await currentSentinel.release();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (untracked(visibility) === 'visible') {
|
|
60
|
+
const newSentinel = await navigator.wakeLock.request('screen');
|
|
61
|
+
sentinel.set(newSentinel);
|
|
62
|
+
listenerRef = setupSync(() => listener(newSentinel, 'release', () => {
|
|
63
|
+
requestedType.set(false);
|
|
64
|
+
sentinel.set(null);
|
|
65
|
+
listenerRef = null;
|
|
66
|
+
}, { injector }));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
sentinel.set(null);
|
|
71
|
+
requestedType.set(false);
|
|
72
|
+
if (listenerRef) {
|
|
73
|
+
listenerRef = null;
|
|
74
|
+
}
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const request = async () => {
|
|
79
|
+
if (untracked(visibility) === 'visible') {
|
|
80
|
+
await forceRequest();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
requestedType.set('screen');
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const release = async () => {
|
|
87
|
+
requestedType.set(false);
|
|
88
|
+
const currentSentinel = untracked(sentinel);
|
|
89
|
+
sentinel.set(null);
|
|
90
|
+
if (currentSentinel) {
|
|
91
|
+
if (listenerRef) {
|
|
92
|
+
listenerRef.destroy();
|
|
93
|
+
listenerRef = null;
|
|
94
|
+
}
|
|
95
|
+
if (!currentSentinel.released) {
|
|
96
|
+
try {
|
|
97
|
+
await currentSentinel.release();
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (ngDevMode) {
|
|
101
|
+
console.warn('[wakeLock] Failed to release wake lock.', err);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
if (autoReacquire) {
|
|
108
|
+
effect(() => {
|
|
109
|
+
const isVisible = visibility() === 'visible';
|
|
110
|
+
const pendingType = requestedType();
|
|
111
|
+
if (isVisible && pendingType) {
|
|
112
|
+
requestedType.set(false);
|
|
113
|
+
forceRequest().catch(() => {
|
|
114
|
+
/* ignore errors, will retry on next visibility change */
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
onCleanup(() => {
|
|
120
|
+
const currentSentinel = sentinel();
|
|
121
|
+
if (currentSentinel) {
|
|
122
|
+
if (listenerRef) {
|
|
123
|
+
listenerRef.destroy();
|
|
124
|
+
listenerRef = null;
|
|
125
|
+
}
|
|
126
|
+
if (!currentSentinel.released) {
|
|
127
|
+
currentSentinel.release().catch(() => {
|
|
128
|
+
/* ignore errors */
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
isSupported,
|
|
135
|
+
isActive,
|
|
136
|
+
sentinel: sentinel.asReadonly(),
|
|
137
|
+
request,
|
|
138
|
+
forceRequest,
|
|
139
|
+
release,
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generated bundle index. Do not edit.
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
export { wakeLock };
|
|
149
|
+
//# sourceMappingURL=signality-core-browser-wake-lock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-browser-wake-lock.mjs","sources":["../../../projects/core/browser/wake-lock/index.ts","../../../projects/core/browser/wake-lock/signality-core-browser-wake-lock.ts"],"sourcesContent":["import { computed, effect, inject, type Signal, signal, untracked } from '@angular/core';\nimport { constSignal, NOOP_ASYNC_FN, setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\nimport { listener, type ListenerRef, setupSync } from '@signality/core/browser/listener';\nimport { PAGE_VISIBILITY } from '@signality/core/browser/page-visibility';\n\nexport interface WakeLockOptions extends WithInjector {\n /** Whether to automatically reacquire wake lock when document becomes visible */\n readonly autoReacquire?: boolean;\n}\n\nexport interface WakeLockRef {\n /** Whether Screen Wake Lock API is supported */\n readonly isSupported: Signal<boolean>;\n\n /** Whether wake lock is currently active */\n readonly isActive: Signal<boolean>;\n\n /** Current wake lock sentinel */\n readonly sentinel: Signal<WakeLockSentinel | null>;\n\n /** Request a wake lock */\n readonly request: () => Promise<void>;\n\n /** Force request a wake lock (releases existing one first) */\n readonly forceRequest: () => Promise<void>;\n\n /** Release the wake lock */\n readonly release: () => Promise<void>;\n}\n\n/**\n * Signal-based wrapper around the [Screen Wake Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API).\n *\n * @param options - Optional configuration\n * @returns A WakeLockRef with isSupported, isActive, sentinel signals and control methods\n *\n * @example\n * ```typescript\n * const wakeLock = wakeLock();\n *\n * if (wakeLock.isSupported()) {\n * await wakeLock.request();\n * // Screen will stay awake\n * }\n * ```\n */\nexport function wakeLock(options?: WakeLockOptions): WakeLockRef {\n const { runInContext } = setupContext(options?.injector, wakeLock);\n\n return runInContext(({ isBrowser, onCleanup, injector }) => {\n const sentinel = signal<WakeLockSentinel | null>(null);\n const requestedType = signal<'screen' | false>(false);\n\n const isSupported = constSignal(\n isBrowser &&\n 'wakeLock' in navigator &&\n typeof (navigator as NavigatorWithWakeLock).wakeLock?.request === 'function'\n );\n\n if (!isSupported()) {\n return {\n isSupported,\n isActive: constSignal(false),\n sentinel: sentinel.asReadonly(),\n request: NOOP_ASYNC_FN,\n forceRequest: NOOP_ASYNC_FN,\n release: NOOP_ASYNC_FN,\n };\n }\n\n const visibility = inject(PAGE_VISIBILITY);\n\n const { autoReacquire = true } = options ?? {};\n\n const isActive = computed(() => {\n const s = sentinel();\n return !!s && !s.released && visibility() === 'visible';\n });\n\n let listenerRef: ListenerRef | null = null;\n\n const forceRequest = async (): Promise<void> => {\n try {\n const currentSentinel = untracked(sentinel);\n\n if (currentSentinel) {\n if (listenerRef) {\n listenerRef.destroy();\n listenerRef = null;\n }\n\n if (!currentSentinel.released) {\n await currentSentinel.release();\n }\n }\n\n if (untracked(visibility) === 'visible') {\n const newSentinel = await (navigator as NavigatorWithWakeLock).wakeLock.request('screen');\n\n sentinel.set(newSentinel);\n\n listenerRef = setupSync(() =>\n listener(\n newSentinel,\n 'release',\n () => {\n requestedType.set(false);\n sentinel.set(null);\n listenerRef = null;\n },\n { injector }\n )\n );\n }\n } catch (err) {\n sentinel.set(null);\n requestedType.set(false);\n\n if (listenerRef) {\n listenerRef = null;\n }\n\n throw err;\n }\n };\n\n const request = async (): Promise<void> => {\n if (untracked(visibility) === 'visible') {\n await forceRequest();\n } else {\n requestedType.set('screen');\n }\n };\n\n const release = async (): Promise<void> => {\n requestedType.set(false);\n\n const currentSentinel = untracked(sentinel);\n\n sentinel.set(null);\n\n if (currentSentinel) {\n if (listenerRef) {\n listenerRef.destroy();\n listenerRef = null;\n }\n if (!currentSentinel.released) {\n try {\n await currentSentinel.release();\n } catch (err) {\n if (ngDevMode) {\n console.warn('[wakeLock] Failed to release wake lock.', err);\n }\n }\n }\n }\n };\n\n if (autoReacquire) {\n effect(() => {\n const isVisible = visibility() === 'visible';\n const pendingType = requestedType();\n\n if (isVisible && pendingType) {\n requestedType.set(false);\n forceRequest().catch(() => {\n /* ignore errors, will retry on next visibility change */\n });\n }\n });\n }\n\n onCleanup(() => {\n const currentSentinel = sentinel();\n if (currentSentinel) {\n if (listenerRef) {\n listenerRef.destroy();\n listenerRef = null;\n }\n if (!currentSentinel.released) {\n currentSentinel.release().catch(() => {\n /* ignore errors */\n });\n }\n }\n });\n\n return {\n isSupported,\n isActive,\n sentinel: sentinel.asReadonly(),\n request,\n forceRequest,\n release,\n };\n });\n}\n\ninterface NavigatorWithWakeLock extends Navigator {\n readonly wakeLock: {\n readonly request: (type: 'screen') => Promise<WakeLockSentinel>;\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { signal, untracked } from '@angular/core';
|
|
2
|
+
import { setupContext, constSignal, NOOP_FN, toValue } from '@signality/core/internal';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal-based wrapper around the Notifications API.
|
|
6
|
+
*
|
|
7
|
+
* Tracks the current notification as a signal. Calling `show()` auto-closes
|
|
8
|
+
* the previous notification. Calling `close()` closes the current one.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Optional configuration and default notification options
|
|
11
|
+
* @returns A WebNotificationRef with notification state and control methods
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* @Component({
|
|
16
|
+
* template: `
|
|
17
|
+
* <button (click)="requestPermission()">Request Permission</button>
|
|
18
|
+
* <button (click)="showNotification()" [disabled]="notif.permission() !== 'granted'">
|
|
19
|
+
* Show Notification
|
|
20
|
+
* </button>
|
|
21
|
+
* @if (notif.notification()) {
|
|
22
|
+
* <button (click)="notif.close()">Close</button>
|
|
23
|
+
* }
|
|
24
|
+
* `
|
|
25
|
+
* })
|
|
26
|
+
* class NotificationComponent {
|
|
27
|
+
* readonly notif = webNotification({ icon: '/icon.png' });
|
|
28
|
+
*
|
|
29
|
+
* async requestPermission() {
|
|
30
|
+
* await this.notif.requestPermission();
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* showNotification() {
|
|
34
|
+
* this.notif.show('Hello!', { body: 'This is a notification' });
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function webNotification(options) {
|
|
40
|
+
const { runInContext } = setupContext(options?.injector, webNotification);
|
|
41
|
+
return runInContext(({ isBrowser, onCleanup }) => {
|
|
42
|
+
const isSupported = constSignal(isBrowser && 'Notification' in window);
|
|
43
|
+
if (!isSupported()) {
|
|
44
|
+
return {
|
|
45
|
+
isSupported,
|
|
46
|
+
permission: constSignal('denied'),
|
|
47
|
+
notification: constSignal(null),
|
|
48
|
+
requestPermission: async () => 'denied',
|
|
49
|
+
show: () => undefined,
|
|
50
|
+
close: NOOP_FN,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const permission = signal(Notification.permission, ...(ngDevMode ? [{ debugName: "permission" }] : []));
|
|
54
|
+
const notification = signal(null, ...(ngDevMode ? [{ debugName: "notification" }] : []));
|
|
55
|
+
let autoCloseTimeout;
|
|
56
|
+
const clearAutoClose = () => {
|
|
57
|
+
if (autoCloseTimeout) {
|
|
58
|
+
clearTimeout(autoCloseTimeout);
|
|
59
|
+
autoCloseTimeout = undefined;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const requestPermission = async () => {
|
|
63
|
+
try {
|
|
64
|
+
const result = await Notification.requestPermission();
|
|
65
|
+
permission.set(result);
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (ngDevMode) {
|
|
70
|
+
console.warn(`[webNotification] Failed to request notification permission.`, error);
|
|
71
|
+
}
|
|
72
|
+
return permission();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const close = () => {
|
|
76
|
+
clearAutoClose();
|
|
77
|
+
const current = untracked(notification);
|
|
78
|
+
if (current) {
|
|
79
|
+
try {
|
|
80
|
+
current.onclose = null;
|
|
81
|
+
current.close();
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (ngDevMode) {
|
|
85
|
+
console.warn(`[webNotification] Failed to close notification.`, error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
notification.set(null);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const show = (title, overrides) => {
|
|
92
|
+
return untracked(() => {
|
|
93
|
+
if (permission() !== 'granted') {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
close();
|
|
97
|
+
try {
|
|
98
|
+
const { autoClose, ...defaults } = options ?? {};
|
|
99
|
+
const mergedOptions = { ...defaults, ...overrides };
|
|
100
|
+
const instance = new Notification(title, mergedOptions);
|
|
101
|
+
instance.onclose = () => {
|
|
102
|
+
clearAutoClose();
|
|
103
|
+
notification.set(null);
|
|
104
|
+
};
|
|
105
|
+
notification.set(instance);
|
|
106
|
+
const autoCloseMs = toValue(autoClose);
|
|
107
|
+
if (autoCloseMs && autoCloseMs > 0) {
|
|
108
|
+
autoCloseTimeout = setTimeout(close, autoCloseMs);
|
|
109
|
+
}
|
|
110
|
+
return instance;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (ngDevMode) {
|
|
114
|
+
console.warn(`[webNotification] Failed to show notification.`, error);
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
onCleanup(close);
|
|
121
|
+
return {
|
|
122
|
+
isSupported,
|
|
123
|
+
permission: permission.asReadonly(),
|
|
124
|
+
notification: notification.asReadonly(),
|
|
125
|
+
requestPermission,
|
|
126
|
+
show,
|
|
127
|
+
close,
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Generated bundle index. Do not edit.
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
export { webNotification };
|
|
137
|
+
//# sourceMappingURL=signality-core-browser-web-notification.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-browser-web-notification.mjs","sources":["../../../projects/core/browser/web-notification/index.ts","../../../projects/core/browser/web-notification/signality-core-browser-web-notification.ts"],"sourcesContent":["import { type Signal, 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';\n\nexport interface WebNotificationOptions extends NotificationOptions, WithInjector {\n /**\n * Auto-close notification after specified milliseconds.\n */\n readonly autoClose?: MaybeSignal<number>;\n}\n\nexport interface WebNotificationRef {\n /** Whether Notifications API is supported */\n readonly isSupported: Signal<boolean>;\n\n /** Current permission state */\n readonly permission: Signal<NotificationPermission>;\n\n /** Current active notification instance */\n readonly notification: Signal<Notification | null>;\n\n /** Request notification permission */\n readonly requestPermission: () => Promise<NotificationPermission>;\n\n /** Show a notification (auto-closes previous). Per-call options override defaults from constructor. */\n readonly show: (title: string, options?: NotificationOptions) => Notification | undefined;\n\n /** Close the current notification */\n readonly close: () => void;\n}\n\n/**\n * Signal-based wrapper around the Notifications API.\n *\n * Tracks the current notification as a signal. Calling `show()` auto-closes\n * the previous notification. Calling `close()` closes the current one.\n *\n * @param options - Optional configuration and default notification options\n * @returns A WebNotificationRef with notification state and control methods\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <button (click)=\"requestPermission()\">Request Permission</button>\n * <button (click)=\"showNotification()\" [disabled]=\"notif.permission() !== 'granted'\">\n * Show Notification\n * </button>\n * @if (notif.notification()) {\n * <button (click)=\"notif.close()\">Close</button>\n * }\n * `\n * })\n * class NotificationComponent {\n * readonly notif = webNotification({ icon: '/icon.png' });\n *\n * async requestPermission() {\n * await this.notif.requestPermission();\n * }\n *\n * showNotification() {\n * this.notif.show('Hello!', { body: 'This is a notification' });\n * }\n * }\n * ```\n */\nexport function webNotification(options?: WebNotificationOptions): WebNotificationRef {\n const { runInContext } = setupContext(options?.injector, webNotification);\n\n return runInContext(({ isBrowser, onCleanup }) => {\n const isSupported = constSignal(isBrowser && 'Notification' in window);\n\n if (!isSupported()) {\n return {\n isSupported,\n permission: constSignal('denied'),\n notification: constSignal(null),\n requestPermission: async () => 'denied',\n show: () => undefined,\n close: NOOP_FN,\n };\n }\n\n const permission = signal(Notification.permission);\n const notification = signal<Notification | null>(null);\n\n let autoCloseTimeout: Timer;\n\n const clearAutoClose = () => {\n if (autoCloseTimeout) {\n clearTimeout(autoCloseTimeout);\n autoCloseTimeout = undefined;\n }\n };\n\n const requestPermission = async (): Promise<NotificationPermission> => {\n try {\n const result = await Notification.requestPermission();\n permission.set(result);\n return result;\n } catch (error) {\n if (ngDevMode) {\n console.warn(`[webNotification] Failed to request notification permission.`, error);\n }\n return permission();\n }\n };\n\n const close = (): void => {\n clearAutoClose();\n\n const current = untracked(notification);\n\n if (current) {\n try {\n current.onclose = null;\n current.close();\n } catch (error) {\n if (ngDevMode) {\n console.warn(`[webNotification] Failed to close notification.`, error);\n }\n }\n notification.set(null);\n }\n };\n\n const show = (title: string, overrides?: NotificationOptions): Notification | undefined => {\n return untracked(() => {\n if (permission() !== 'granted') {\n return undefined;\n }\n\n close();\n\n try {\n const { autoClose, ...defaults } = options ?? {};\n const mergedOptions = { ...defaults, ...overrides };\n\n const instance = new Notification(title, mergedOptions);\n\n instance.onclose = () => {\n clearAutoClose();\n notification.set(null);\n };\n\n notification.set(instance);\n\n const autoCloseMs = toValue(autoClose);\n if (autoCloseMs && autoCloseMs > 0) {\n autoCloseTimeout = setTimeout(close, autoCloseMs);\n }\n\n return instance;\n } catch (error) {\n if (ngDevMode) {\n console.warn(`[webNotification] Failed to show notification.`, error);\n }\n return undefined;\n }\n });\n };\n\n onCleanup(close);\n\n return {\n isSupported,\n permission: permission.asReadonly(),\n notification: notification.asReadonly(),\n requestPermission,\n show,\n close,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { signal, untracked } from '@angular/core';
|
|
2
|
+
import { setupContext, constSignal, NOOP_ASYNC_FN } from '@signality/core/internal';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signal-based wrapper around the [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API).
|
|
6
|
+
*
|
|
7
|
+
* @param options - Optional injector for DI context
|
|
8
|
+
* @returns A WebShareRef with share methods and state signals
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* @Component({
|
|
13
|
+
* template: `
|
|
14
|
+
* @if (webShare.isSupported()) {
|
|
15
|
+
* <button (click)="shareContent()" [disabled]="webShare.isSharing()">
|
|
16
|
+
* Share This Page
|
|
17
|
+
* </button>
|
|
18
|
+
* }
|
|
19
|
+
* `
|
|
20
|
+
* })
|
|
21
|
+
* class WebShareComponent {
|
|
22
|
+
* readonly webShare = webShare();
|
|
23
|
+
*
|
|
24
|
+
* async shareContent() {
|
|
25
|
+
* await this.webShare.share({
|
|
26
|
+
* title: 'Check this out!',
|
|
27
|
+
* url: window.location.href,
|
|
28
|
+
* });
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function webShare(options) {
|
|
34
|
+
const { runInContext } = setupContext(options?.injector, webShare);
|
|
35
|
+
return runInContext(({ isBrowser }) => {
|
|
36
|
+
const isSupported = constSignal(isBrowser && 'share' in navigator);
|
|
37
|
+
if (!isSupported()) {
|
|
38
|
+
return {
|
|
39
|
+
isSupported,
|
|
40
|
+
isSharing: constSignal(false),
|
|
41
|
+
canShare: () => false,
|
|
42
|
+
share: NOOP_ASYNC_FN,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const isSharing = signal(false, ...(ngDevMode ? [{ debugName: "isSharing" }] : []));
|
|
46
|
+
const share = async (data) => {
|
|
47
|
+
if (untracked(isSharing)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
isSharing.set(true);
|
|
52
|
+
await navigator.share(data);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
// user canceled, or share failed
|
|
56
|
+
// AbortError is expected when a user cancels
|
|
57
|
+
if (error.name !== 'AbortError') {
|
|
58
|
+
if (ngDevMode) {
|
|
59
|
+
console.warn(`[webShare] Failed to share content.`, error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
isSharing.set(false);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const canShare = (data) => {
|
|
68
|
+
try {
|
|
69
|
+
return navigator.canShare(data);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (ngDevMode) {
|
|
73
|
+
console.warn(`[webShare] Failed to check if content can be shared.`, error);
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
isSupported,
|
|
80
|
+
isSharing: isSharing.asReadonly(),
|
|
81
|
+
canShare,
|
|
82
|
+
share,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Generated bundle index. Do not edit.
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
export { webShare };
|
|
92
|
+
//# sourceMappingURL=signality-core-browser-web-share.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-browser-web-share.mjs","sources":["../../../projects/core/browser/web-share/index.ts","../../../projects/core/browser/web-share/signality-core-browser-web-share.ts"],"sourcesContent":["import { type Signal, signal, untracked } from '@angular/core';\nimport { constSignal, NOOP_ASYNC_FN, setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport interface WebShareRef {\n /** Whether Web Share API is supported */\n readonly isSupported: Signal<boolean>;\n\n /** Whether the share dialog is currently open */\n readonly isSharing: Signal<boolean>;\n\n /** Open the native share dialog */\n readonly share: (data: ShareData) => Promise<void>;\n\n /** Check if data can be shared */\n readonly canShare: (data?: ShareData) => boolean;\n}\n\n/**\n * Signal-based wrapper around the [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API).\n *\n * @param options - Optional injector for DI context\n * @returns A WebShareRef with share methods and state signals\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * @if (webShare.isSupported()) {\n * <button (click)=\"shareContent()\" [disabled]=\"webShare.isSharing()\">\n * Share This Page\n * </button>\n * }\n * `\n * })\n * class WebShareComponent {\n * readonly webShare = webShare();\n *\n * async shareContent() {\n * await this.webShare.share({\n * title: 'Check this out!',\n * url: window.location.href,\n * });\n * }\n * }\n * ```\n */\nexport function webShare(options?: WithInjector): WebShareRef {\n const { runInContext } = setupContext(options?.injector, webShare);\n\n return runInContext(({ isBrowser }) => {\n const isSupported = constSignal(isBrowser && 'share' in navigator);\n\n if (!isSupported()) {\n return {\n isSupported,\n isSharing: constSignal(false),\n canShare: () => false,\n share: NOOP_ASYNC_FN,\n };\n }\n\n const isSharing = signal(false);\n\n const share = async (data: ShareData): Promise<void> => {\n if (untracked(isSharing)) {\n return;\n }\n\n try {\n isSharing.set(true);\n await navigator.share(data);\n } catch (error) {\n // user canceled, or share failed\n // AbortError is expected when a user cancels\n if ((error as Error).name !== 'AbortError') {\n if (ngDevMode) {\n console.warn(`[webShare] Failed to share content.`, error);\n }\n }\n } finally {\n isSharing.set(false);\n }\n };\n\n const canShare = (data?: ShareData): boolean => {\n try {\n return navigator.canShare(data);\n } catch (error) {\n if (ngDevMode) {\n console.warn(`[webShare] Failed to check if content can be shared.`, error);\n }\n return false;\n }\n };\n\n return {\n isSupported,\n isSharing: isSharing.asReadonly(),\n canShare,\n share,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;AACG,SAAU,QAAQ,CAAC,OAAsB,EAAA;AAC7C,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAElE,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,KAAI;QACpC,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,IAAI,OAAO,IAAI,SAAS,CAAC;AAElE,QAAA,IAAI,CAAC,WAAW,EAAE,EAAE;YAClB,OAAO;gBACL,WAAW;AACX,gBAAA,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC;AAC7B,gBAAA,QAAQ,EAAE,MAAM,KAAK;AACrB,gBAAA,KAAK,EAAE,aAAa;aACrB;QACH;AAEA,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,qDAAC;AAE/B,QAAA,MAAM,KAAK,GAAG,OAAO,IAAe,KAAmB;AACrD,YAAA,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE;gBACxB;YACF;AAEA,YAAA,IAAI;AACF,gBAAA,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACnB,gBAAA,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YAC7B;YAAE,OAAO,KAAK,EAAE;;;AAGd,gBAAA,IAAK,KAAe,CAAC,IAAI,KAAK,YAAY,EAAE;oBAC1C,IAAI,SAAS,EAAE;AACb,wBAAA,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,CAAC;oBAC5D;gBACF;YACF;oBAAU;AACR,gBAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YACtB;AACF,QAAA,CAAC;AAED,QAAA,MAAM,QAAQ,GAAG,CAAC,IAAgB,KAAa;AAC7C,YAAA,IAAI;AACF,gBAAA,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjC;YAAE,OAAO,KAAK,EAAE;gBACd,IAAI,SAAS,EAAE;AACb,oBAAA,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,KAAK,CAAC;gBAC7E;AACA,gBAAA,OAAO,KAAK;YACd;AACF,QAAA,CAAC;QAED,OAAO;YACL,WAAW;AACX,YAAA,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE;YACjC,QAAQ;YACR,KAAK;SACN;AACH,IAAA,CAAC,CAAC;AACJ;;ACvGA;;AAEG;;;;"}
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
* Signal-based wrapper around the Web Workers API.
|
|
7
|
+
*
|
|
8
|
+
* @param url - Worker script URL
|
|
9
|
+
* @param options - Optional configuration
|
|
10
|
+
* @returns A WebWorkerRef with data signal and control methods
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @Component({
|
|
15
|
+
* template: `
|
|
16
|
+
* <button (click)="worker.post(42)">Calculate</button>
|
|
17
|
+
* @if (worker.data()) {
|
|
18
|
+
* <p>Result: {{ worker.data() }}</p>
|
|
19
|
+
* }
|
|
20
|
+
* `
|
|
21
|
+
* })
|
|
22
|
+
* class WorkerComponent {
|
|
23
|
+
* readonly worker = webWorker<number, number>('/workers/calc.js');
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function webWorker(url, options) {
|
|
28
|
+
const { runInContext } = setupContext(options?.injector, webWorker);
|
|
29
|
+
return runInContext(({ isServer, onCleanup }) => {
|
|
30
|
+
if (isServer) {
|
|
31
|
+
return {
|
|
32
|
+
data: constSignal(undefined),
|
|
33
|
+
isReady: constSignal(false),
|
|
34
|
+
error: constSignal(null),
|
|
35
|
+
post: NOOP_FN,
|
|
36
|
+
terminate: NOOP_FN,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const type = options?.type ?? 'classic';
|
|
40
|
+
const credentials = options?.credentials;
|
|
41
|
+
const name = options?.name;
|
|
42
|
+
const data = signal(undefined, ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
43
|
+
const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : []));
|
|
44
|
+
const error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
45
|
+
let worker = null;
|
|
46
|
+
const createWorker = (workerUrl) => {
|
|
47
|
+
if (worker) {
|
|
48
|
+
worker.terminate();
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
worker = new Worker(workerUrl, { type, credentials, name });
|
|
52
|
+
worker.onmessage = (event) => {
|
|
53
|
+
data.set(event.data);
|
|
54
|
+
};
|
|
55
|
+
worker.onerror = (event) => {
|
|
56
|
+
error.set(new Error(event.message));
|
|
57
|
+
};
|
|
58
|
+
worker.onmessageerror = () => {
|
|
59
|
+
error.set(new Error('Message deserialization error'));
|
|
60
|
+
};
|
|
61
|
+
isReady.set(true);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
error.set(e);
|
|
65
|
+
isReady.set(false);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const post = (message) => {
|
|
69
|
+
if (worker && untracked(isReady)) {
|
|
70
|
+
try {
|
|
71
|
+
worker.postMessage(message);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
error.set(e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const terminate = () => {
|
|
79
|
+
if (worker) {
|
|
80
|
+
worker.terminate();
|
|
81
|
+
worker = null;
|
|
82
|
+
isReady.set(false);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
if (isSignal(url)) {
|
|
86
|
+
watcher(url, createWorker);
|
|
87
|
+
}
|
|
88
|
+
onCleanup(terminate);
|
|
89
|
+
createWorker(toValue(url));
|
|
90
|
+
return {
|
|
91
|
+
data: data.asReadonly(),
|
|
92
|
+
isReady: isReady.asReadonly(),
|
|
93
|
+
error: error.asReadonly(),
|
|
94
|
+
post,
|
|
95
|
+
terminate,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Generated bundle index. Do not edit.
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
export { webWorker };
|
|
105
|
+
//# sourceMappingURL=signality-core-browser-web-worker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-browser-web-worker.mjs","sources":["../../../projects/core/browser/web-worker/index.ts","../../../projects/core/browser/web-worker/signality-core-browser-web-worker.ts"],"sourcesContent":["import { isSignal, type Signal, signal, untracked } from '@angular/core';\nimport { constSignal, NOOP_FN, setupContext, toValue } from '@signality/core/internal';\nimport type { MaybeSignal, WithInjector } from '@signality/core/types';\nimport { watcher } from '@signality/core/reactivity/watcher';\n\nexport interface WebWorkerOptions extends WithInjector {\n /**\n * Worker type.\n * @default 'classic'\n */\n readonly type?: 'classic' | 'module';\n\n /**\n * Credentials mode.\n */\n readonly credentials?: RequestCredentials;\n\n /**\n * Worker name for debugging.\n */\n readonly name?: string;\n}\n\nexport interface WebWorkerRef<I, O> {\n /** Last message received from worker */\n readonly data: Signal<O | undefined>;\n\n /** Whether worker is ready */\n readonly isReady: Signal<boolean>;\n\n /** Last error from worker */\n readonly error: Signal<Error | null>;\n\n /** Send message to worker */\n readonly post: (data: I) => void;\n\n /** Terminate the worker */\n readonly terminate: () => void;\n}\n\n/**\n * Signal-based wrapper around the Web Workers API.\n *\n * @param url - Worker script URL\n * @param options - Optional configuration\n * @returns A WebWorkerRef with data signal and control methods\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <button (click)=\"worker.post(42)\">Calculate</button>\n * @if (worker.data()) {\n * <p>Result: {{ worker.data() }}</p>\n * }\n * `\n * })\n * class WorkerComponent {\n * readonly worker = webWorker<number, number>('/workers/calc.js');\n * }\n * ```\n */\nexport function webWorker<I, O>(\n url: MaybeSignal<string | URL>,\n options?: WebWorkerOptions\n): WebWorkerRef<I, O> {\n const { runInContext } = setupContext(options?.injector, webWorker);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return {\n data: constSignal(undefined),\n isReady: constSignal(false),\n error: constSignal(null),\n post: NOOP_FN,\n terminate: NOOP_FN,\n };\n }\n\n const type = options?.type ?? 'classic';\n const credentials = options?.credentials;\n const name = options?.name;\n\n const data = signal<O | undefined>(undefined);\n const isReady = signal(false);\n const error = signal<Error | null>(null);\n\n let worker: Worker | null = null;\n\n const createWorker = (workerUrl: string | URL) => {\n if (worker) {\n worker.terminate();\n }\n\n try {\n worker = new Worker(workerUrl, { type, credentials, name });\n\n worker.onmessage = (event: MessageEvent<O>) => {\n data.set(event.data);\n };\n\n worker.onerror = (event: ErrorEvent) => {\n error.set(new Error(event.message));\n };\n\n worker.onmessageerror = () => {\n error.set(new Error('Message deserialization error'));\n };\n\n isReady.set(true);\n } catch (e) {\n error.set(e as Error);\n isReady.set(false);\n }\n };\n\n const post = (message: I) => {\n if (worker && untracked(isReady)) {\n try {\n worker.postMessage(message);\n } catch (e) {\n error.set(e as Error);\n }\n }\n };\n\n const terminate = () => {\n if (worker) {\n worker.terminate();\n worker = null;\n isReady.set(false);\n }\n };\n\n if (isSignal(url)) {\n watcher(url, createWorker);\n }\n\n onCleanup(terminate);\n\n createWorker(toValue(url));\n\n return {\n data: data.asReadonly(),\n isReady: isReady.asReadonly(),\n error: error.asReadonly(),\n post,\n terminate,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export * from '@signality/core/browser/battery';
|
|
2
|
+
export * from '@signality/core/browser/bluetooth';
|
|
3
|
+
export * from '@signality/core/browser/breakpoints';
|
|
4
|
+
export * from '@signality/core/browser/broadcast-channel';
|
|
5
|
+
export * from '@signality/core/browser/browser-language';
|
|
6
|
+
export * from '@signality/core/browser/clipboard';
|
|
7
|
+
export * from '@signality/core/browser/device-posture';
|
|
8
|
+
export * from '@signality/core/browser/display-media';
|
|
9
|
+
export * from '@signality/core/browser/eye-dropper';
|
|
10
|
+
export * from '@signality/core/browser/favicon';
|
|
11
|
+
export * from '@signality/core/browser/fps';
|
|
12
|
+
export * from '@signality/core/browser/gamepad';
|
|
13
|
+
export * from '@signality/core/browser/geolocation';
|
|
14
|
+
export * from '@signality/core/browser/input-modality';
|
|
15
|
+
export * from '@signality/core/browser/listener';
|
|
16
|
+
export * from '@signality/core/browser/media-query';
|
|
17
|
+
export * from '@signality/core/browser/network';
|
|
18
|
+
export * from '@signality/core/browser/online';
|
|
19
|
+
export * from '@signality/core/browser/page-visibility';
|
|
20
|
+
export * from '@signality/core/browser/picture-in-picture';
|
|
21
|
+
export * from '@signality/core/browser/web-share';
|
|
22
|
+
export * from '@signality/core/browser/speech-recognition';
|
|
23
|
+
export * from '@signality/core/browser/speech-synthesis';
|
|
24
|
+
export * from '@signality/core/browser/storage';
|
|
25
|
+
export * from '@signality/core/browser/text-direction';
|
|
26
|
+
export * from '@signality/core/browser/vibration';
|
|
27
|
+
export * from '@signality/core/browser/wake-lock';
|
|
28
|
+
export * from '@signality/core/browser/web-notification';
|
|
29
|
+
export * from '@signality/core/browser/web-worker';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Generated bundle index. Do not edit.
|
|
33
|
+
*/
|
|
34
|
+
//# sourceMappingURL=signality-core-browser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signality-core-browser.mjs","sources":["../../../projects/core/browser/signality-core-browser.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AAEG"}
|