@12-apps/notifications 4.4.0 → 4.6.0
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/dist/chunk-WU6QJLSZ.js +94 -0
- package/dist/chunk-WU6QJLSZ.js.map +1 -0
- package/dist/chunk-YE24MDS6.js +1022 -0
- package/dist/chunk-YE24MDS6.js.map +1 -0
- package/dist/create-api-notifications-CgBdjfyF.d.ts +909 -0
- package/dist/create-web-notifications-Du3hTs7P.d.ts +354 -0
- package/dist/{generators-FATT537X.d.ts → generators-B9xt3sRh.d.ts} +1 -1
- package/dist/hono/index.d.ts +5 -5
- package/dist/index.d.ts +3 -3
- package/dist/jobs-DhDjrAX5.d.ts +74 -0
- package/dist/manifest/index.d.ts +20 -6
- package/dist/manifest/index.js +2 -1
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/server.d.ts +22 -30
- package/dist/manifest/server.js +11 -2
- package/dist/manifest/server.js.map +1 -1
- package/dist/manifest/web.d.ts +51 -0
- package/dist/manifest/web.js +15 -0
- package/dist/manifest/web.js.map +1 -0
- package/dist/react/index.d.ts +6 -353
- package/dist/react/index.js +20 -1008
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.d.ts +79 -902
- package/dist/server/index.js +13 -2
- package/dist/{types-yq_o4N01.d.ts → types-CXLAG3UU.d.ts} +1 -1
- package/dist/web-push/index.d.ts +2 -2
- package/dist/{web-push-KLY6UMRT.d.ts → web-push-Cs14Wp9u.d.ts} +2 -2
- package/dist/{wire-SDUtscGu.d.ts → wire-5IRin4zH.d.ts} +1 -1
- package/package.json +13 -5
- package/src/manifest/index.ts +20 -6
- package/src/manifest/server.ts +8 -0
- package/src/manifest/web.ts +46 -0
- package/src/server/index.ts +20 -0
- package/src/server/jobs.ts +118 -0
- package/src/server/wire-notify-port.ts +125 -0
- package/dist/chunk-F5ANWJCY.js +0 -1
- package/dist/chunk-F5ANWJCY.js.map +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { c as createWebNotifications } from '../create-web-notifications-Du3hTs7P.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '../wire-5IRin4zH.js';
|
|
4
|
+
import '../types-CXLAG3UU.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `@12-apps/notifications/manifest/web` — the web capabilities.
|
|
8
|
+
*
|
|
9
|
+
* `surface.create` IS `createWebNotifications`, unchanged: the bell, the inbox
|
|
10
|
+
* slide-over, the preferences screen and the bound store, built once per
|
|
11
|
+
* adoption by the consumer's binder (the members are component TYPES, so
|
|
12
|
+
* rebuilding per render unmounts the panel mid-interaction — the memoisation
|
|
13
|
+
* rule every hand wiring carries as a comment today).
|
|
14
|
+
*
|
|
15
|
+
* ## Why this manifest exists now
|
|
16
|
+
*
|
|
17
|
+
* It was narrowed away with a reason that reads plausibly and is FALSE:
|
|
18
|
+
* "listing `web` would oblige every server host adopting this manifest to
|
|
19
|
+
* answer for a React surface it never mounts." The consumer does not work
|
|
20
|
+
* that way. A capability declared for the other runtime is reported
|
|
21
|
+
* `out-of-scope` — "a web host answers for this" — and `assemble()` returns
|
|
22
|
+
* fine; only a capability applicable to THIS runtime and unanswered is
|
|
23
|
+
* `unbound`. `wiring`'s own fixture package declares both halves and its
|
|
24
|
+
* server-host suite asserts exactly that.
|
|
25
|
+
*
|
|
26
|
+
* The narrowing therefore bought nothing and cost the thing the capability is
|
|
27
|
+
* for. `./react` and `./web-push` ship Bell, Panel and Preferences — the exact
|
|
28
|
+
* screens the adaptation report wanted to stop being hand-duplicated in hosts,
|
|
29
|
+
* and the origin host duplicated the preferences screen and the push setup
|
|
30
|
+
* anyway, because a manifest that never mentions them is a manifest nobody
|
|
31
|
+
* discovers them from.
|
|
32
|
+
*
|
|
33
|
+
* ## Why there are no `areas`
|
|
34
|
+
*
|
|
35
|
+
* The bell is not a routed screen: it lives in a host's header chrome, beside
|
|
36
|
+
* whatever else that host puts there, and no package can suggest a route for
|
|
37
|
+
* it. Preferences IS routed, but where it belongs differs per host — under
|
|
38
|
+
* account settings in one app, under a tenant's configuration in another — and
|
|
39
|
+
* it is offered as `page` on the surface for the host to route at its own
|
|
40
|
+
* call site. A suggested nav row would be wrong for every host but the first,
|
|
41
|
+
* which is the `AreaContribution` doctrine's own test.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
declare const notificationsWebManifest: {
|
|
45
|
+
readonly name: "@12-apps/notifications";
|
|
46
|
+
readonly surface: {
|
|
47
|
+
readonly create: typeof createWebNotifications;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { notificationsWebManifest };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createWebNotifications
|
|
3
|
+
} from "../chunk-YE24MDS6.js";
|
|
4
|
+
import "../chunk-4TTYQVPK.js";
|
|
5
|
+
import "../chunk-7QVYU63E.js";
|
|
6
|
+
|
|
7
|
+
// src/manifest/web.ts
|
|
8
|
+
var notificationsWebManifest = {
|
|
9
|
+
name: "@12-apps/notifications",
|
|
10
|
+
surface: { create: createWebNotifications }
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
notificationsWebManifest
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/manifest/web.ts"],"sourcesContent":["/**\n * `@12-apps/notifications/manifest/web` — the web capabilities.\n *\n * `surface.create` IS `createWebNotifications`, unchanged: the bell, the inbox\n * slide-over, the preferences screen and the bound store, built once per\n * adoption by the consumer's binder (the members are component TYPES, so\n * rebuilding per render unmounts the panel mid-interaction — the memoisation\n * rule every hand wiring carries as a comment today).\n *\n * ## Why this manifest exists now\n *\n * It was narrowed away with a reason that reads plausibly and is FALSE:\n * \"listing `web` would oblige every server host adopting this manifest to\n * answer for a React surface it never mounts.\" The consumer does not work\n * that way. A capability declared for the other runtime is reported\n * `out-of-scope` — \"a web host answers for this\" — and `assemble()` returns\n * fine; only a capability applicable to THIS runtime and unanswered is\n * `unbound`. `wiring`'s own fixture package declares both halves and its\n * server-host suite asserts exactly that.\n *\n * The narrowing therefore bought nothing and cost the thing the capability is\n * for. `./react` and `./web-push` ship Bell, Panel and Preferences — the exact\n * screens the adaptation report wanted to stop being hand-duplicated in hosts,\n * and the origin host duplicated the preferences screen and the push setup\n * anyway, because a manifest that never mentions them is a manifest nobody\n * discovers them from.\n *\n * ## Why there are no `areas`\n *\n * The bell is not a routed screen: it lives in a host's header chrome, beside\n * whatever else that host puts there, and no package can suggest a route for\n * it. Preferences IS routed, but where it belongs differs per host — under\n * account settings in one app, under a tenant's configuration in another — and\n * it is offered as `page` on the surface for the host to route at its own\n * call site. A suggested nav row would be wrong for every host but the first,\n * which is the `AreaContribution` doctrine's own test.\n */\n\nimport type { AnyWebManifest } from '@12-apps/wiring';\n\nimport { createWebNotifications } from '../react/create-web-notifications';\n\nexport const notificationsWebManifest = {\n name: '@12-apps/notifications',\n surface: { create: createWebNotifications },\n} as const satisfies AnyWebManifest;\n"],"mappings":";;;;;;;AA0CO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,SAAS,EAAE,QAAQ,uBAAuB;AAC5C;","names":[]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,355 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* How the notification screens reach their data (12-15) — the report-builder
|
|
7
|
-
* transport doctrine: this is the ONLY way the surface performs I/O, so a
|
|
8
|
-
* caller supplying one has substituted the entire backend without stubbing a
|
|
9
|
-
* global. The default is same-origin `fetch` riding the browser's cookies.
|
|
10
|
-
*/
|
|
11
|
-
/** A write outcome the screens branch on — never a thrown mutation. */
|
|
12
|
-
type NotificationsResult<T> = {
|
|
13
|
-
ok: true;
|
|
14
|
-
data: T;
|
|
15
|
-
} | {
|
|
16
|
-
ok: false;
|
|
17
|
-
error: string;
|
|
18
|
-
};
|
|
19
|
-
/** A failed read, carrying the status the screens branch on (401 = signed out). */
|
|
20
|
-
declare class NotificationsHttpError extends Error {
|
|
21
|
-
readonly status: number;
|
|
22
|
-
constructor(status: number, message: string);
|
|
23
|
-
}
|
|
24
|
-
interface NotificationsTransport {
|
|
25
|
-
/** A read. Returns the payload INSIDE the `{ data }` envelope. */
|
|
26
|
-
get<T>(path: string): Promise<T>;
|
|
27
|
-
/** A write. Returns a {@link NotificationsResult} rather than rejecting. */
|
|
28
|
-
send<T>(path: string, method: string, body?: unknown): Promise<NotificationsResult<T>>;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* @param fallbackError What a failed write says when the server sent no
|
|
32
|
-
* sentence of its own — REQUIRED, the host's words. `createWebNotifications`
|
|
33
|
-
* already passes its (equally required) `messages.operationFailed`; only a
|
|
34
|
-
* host constructing the transport directly writes it here. The old default
|
|
35
|
-
* was one application's Portuguese, and the only string in this package the
|
|
36
|
-
* required-messages port did not cover.
|
|
37
|
-
*/
|
|
38
|
-
declare function httpNotificationsTransport(fallbackError: string): NotificationsTransport;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* The wire client, bound to one mount (12-15).
|
|
42
|
-
*
|
|
43
|
-
* Every path this package's screens can call, in one place — which is what
|
|
44
|
-
* makes the api half's route table and the web half's URLs one contract instead
|
|
45
|
-
* of two lists that drift.
|
|
46
|
-
*/
|
|
47
|
-
/** `GET <mount>/notification-preferences` and the PUT's answer. */
|
|
48
|
-
interface PreferencesPayload {
|
|
49
|
-
preferences: Record<string, ChannelRow>;
|
|
50
|
-
availability: Record<NotificationChannel, boolean>;
|
|
51
|
-
/** The host's taxonomy, so the screen renders it without being told twice. */
|
|
52
|
-
categories: string[];
|
|
53
|
-
}
|
|
54
|
-
/** `GET <mount>/push-subscriptions`. */
|
|
55
|
-
interface PushRegistrationPayload {
|
|
56
|
-
/** null = web push is not configured on this deployment. */
|
|
57
|
-
vapidPublicKey: string | null;
|
|
58
|
-
count: number;
|
|
59
|
-
/**
|
|
60
|
-
* Whether the endpoint asked about is still registered to the caller. Present
|
|
61
|
-
* only when one was passed — see {@link NotificationsApiClient.getPushRegistration}.
|
|
62
|
-
*/
|
|
63
|
-
registered?: boolean;
|
|
64
|
-
}
|
|
65
|
-
interface NotificationsApiClient {
|
|
66
|
-
listNotifications(input: {
|
|
67
|
-
cursor?: string | null;
|
|
68
|
-
limit?: number;
|
|
69
|
-
filter?: 'all' | 'unread';
|
|
70
|
-
}): Promise<ListNotificationsResult>;
|
|
71
|
-
unreadCount(): Promise<number>;
|
|
72
|
-
markRead(ids: readonly string[]): Promise<NotificationsResult<{
|
|
73
|
-
updated: number;
|
|
74
|
-
}>>;
|
|
75
|
-
markAllRead(): Promise<NotificationsResult<{
|
|
76
|
-
updated: number;
|
|
77
|
-
}>>;
|
|
78
|
-
remove(ids: readonly string[]): Promise<NotificationsResult<{
|
|
79
|
-
deleted: number;
|
|
80
|
-
}>>;
|
|
81
|
-
getPreferences(): Promise<PreferencesPayload>;
|
|
82
|
-
savePreference(category: string, channel: NotificationChannel, enabled: boolean): Promise<NotificationsResult<PreferencesPayload>>;
|
|
83
|
-
/**
|
|
84
|
-
* The deployment's VAPID key and the caller's device count — and, when an
|
|
85
|
-
* `endpoint` is passed, whether the SERVER still has that exact subscription
|
|
86
|
-
* under the caller's id. The browser holding a subscription object is not
|
|
87
|
-
* evidence of that: a re-own or a 404/410 prune drops the row and leaves the
|
|
88
|
-
* browser's object in place.
|
|
89
|
-
*/
|
|
90
|
-
getPushRegistration(input?: {
|
|
91
|
-
endpoint?: string;
|
|
92
|
-
}): Promise<PushRegistrationPayload>;
|
|
93
|
-
savePushSubscription(input: {
|
|
94
|
-
endpoint: string;
|
|
95
|
-
keys: {
|
|
96
|
-
p256dh: string;
|
|
97
|
-
auth: string;
|
|
98
|
-
};
|
|
99
|
-
}): Promise<NotificationsResult<{
|
|
100
|
-
count: number;
|
|
101
|
-
}>>;
|
|
102
|
-
removePushSubscription(endpoint: string): Promise<NotificationsResult<{
|
|
103
|
-
count: number;
|
|
104
|
-
}>>;
|
|
105
|
-
}
|
|
106
|
-
declare function createNotificationsApiClient(apiBase: string, transport: NotificationsTransport): NotificationsApiClient;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* The inbox's client state, as ONE store shared by the bell and the panel.
|
|
110
|
-
*
|
|
111
|
-
* They have to share it: marking a row read in the panel must move the badge in
|
|
112
|
-
* the same tick, and an arrival must add a row to the list AND to the count.
|
|
113
|
-
* the origin got that for free from a react-query cache the host had already
|
|
114
|
-
* mounted; a published package cannot assume one — a query client is a host
|
|
115
|
-
* decision, and requiring a particular one (or a particular version of one) is
|
|
116
|
-
* the kind of dependency that keeps a package out of a host that made the other
|
|
117
|
-
* choice. So the sharing is explicit and dependency-free: one subscribable
|
|
118
|
-
* store, read through `useSyncExternalStore`.
|
|
119
|
-
*
|
|
120
|
-
* Optimistic on every write, with invalidate-on-error: the badge and the list
|
|
121
|
-
* update instantly, and a failed write refetches the server truth rather than
|
|
122
|
-
* leaving the screen asserting something the database does not say.
|
|
123
|
-
*/
|
|
124
|
-
declare const PAGE_SIZE = 20;
|
|
125
|
-
/** The badge's poll while nothing is pushing to us. */
|
|
126
|
-
declare const BADGE_POLL_MS = 60000;
|
|
127
|
-
/**
|
|
128
|
-
* The badge's interval while a realtime connection is live.
|
|
129
|
-
*
|
|
130
|
-
* Five minutes, not "never": this is the reconcile that catches an event the bus
|
|
131
|
-
* dropped, and it costs one COUNT per open tab per five minutes. Deliberately
|
|
132
|
-
* far slower than an operational screen's — a bell badge is ambient, and the
|
|
133
|
-
* arrival that matters is pushed within milliseconds anyway. The poll does NOT
|
|
134
|
-
* stop, which is the standing contract: a dropped event must cost latency and
|
|
135
|
-
* never correctness.
|
|
136
|
-
*/
|
|
137
|
-
declare const BADGE_RECONCILE_MS = 300000;
|
|
138
|
-
type InboxListStatus = 'idle' | 'pending' | 'ready' | 'error';
|
|
139
|
-
interface InboxState {
|
|
140
|
-
unread: number;
|
|
141
|
-
items: InboxNotification[];
|
|
142
|
-
status: InboxListStatus;
|
|
143
|
-
/** A cursor means there is another page. */
|
|
144
|
-
nextCursor: string | null;
|
|
145
|
-
loadingMore: boolean;
|
|
146
|
-
}
|
|
147
|
-
interface InboxStore {
|
|
148
|
-
getState(): InboxState;
|
|
149
|
-
subscribe(listener: () => void): () => void;
|
|
150
|
-
/** Load the first page (idempotent while one is in flight). */
|
|
151
|
-
open(): void;
|
|
152
|
-
/** Refetch the badge count. */
|
|
153
|
-
refreshBadge(): void;
|
|
154
|
-
/** Refetch both — what a realtime hint or a failed write triggers. */
|
|
155
|
-
invalidate(): void;
|
|
156
|
-
loadMore(): void;
|
|
157
|
-
markRead(ids: readonly string[]): void;
|
|
158
|
-
markAllRead(): void;
|
|
159
|
-
remove(id: string): void;
|
|
160
|
-
}
|
|
161
|
-
declare function createInboxStore(api: NotificationsApiClient): InboxStore;
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* The two hooks the bell and the panel use, and the realtime seam between them.
|
|
165
|
-
*
|
|
166
|
-
* A host that has a message bus passes `subscribe`; one that has not passes
|
|
167
|
-
* nothing and keeps the 60 s poll. The bell ships in this package and mounts in
|
|
168
|
-
* whatever embeds it, so it must not require the host to have adopted anything.
|
|
169
|
-
*/
|
|
170
|
-
/**
|
|
171
|
-
* How the surface learns an inbox changed without asking.
|
|
172
|
-
*
|
|
173
|
-
* Called once per mounted bell with a callback that means only "ask again" — no
|
|
174
|
-
* payload, so the number on screen is always one the server just gave us.
|
|
175
|
-
* Returns its own teardown. A host wires this to whatever it already has.
|
|
176
|
-
*/
|
|
177
|
-
type NotificationsSubscribe = (onHint: () => void) => () => void;
|
|
178
|
-
/**
|
|
179
|
-
* The same wiring, as a HOOK — for a host whose realtime connection lives in
|
|
180
|
-
* React context rather than in a module.
|
|
181
|
-
*
|
|
182
|
-
* `subscribe` above is supplied at FACTORY time, which is module scope, and a
|
|
183
|
-
* context-bound connection cannot be reached from there: the provider holding
|
|
184
|
-
* it is inside the tree. A host in that shape (a `<UserRealtimeProvider>` and a
|
|
185
|
-
* `useUserTopics` hook, which is the common one) had no way to pass anything at
|
|
186
|
-
* all, and the badge simply never heard an event.
|
|
187
|
-
*
|
|
188
|
-
* So this is the second door, and it is the one `@12-apps/app-shell` already
|
|
189
|
-
* uses for the same problem — its consent dialog takes a `useSignal` hook for
|
|
190
|
-
* exactly this reason. Two packages solving one problem two ways is how an
|
|
191
|
-
* adopter ends up believing the feature is unavailable to it.
|
|
192
|
-
*
|
|
193
|
-
* Called during render, so it may use context and hooks freely. Pass one or
|
|
194
|
-
* the other; passing both runs both, which is a host's business.
|
|
195
|
-
*/
|
|
196
|
-
type NotificationsSignalHook = (onHint: () => void) => void;
|
|
197
|
-
declare function useInboxState(store: InboxStore): InboxState;
|
|
198
|
-
/**
|
|
199
|
-
* The bell badge number: pushed while a subscription is live, polled otherwise.
|
|
200
|
-
*
|
|
201
|
-
* `enabled` gates the poll AND the subscription. A signed-out header still
|
|
202
|
-
* mounts the bell, and there is nothing for it to hear.
|
|
203
|
-
*/
|
|
204
|
-
declare function useUnreadCount(store: InboxStore, options?: {
|
|
205
|
-
enabled?: boolean;
|
|
206
|
-
subscribe?: NotificationsSubscribe;
|
|
207
|
-
useSignal?: NotificationsSignalHook;
|
|
208
|
-
}): number;
|
|
209
|
-
/** The panel's list — only fetches while the panel is open. */
|
|
210
|
-
declare function useInboxList(store: InboxStore, open: boolean): InboxState;
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Bare bell trigger with the live unread badge — for hosts that do not already
|
|
214
|
-
* have a styled icon-button slot. A host with its own trigger chrome uses
|
|
215
|
-
* `useUnreadCount` + `Panel` directly.
|
|
216
|
-
*/
|
|
217
|
-
|
|
218
|
-
interface BellButtonProps {
|
|
219
|
-
onClick: () => void;
|
|
220
|
-
/** Signed-out hosts still mount the bell; `false` silences it. */
|
|
221
|
-
enabled?: boolean;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* The notification-centre slide-over: newest-first list with unread styling,
|
|
226
|
-
* per-item open (marks read + deep-links), soft delete, mark-all, empty /
|
|
227
|
-
* loading / error states and a "load more" cursor pager.
|
|
228
|
-
*
|
|
229
|
-
* Rendering is app-agnostic — the host passes `onNavigate` (its router's
|
|
230
|
-
* navigate) for deep links. Without one a link is simply not followed, which is
|
|
231
|
-
* what lets the panel mount in a host that has no router at all.
|
|
232
|
-
*/
|
|
233
|
-
|
|
234
|
-
interface NotificationsPanelProps {
|
|
235
|
-
open: boolean;
|
|
236
|
-
onClose: () => void;
|
|
237
|
-
/** Navigate to a notification's in-app link (the host's router). */
|
|
238
|
-
onNavigate?: (link: string) => void;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* The per-BROWSER Web Push enable step, which sits above the preference matrix
|
|
243
|
-
* because a preference alone cannot reach a device that never subscribed.
|
|
244
|
-
*/
|
|
245
|
-
|
|
246
|
-
/** The panel's copy for a host whose platform blocks browser-level push. */
|
|
247
|
-
interface WebPushPlatformHint {
|
|
248
|
-
title: string;
|
|
249
|
-
body: string;
|
|
250
|
-
}
|
|
251
|
-
interface WebPushSetupConfig {
|
|
252
|
-
/**
|
|
253
|
-
* The host's service-worker path. Path-routed SPAs each control their own
|
|
254
|
-
* scope, and the file itself is the host's.
|
|
255
|
-
*/
|
|
256
|
-
swPath?: string;
|
|
257
|
-
/**
|
|
258
|
-
* Whether THIS platform must be installed to the home screen before a
|
|
259
|
-
* subscription can exist at all.
|
|
260
|
-
*
|
|
261
|
-
* iOS is the case: Safari has no browser-level Web Push, so "Ativar" there
|
|
262
|
-
* asks no permission, creates no subscription, and fails with nothing a user
|
|
263
|
-
* could act on. The check is a config seam rather than a dependency because
|
|
264
|
-
* "is this an installable iOS browser" is a question a host's PWA layer
|
|
265
|
-
* already answers (the origin passes
|
|
266
|
-
* `() => isIosInstallable() && !isStandalone()` from `@12-apps/pwa`).
|
|
267
|
-
*/
|
|
268
|
-
needsInstallFirst?: () => boolean;
|
|
269
|
-
/** What to say instead of the button when the check above is true. */
|
|
270
|
-
installHint?: WebPushPlatformHint;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* The notification-preferences screen: the category × channel matrix over
|
|
275
|
-
* `GET/PUT <mount>/notification-preferences`.
|
|
276
|
-
*
|
|
277
|
-
* Toggles auto-save (optimistic, per change); channels that cannot reach the
|
|
278
|
-
* user right now (no phone on file / channel not declared) render disabled with
|
|
279
|
-
* a hint. Web Push additionally carries the per-BROWSER enable step, since a
|
|
280
|
-
* preference alone cannot reach a device that never subscribed.
|
|
281
|
-
*/
|
|
282
|
-
|
|
283
|
-
interface PreferencesScreenProps {
|
|
284
|
-
/** Rendered under the lead paragraph — a "back to account" link, typically. */
|
|
285
|
-
footer?: JSX.Element;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* The one thing this package exposes to a FRONTEND host (12-15).
|
|
290
|
-
*
|
|
291
|
-
* Everything the notification centre IS — the bell with its live badge, the
|
|
292
|
-
* slide-over inbox with its optimistic mark-read / delete / mark-all and its
|
|
293
|
-
* cursor pager, the preferences matrix with its availability hints and the
|
|
294
|
-
* per-browser push enable step, and every wire call between them — lives inside
|
|
295
|
-
* this package. The host names where the API is mounted, and that is the whole
|
|
296
|
-
* wiring.
|
|
297
|
-
*
|
|
298
|
-
* `page` is the standalone surface (the preferences screen), which is the one
|
|
299
|
-
* thing a host routes to. The bell and the panel are a PAIR a host drops into
|
|
300
|
-
* its own chrome, and they share one store, so a read in the panel moves the
|
|
301
|
-
* badge in the same tick.
|
|
302
|
-
*/
|
|
303
|
-
interface NotificationsWebConfig {
|
|
304
|
-
/** The account mount the routes live under, e.g. `/api/account`. */
|
|
305
|
-
apiBase: string;
|
|
306
|
-
/** How the surface reaches its data. Default: same-origin fetch. */
|
|
307
|
-
transport?: NotificationsTransport;
|
|
308
|
-
/** User-facing copy overrides (pt-BR product copy by default). */
|
|
309
|
-
messages: NotificationMessages;
|
|
310
|
-
/**
|
|
311
|
-
* How the surface learns an inbox changed without asking — the host's message
|
|
312
|
-
* bus. Without it the badge keeps its 60 s poll, which is the standing
|
|
313
|
-
* contract rather than a fallback: a dropped event must cost latency, never
|
|
314
|
-
* correctness.
|
|
315
|
-
*/
|
|
316
|
-
subscribe?: NotificationsSubscribe;
|
|
317
|
-
/**
|
|
318
|
-
* The same wiring as a HOOK, for a host whose realtime connection lives in
|
|
319
|
-
* React context — see `NotificationsSignalHook`. `subscribe` is read at
|
|
320
|
-
* factory time, which such a host cannot reach.
|
|
321
|
-
*/
|
|
322
|
-
useSignal?: NotificationsSignalHook;
|
|
323
|
-
/** The browser push enable step's host seams (SW path, platform hint). */
|
|
324
|
-
webPush?: WebPushSetupConfig;
|
|
325
|
-
}
|
|
326
|
-
interface WebNotifications {
|
|
327
|
-
/** The routed surface: the preferences screen. */
|
|
328
|
-
page: ComponentType<PreferencesScreenProps>;
|
|
329
|
-
/** The bell, already bound to the shared store. */
|
|
330
|
-
BellButton: ComponentType<BellButtonProps>;
|
|
331
|
-
/** The inbox slide-over, sharing that store. */
|
|
332
|
-
Panel: ComponentType<NotificationsPanelProps>;
|
|
333
|
-
/**
|
|
334
|
-
* Bell + panel as ONE element, for a host that just wants the feature in its
|
|
335
|
-
* header and does not want to own the open/closed state.
|
|
336
|
-
*/
|
|
337
|
-
BellWithPanel: ComponentType<{
|
|
338
|
-
enabled?: boolean;
|
|
339
|
-
onNavigate?: (link: string) => void;
|
|
340
|
-
}>;
|
|
341
|
-
/** The badge number, for a host with its own trigger chrome. */
|
|
342
|
-
useUnreadCount: (options?: {
|
|
343
|
-
enabled?: boolean;
|
|
344
|
-
}) => number;
|
|
345
|
-
/** The shared client state, for host glue. */
|
|
346
|
-
store: InboxStore;
|
|
347
|
-
/** The bound wire client. */
|
|
348
|
-
api: NotificationsApiClient;
|
|
349
|
-
/** The copy in force, so a host's own chrome can reuse a sentence. */
|
|
350
|
-
messages: NotificationMessages;
|
|
351
|
-
}
|
|
352
|
-
declare function createWebNotifications(config: NotificationsWebConfig): WebNotifications;
|
|
1
|
+
import { N as NotificationsApiClient } from '../create-web-notifications-Du3hTs7P.js';
|
|
2
|
+
export { B as BADGE_POLL_MS, a as BADGE_RECONCILE_MS, b as BellButtonProps, I as InboxListStatus, d as InboxState, e as InboxStore, f as NotificationsHttpError, g as NotificationsPanelProps, h as NotificationsResult, i as NotificationsSignalHook, j as NotificationsSubscribe, k as NotificationsTransport, l as NotificationsWebConfig, P as PAGE_SIZE, m as PreferencesPayload, n as PreferencesScreenProps, o as PushRegistrationPayload, W as WebNotifications, p as WebPushPlatformHint, q as WebPushSetupConfig, r as createInboxStore, s as createNotificationsApiClient, c as createWebNotifications, t as httpNotificationsTransport, u as useInboxList, v as useInboxState, w as useUnreadCount } from '../create-web-notifications-Du3hTs7P.js';
|
|
3
|
+
import { JSX } from 'react';
|
|
4
|
+
import { N as NotificationMessages } from '../wire-5IRin4zH.js';
|
|
5
|
+
import '../types-CXLAG3UU.js';
|
|
353
6
|
|
|
354
7
|
/** Inline SVG bell (no icon-library dependency in this package). */
|
|
355
8
|
|
|
@@ -391,4 +44,4 @@ declare function enableWebPush(api: NotificationsApiClient, swPath?: string): Pr
|
|
|
391
44
|
/** Disable flow: unsubscribe the browser and drop the server-side row. */
|
|
392
45
|
declare function disableWebPush(api: NotificationsApiClient): Promise<void>;
|
|
393
46
|
|
|
394
|
-
export {
|
|
47
|
+
export { BellIcon, NotificationsApiClient, type PushSetupResult, disableWebPush, enableWebPush, getExistingPushSubscription, pushSupported, relativeTime };
|