@wcstack/notification 1.13.1

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.
@@ -0,0 +1,333 @@
1
+ interface ITagNames {
2
+ readonly notify: string;
3
+ }
4
+ interface IWritableTagNames {
5
+ notify?: string;
6
+ }
7
+ interface IConfig {
8
+ readonly tagNames: ITagNames;
9
+ readonly autoTrigger: boolean;
10
+ readonly triggerAttribute: string;
11
+ }
12
+ interface IWritableConfig {
13
+ tagNames?: IWritableTagNames;
14
+ autoTrigger?: boolean;
15
+ triggerAttribute?: string;
16
+ }
17
+ interface IWcBindableProperty {
18
+ readonly name: string;
19
+ readonly event: string;
20
+ readonly getter?: (event: Event) => any;
21
+ }
22
+ interface IWcBindableInput {
23
+ readonly name: string;
24
+ readonly attribute?: string;
25
+ }
26
+ interface IWcBindableCommand {
27
+ readonly name: string;
28
+ readonly async?: boolean;
29
+ }
30
+ interface IWcBindable {
31
+ readonly protocol: "wc-bindable";
32
+ readonly version: number;
33
+ readonly properties: IWcBindableProperty[];
34
+ readonly inputs?: IWcBindableInput[];
35
+ readonly commands?: IWcBindableCommand[];
36
+ }
37
+ /**
38
+ * Permission state mirroring the Permissions API `PermissionState`
39
+ * (`"prompt"` / `"granted"` / `"denied"`) plus `"unsupported"` for environments
40
+ * without the Notifications API. The Notifications API's own value `"default"` is
41
+ * normalized to `"prompt"` so this node shares the exact four-value surface used by
42
+ * `@wcstack/permission` / `@wcstack/geolocation` / `@wcstack/clipboard` — a binding
43
+ * like `hidden@granted` works the same across all of them.
44
+ */
45
+ type PermissionStateOrUnsupported = "prompt" | "granted" | "denied" | "unsupported";
46
+ /** Raw value returned by `Notification.permission` / `Notification.requestPermission()`. */
47
+ type NotificationPermissionRaw = "default" | "granted" | "denied";
48
+ /**
49
+ * Which API actually shows the notification.
50
+ * - `"constructor"` — `new Notification(title, options)` (desktop only).
51
+ * - `"sw"` — `ServiceWorkerRegistration.showNotification()` (required on mobile/Android Chrome).
52
+ * - `"auto"` — pick SW when a registration is ready and `new Notification` is unusable,
53
+ * otherwise the constructor; fall back to SW if the constructor throws `TypeError`.
54
+ */
55
+ type NotifyBackend = "auto" | "sw" | "constructor";
56
+ /**
57
+ * Per-notification options forwarded to `new Notification(title, options)` or
58
+ * `registration.showNotification(title, options)`. Mirrors the standard
59
+ * `NotificationOptions`; `data` is round-tripped back to the click event payload.
60
+ */
61
+ interface NotifyOptions {
62
+ body?: string;
63
+ icon?: string;
64
+ badge?: string;
65
+ image?: string;
66
+ tag?: string;
67
+ data?: unknown;
68
+ lang?: string;
69
+ dir?: "auto" | "ltr" | "rtl";
70
+ requireInteraction?: boolean;
71
+ silent?: boolean;
72
+ renotify?: boolean;
73
+ }
74
+ /** Detail of the `wcs-notify:error` event. */
75
+ interface WcsNotifyErrorDetail {
76
+ error: string;
77
+ message: string;
78
+ }
79
+ /**
80
+ * Detail of the `wcs-notify:click` / `:close` / `:show` events. `tag` identifies
81
+ * the notification (a caller-supplied `options.tag`, or a Core-assigned `wcs-<n>`
82
+ * id when omitted). `data` is whatever was passed in `options.data`. `action` is
83
+ * the Service Worker action-button id (always `""` for the constructor backend).
84
+ */
85
+ interface WcsNotifyClickDetail {
86
+ tag: string;
87
+ data: unknown;
88
+ action: string;
89
+ }
90
+ /** Message posted from the Service Worker helper (`wireNotificationClicks`) to the page. */
91
+ interface WcsNotifySwMessage {
92
+ __wcsNotify: true;
93
+ id: string;
94
+ tag: string;
95
+ data: unknown;
96
+ action: string;
97
+ }
98
+ /**
99
+ * Value types for NotificationCore (headless) — the observable state properties.
100
+ * Use with `bind()` from `@wc-bindable/core` for compile-time type checking.
101
+ */
102
+ interface WcsNotifyCoreValues {
103
+ permission: PermissionStateOrUnsupported;
104
+ granted: boolean;
105
+ denied: boolean;
106
+ prompt: boolean;
107
+ unsupported: boolean;
108
+ error: WcsNotifyErrorDetail | null;
109
+ clicked: WcsNotifyClickDetail | null;
110
+ closed: WcsNotifyClickDetail | null;
111
+ shown: WcsNotifyClickDetail | null;
112
+ }
113
+ /** Command surface for NotificationCore (headless). */
114
+ interface WcsNotifyCoreCommands {
115
+ request(): Promise<PermissionStateOrUnsupported>;
116
+ notify(title: string, options?: NotifyOptions): string;
117
+ close(tag?: string): void;
118
+ closeAll(): void;
119
+ }
120
+ /** Value types for the Shell (`<wcs-notify>`) — identical observable surface to the Core. */
121
+ type WcsNotifyValues = WcsNotifyCoreValues;
122
+ /** Command surface for the Shell (`<wcs-notify>`) — identical to the Core. */
123
+ type WcsNotifyCommands = WcsNotifyCoreCommands;
124
+ /**
125
+ * Settable input surface for the Shell (`<wcs-notify>`). `notice` is the reactive
126
+ * command-property (writing a *changed* value shows a notification); the rest are
127
+ * declarative options mirrored as HTML attributes.
128
+ */
129
+ interface WcsNotifyInputs {
130
+ notice: string;
131
+ mode: NotifyBackend;
132
+ body: string;
133
+ icon: string;
134
+ badge: string;
135
+ tag: string;
136
+ lang: string;
137
+ dir: string;
138
+ requireInteraction: boolean;
139
+ silent: boolean;
140
+ renotify: boolean;
141
+ manual: boolean;
142
+ }
143
+
144
+ declare function bootstrapNotification(userConfig?: IWritableConfig): void;
145
+
146
+ declare function getConfig(): IConfig;
147
+
148
+ /**
149
+ * Headless desktop-notification primitive. A thin, framework-agnostic wrapper
150
+ * around the Notifications API exposed through the wc-bindable protocol.
151
+ *
152
+ * Unlike `@wcstack/permission` (a read-only monitor — the Permissions API has no
153
+ * `request()`), the Notifications API *does* expose `Notification.requestPermission()`,
154
+ * so this node is self-contained: it both **requests/monitors** the permission and
155
+ * **shows** notifications. It is the first @wcstack node where the command-token
156
+ * (show: `notify`) and event-token (`click` / `close` / `show`) directions both
157
+ * live in one tag.
158
+ *
159
+ * - **request()** asks for the `notifications` permission (`Notification.requestPermission`).
160
+ * - **notify(title, options)** shows a notification and returns its identifying tag
161
+ * (a caller `options.tag`, or a generated `wcs-<n>`). It picks a backend per
162
+ * `mode`: the `Notification` constructor (desktop) or
163
+ * `ServiceWorkerRegistration.showNotification()` (mobile). `"auto"` prefers the
164
+ * constructor and falls back to the SW on a `TypeError`.
165
+ * - **close(tag) / closeAll()** dismiss notifications by tag / all.
166
+ * - Clicks flow back as the `wcs-notify:click` event: directly via the
167
+ * Notification's `onclick` (constructor), or via the SW helper's
168
+ * BroadcastChannel/postMessage relay (SW). `permission` mirrors the live grant.
169
+ *
170
+ * Failures never throw: they surface through `error` (and the `unsupported`
171
+ * permission state) so they flow into the declarative state.
172
+ */
173
+ declare class NotificationCore extends EventTarget {
174
+ static wcBindable: IWcBindable;
175
+ private _target;
176
+ private _mode;
177
+ private _permission;
178
+ private _error;
179
+ private _lastClick;
180
+ private _lastClose;
181
+ private _lastShow;
182
+ private _permissionStatus;
183
+ private _permissionSubscribed;
184
+ private _gen;
185
+ private _ready;
186
+ private _idSeq;
187
+ private _constructed;
188
+ private _swTags;
189
+ private _channel;
190
+ private _serviceWorker;
191
+ private _clicksSubscribed;
192
+ private _seenIds;
193
+ constructor(target?: EventTarget);
194
+ get permission(): PermissionStateOrUnsupported;
195
+ get granted(): boolean;
196
+ get denied(): boolean;
197
+ get prompt(): boolean;
198
+ get unsupported(): boolean;
199
+ get error(): WcsNotifyErrorDetail | null;
200
+ get clicked(): WcsNotifyClickDetail | null;
201
+ get closed(): WcsNotifyClickDetail | null;
202
+ get shown(): WcsNotifyClickDetail | null;
203
+ /** Resolves once the current (or initial) permission probe settles. */
204
+ get ready(): Promise<void>;
205
+ private _setPermission;
206
+ private _setError;
207
+ private _emit;
208
+ /**
209
+ * Start observing the `notifications` permission and subscribing to Service
210
+ * Worker click relays. `mode` selects the show backend (default `"auto"`).
211
+ * Idempotent while already subscribed: it only updates the stored mode; to
212
+ * restart, dispose() first. Returns a promise that resolves once the first
213
+ * permission probe settles, for SSR.
214
+ *
215
+ * Headless callers must call observe() to begin; the Shell calls it from
216
+ * connectedCallback once the element's attributes resolve.
217
+ */
218
+ observe(mode?: NotifyBackend): Promise<void>;
219
+ /**
220
+ * Ask the user for the `notifications` permission. Resolves to the resulting
221
+ * (normalized) permission state. Never throws: an unavailable API resolves to
222
+ * `"unsupported"`.
223
+ */
224
+ request(): Promise<PermissionStateOrUnsupported>;
225
+ /**
226
+ * Show a notification. Returns the identifying tag (the caller's `options.tag`,
227
+ * or a generated `wcs-<n>` when omitted). Never throws: when the API is
228
+ * unavailable or the permission is not granted it surfaces an `error` and
229
+ * returns an empty string.
230
+ */
231
+ notify(title: string, options?: NotifyOptions): string;
232
+ /** Dismiss the notification(s) with `tag` across both backends. */
233
+ close(tag?: string): void;
234
+ /**
235
+ * Dismiss every notification this instance has shown. Scoped to this instance's
236
+ * own tags on both backends — the SW path closes each tracked tag individually
237
+ * rather than enumerating the whole origin, so it never dismisses notifications
238
+ * shown by another `<wcs-notify>` or by an unrelated code path.
239
+ */
240
+ closeAll(): void;
241
+ /**
242
+ * Detach permission and click subscriptions. Open notifications are intentionally
243
+ * **left on screen** (a notification outlives the page that posted it — that is
244
+ * the point); use close()/closeAll() to dismiss. Call from the Shell's
245
+ * disconnectedCallback. A later observe() resumes.
246
+ */
247
+ dispose(): void;
248
+ private _initPermission;
249
+ private _onPermissionChange;
250
+ private _normalize;
251
+ private _show;
252
+ private _showViaConstructor;
253
+ private _showViaSw;
254
+ private _closeSw;
255
+ private _subscribeClicks;
256
+ private _onInbound;
257
+ private _isDuplicate;
258
+ private _unwrap;
259
+ private _api;
260
+ private _nextId;
261
+ private _err;
262
+ }
263
+
264
+ /**
265
+ * `<wcs-notify>` — declarative desktop notifications. Wraps NotificationCore and
266
+ * exposes both directions in one tag:
267
+ *
268
+ * - **`notice`** (reactive input): writing a *changed* value shows a notification,
269
+ * suppressing same-value writes so it fires only when the bound source actually
270
+ * changes. The imperative `notify` command instead shows on demand (even the
271
+ * same text again). See `docs/notification-tag-design.md` § 2.
272
+ * - **`request` / `notify` / `close` / `closeAll`** commands (state → element).
273
+ * - per-notification options (`body` / `icon` / `badge` / `tag` / `lang` / `dir` /
274
+ * `require-interaction` / `silent` / `renotify`) as mirrored attributes.
275
+ * - `mode` selects the show backend (`auto` / `sw` / `constructor`).
276
+ * - the Core's observable surface (permission / granted / … / error / clicked /
277
+ * closed / shown) via delegated getters; clicked/closed/shown carry the
278
+ * `{ tag, data, action }` payload for event-token wiring.
279
+ */
280
+ declare class WcsNotify extends HTMLElement {
281
+ static hasConnectedCallbackPromise: boolean;
282
+ static wcBindable: IWcBindable;
283
+ private _core;
284
+ private _notice;
285
+ private _connectedCallbackPromise;
286
+ constructor();
287
+ get mode(): NotifyBackend;
288
+ set mode(value: NotifyBackend);
289
+ get body(): string;
290
+ set body(value: string | null);
291
+ get icon(): string;
292
+ set icon(value: string | null);
293
+ get badge(): string;
294
+ set badge(value: string | null);
295
+ get tag(): string;
296
+ set tag(value: string | null);
297
+ get lang(): string;
298
+ set lang(value: string | null);
299
+ get dir(): string;
300
+ set dir(value: string | null);
301
+ get requireInteraction(): boolean;
302
+ set requireInteraction(value: boolean);
303
+ get silent(): boolean;
304
+ set silent(value: boolean);
305
+ get renotify(): boolean;
306
+ set renotify(value: boolean);
307
+ get manual(): boolean;
308
+ set manual(value: boolean);
309
+ get notice(): string;
310
+ set notice(value: string | null);
311
+ get permission(): PermissionStateOrUnsupported;
312
+ get granted(): boolean;
313
+ get denied(): boolean;
314
+ get prompt(): boolean;
315
+ get unsupported(): boolean;
316
+ get error(): WcsNotifyErrorDetail | null;
317
+ get clicked(): WcsNotifyClickDetail | null;
318
+ get closed(): WcsNotifyClickDetail | null;
319
+ get shown(): WcsNotifyClickDetail | null;
320
+ get connectedCallbackPromise(): Promise<void>;
321
+ request(): Promise<PermissionStateOrUnsupported>;
322
+ notify(title: string, options?: NotifyOptions): string;
323
+ close(tag?: string): void;
324
+ closeAll(): void;
325
+ private _reflect;
326
+ private _reflectBool;
327
+ private _options;
328
+ connectedCallback(): void;
329
+ disconnectedCallback(): void;
330
+ }
331
+
332
+ export { NotificationCore, WcsNotify, bootstrapNotification, getConfig };
333
+ export type { IWritableConfig, IWritableTagNames, NotificationPermissionRaw, NotifyBackend, NotifyOptions, PermissionStateOrUnsupported, WcsNotifyClickDetail, WcsNotifyCommands, WcsNotifyCoreCommands, WcsNotifyCoreValues, WcsNotifyErrorDetail, WcsNotifyInputs, WcsNotifySwMessage, WcsNotifyValues };