@arkstack/realtime 0.19.0 → 0.19.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.
@@ -70,7 +70,7 @@ interface RealtimeTransport {
70
70
  /**
71
71
  * This device's push registration token, when the transport can issue one.
72
72
  */
73
- deviceToken?(): Promise<string | null>;
73
+ deviceToken?(options?: DeviceTokenOptions): Promise<string | null>;
74
74
  /**
75
75
  * Set by transports that push nothing; clients should poll this often instead.
76
76
  */
@@ -117,6 +117,15 @@ interface FirebaseClientConfig {
117
117
  /** Web push VAPID key used when requesting a messaging token. */
118
118
  vapidKey?: string;
119
119
  }
120
+ interface DeviceTokenOptions {
121
+ /**
122
+ * The service worker that receives background messages: a registration, or
123
+ * the URL of a script to register. A registered URL receives the Firebase
124
+ * web config as its `firebaseConfig` query parameter. Defaults to Firebase's
125
+ * own `/firebase-messaging-sw.js` lookup.
126
+ */
127
+ serviceWorker?: ServiceWorkerRegistration | string;
128
+ }
120
129
  interface FirebaseDatabaseClientConfig {
121
130
  apiKey: string;
122
131
  projectId: string;
@@ -241,15 +250,18 @@ declare class RealtimeClient {
241
250
  onPoll(handler: () => void, interval?: number): Promise<() => void>;
242
251
  /**
243
252
  * This device's push registration token, for registering with your API.
244
- * Null when the transport cannot issue one.
253
+ * Uses the transport when it can issue one, otherwise the `firebase` config
254
+ * (push over FCM while streaming over another transport). Null when neither
255
+ * can, or the browser cannot receive web push.
245
256
  *
257
+ * @param options
246
258
  * @returns
247
259
  */
248
- deviceToken(): Promise<string | null>;
260
+ deviceToken(options?: DeviceTokenOptions): Promise<string | null>;
249
261
  /** Tear down the underlying transport connection. */
250
262
  disconnect(): Promise<void>;
251
263
  }
252
264
  /** Create a new {@link RealtimeClient}. */
253
265
  declare const createRealtime: (config?: RealtimeConfig) => RealtimeClient;
254
266
  //#endregion
255
- export { NotificationHandler as a, RealtimeConfig as c, RealtimeSubscription as d, RealtimeTransport as f, FirebaseDatabaseClientConfig as i, RealtimeEventHandler as l, createRealtime as n, PollingClientConfig as o, RealtimeTransportName as p, FirebaseClientConfig as r, PusherClientConfig as s, RealtimeClient as t, RealtimeNotification as u };
267
+ export { FirebaseDatabaseClientConfig as a, PusherClientConfig as c, RealtimeNotification as d, RealtimeSubscription as f, FirebaseClientConfig as i, RealtimeConfig as l, RealtimeTransportName as m, createRealtime as n, NotificationHandler as o, RealtimeTransport as p, DeviceTokenOptions as r, PollingClientConfig as s, RealtimeClient as t, RealtimeEventHandler as u };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as NotificationHandler, c as RealtimeConfig, d as RealtimeSubscription, f as RealtimeTransport, i as FirebaseDatabaseClientConfig, l as RealtimeEventHandler, n as createRealtime, o as PollingClientConfig, p as RealtimeTransportName, r as FirebaseClientConfig, s as PusherClientConfig, t as RealtimeClient, u as RealtimeNotification } from "./RealtimeClient-MI224djP.js";
1
+ import { a as FirebaseDatabaseClientConfig, c as PusherClientConfig, d as RealtimeNotification, f as RealtimeSubscription, i as FirebaseClientConfig, l as RealtimeConfig, m as RealtimeTransportName, n as createRealtime, o as NotificationHandler, p as RealtimeTransport, r as DeviceTokenOptions, s as PollingClientConfig, t as RealtimeClient, u as RealtimeEventHandler } from "./RealtimeClient-CAoMUUkc.js";
2
2
  //#region src/transports/pusher.d.ts
3
3
  /**
4
4
  * Realtime transport backed by [pusher-js](https://github.com/pusher/pusher-js).
@@ -87,4 +87,15 @@ declare const createMemoryTransport: () => RealtimeTransport;
87
87
  */
88
88
  declare const supersede: (list: RealtimeNotification[], incoming: RealtimeNotification, limit?: number) => RealtimeNotification[];
89
89
  //#endregion
90
- export { type FirebaseClientConfig, type FirebaseDatabaseClientConfig, type NotificationHandler, type PollingClientConfig, type PusherClientConfig, RealtimeClient, type RealtimeConfig, type RealtimeEventHandler, type RealtimeNotification, type RealtimeSubscription, type RealtimeTransport, type RealtimeTransportName, createFirebaseDatabaseTransport, createFirebaseTransport, createMemoryTransport, createPollingTransport, createPusherTransport, createRealtime, emitMemoryEvent, supersede };
90
+ //#region src/push.d.ts
91
+ /**
92
+ * Issue a device token without a Firebase transport, e.g. when notifications
93
+ * stream over Pusher but are pushed to devices over FCM.
94
+ *
95
+ * @param config
96
+ * @param options
97
+ * @returns
98
+ */
99
+ declare const requestDeviceToken: (config: FirebaseClientConfig, options?: DeviceTokenOptions) => Promise<string | null>;
100
+ //#endregion
101
+ export { type DeviceTokenOptions, type FirebaseClientConfig, type FirebaseDatabaseClientConfig, type NotificationHandler, type PollingClientConfig, type PusherClientConfig, RealtimeClient, type RealtimeConfig, type RealtimeEventHandler, type RealtimeNotification, type RealtimeSubscription, type RealtimeTransport, type RealtimeTransportName, createFirebaseDatabaseTransport, createFirebaseTransport, createMemoryTransport, createPollingTransport, createPusherTransport, createRealtime, emitMemoryEvent, requestDeviceToken, supersede };
package/dist/index.js CHANGED
@@ -1,16 +1,5 @@
1
+ import { i as __exportAll, r as requestDeviceToken, t as issueDeviceToken } from "./push-TmPMqRUR.js";
1
2
  import { t as supersede } from "./supersede-T1ch4wJF.js";
2
- //#region \0rolldown/runtime.js
3
- var __defProp = Object.defineProperty;
4
- var __exportAll = (all, no_symbols) => {
5
- let target = {};
6
- for (var name in all) __defProp(target, name, {
7
- get: all[name],
8
- enumerable: true
9
- });
10
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
- return target;
12
- };
13
- //#endregion
14
3
  //#region src/RealtimeClient.ts
15
4
  /**
16
5
  * Consumes Arkstack realtime notifications. Resolves a transport (Pusher,
@@ -159,12 +148,19 @@ var RealtimeClient = class {
159
148
  }
160
149
  /**
161
150
  * This device's push registration token, for registering with your API.
162
- * Null when the transport cannot issue one.
151
+ * Uses the transport when it can issue one, otherwise the `firebase` config
152
+ * (push over FCM while streaming over another transport). Null when neither
153
+ * can, or the browser cannot receive web push.
163
154
  *
155
+ * @param options
164
156
  * @returns
165
157
  */
166
- async deviceToken() {
167
- return await (await this.transport()).deviceToken?.() ?? null;
158
+ async deviceToken(options) {
159
+ const transport = await this.transport();
160
+ if (transport.deviceToken) return await transport.deviceToken(options);
161
+ if (!this.config.firebase) return null;
162
+ const { requestDeviceToken } = await import("./push-TmPMqRUR.js").then((n) => n.n);
163
+ return await requestDeviceToken(this.config.firebase, options);
168
164
  }
169
165
  /** Tear down the underlying transport connection. */
170
166
  async disconnect() {
@@ -307,9 +303,8 @@ const createFirebaseTransport = async (config) => {
307
303
  });
308
304
  await databaseApi.remove(eventReference);
309
305
  },
310
- async deviceToken() {
311
- const getToken = messagingMod.getToken;
312
- return await getToken(messaging, config.vapidKey ? { vapidKey: config.vapidKey } : void 0) || null;
306
+ async deviceToken(options) {
307
+ return await issueDeviceToken(messagingMod, messaging, config, options);
313
308
  },
314
309
  disconnect() {
315
310
  messageUnsubscribers.forEach((off) => off());
@@ -508,4 +503,4 @@ const createMemoryTransport = () => {
508
503
  };
509
504
  };
510
505
  //#endregion
511
- export { RealtimeClient, createFirebaseDatabaseTransport, createFirebaseTransport, createMemoryTransport, createPollingTransport, createPusherTransport, createRealtime, emitMemoryEvent, supersede };
506
+ export { RealtimeClient, createFirebaseDatabaseTransport, createFirebaseTransport, createMemoryTransport, createPollingTransport, createPusherTransport, createRealtime, emitMemoryEvent, requestDeviceToken, supersede };
@@ -0,0 +1,78 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ //#region src/push.ts
14
+ var push_exports = /* @__PURE__ */ __exportAll({
15
+ issueDeviceToken: () => issueDeviceToken,
16
+ requestDeviceToken: () => requestDeviceToken
17
+ });
18
+ const APP_NAME = "arkstack-push";
19
+ /**
20
+ * The public settings a service worker needs to initialize Firebase.
21
+ *
22
+ * @param config
23
+ * @returns
24
+ */
25
+ const webConfig = (config) => ({
26
+ apiKey: config.apiKey,
27
+ projectId: config.projectId,
28
+ appId: config.appId,
29
+ messagingSenderId: config.messagingSenderId
30
+ });
31
+ /**
32
+ * Register `url` as the messaging service worker, handing it the Firebase web
33
+ * config as the `firebaseConfig` query parameter.
34
+ *
35
+ * @param url
36
+ * @param config
37
+ * @returns
38
+ */
39
+ const registerServiceWorker = async (url, config) => {
40
+ const separator = url.includes("?") ? "&" : "?";
41
+ const query = `firebaseConfig=${encodeURIComponent(JSON.stringify(webConfig(config)))}`;
42
+ return await navigator.serviceWorker.register(`${url}${separator}${query}`);
43
+ };
44
+ /**
45
+ * Issue an FCM registration token for this browser, prompting for notification
46
+ * permission when needed. Null when the browser cannot receive web push.
47
+ *
48
+ * @param messagingMod
49
+ * @param messaging
50
+ * @param config
51
+ * @param options
52
+ * @returns
53
+ */
54
+ const issueDeviceToken = async (messagingMod, messaging, config, options = {}) => {
55
+ if (!await messagingMod.isSupported().catch(() => false)) return null;
56
+ const serviceWorkerRegistration = typeof options.serviceWorker === "string" ? await registerServiceWorker(options.serviceWorker, config) : options.serviceWorker;
57
+ return await messagingMod.getToken(messaging, {
58
+ ...config.vapidKey ? { vapidKey: config.vapidKey } : {},
59
+ ...serviceWorkerRegistration ? { serviceWorkerRegistration } : {}
60
+ }) || null;
61
+ };
62
+ /**
63
+ * Issue a device token without a Firebase transport, e.g. when notifications
64
+ * stream over Pusher but are pushed to devices over FCM.
65
+ *
66
+ * @param config
67
+ * @param options
68
+ * @returns
69
+ */
70
+ const requestDeviceToken = async (config, options = {}) => {
71
+ const [appMod, messagingMod] = await Promise.all([import("firebase/app"), import("firebase/messaging")]).catch(() => {
72
+ throw new Error("The \"firebase\" package is required for device tokens. Install it with `npm i firebase`.");
73
+ });
74
+ const app = appMod.getApps().find((existing) => existing.name === APP_NAME) ?? appMod.initializeApp(webConfig(config), APP_NAME);
75
+ return await issueDeviceToken(messagingMod, messagingMod.getMessaging(app), config, options);
76
+ };
77
+ //#endregion
78
+ export { __exportAll as i, push_exports as n, requestDeviceToken as r, issueDeviceToken as t };
@@ -1,4 +1,4 @@
1
- import { t as RealtimeClient, u as RealtimeNotification } from "../RealtimeClient-MI224djP.js";
1
+ import { d as RealtimeNotification, t as RealtimeClient } from "../RealtimeClient-CAoMUUkc.js";
2
2
  //#region src/react/index.d.ts
3
3
  interface UseNotificationsOptions {
4
4
  /** Cap the number of retained notifications (newest kept). Default: unbounded. */
@@ -1,4 +1,4 @@
1
- import { t as RealtimeClient, u as RealtimeNotification } from "../RealtimeClient-MI224djP.js";
1
+ import { d as RealtimeNotification, t as RealtimeClient } from "../RealtimeClient-CAoMUUkc.js";
2
2
  import { ComputedRef, Ref } from "vue";
3
3
  //#region src/vue/index.d.ts
4
4
  interface UseNotificationsOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/realtime",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
4
4
  "type": "module",
5
5
  "description": "Client for consuming Arkstack realtime notifications (Pusher/Firebase), with framework-agnostic core plus React and Vue bindings.",
6
6
  "homepage": "https://arkstack.toneflix.net/guide/notifications",