@arkstack/realtime 0.18.7 → 0.18.8
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/{RealtimeClient-CpYmOGZa.d.ts → RealtimeClient-CzrWnLtj.d.ts} +8 -0
- package/dist/index.d.ts +28 -2
- package/dist/index.js +2 -1
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.js +6 -4
- package/dist/supersede-T1ch4wJF.js +40 -0
- package/dist/vue/index.d.ts +5 -1
- package/dist/vue/index.js +6 -2
- package/package.json +1 -1
|
@@ -12,6 +12,14 @@ interface RealtimeNotification {
|
|
|
12
12
|
actionText?: string | null;
|
|
13
13
|
actionLink?: string | null;
|
|
14
14
|
meta?: Record<string, unknown> | null;
|
|
15
|
+
/**
|
|
16
|
+
* Stable identity for what this notification is about. A later notification
|
|
17
|
+
* with the same tag supersedes this one rather than stacking beside it — see
|
|
18
|
+
* {@link supersede}, which the React and Vue bindings apply for you.
|
|
19
|
+
*/
|
|
20
|
+
tag?: string | null;
|
|
21
|
+
/** Removes the notification carrying `tag` instead of displaying anything. */
|
|
22
|
+
retracted?: boolean;
|
|
15
23
|
read_at: string | null;
|
|
16
24
|
created_at: string;
|
|
17
25
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as PusherClientConfig, c as RealtimeNotification, d as RealtimeTransportName, i as NotificationHandler, l as RealtimeSubscription, n as createRealtime, o as RealtimeConfig, r as FirebaseClientConfig, s as RealtimeEventHandler, t as RealtimeClient, u as RealtimeTransport } from "./RealtimeClient-
|
|
1
|
+
import { a as PusherClientConfig, c as RealtimeNotification, d as RealtimeTransportName, i as NotificationHandler, l as RealtimeSubscription, n as createRealtime, o as RealtimeConfig, r as FirebaseClientConfig, s as RealtimeEventHandler, t as RealtimeClient, u as RealtimeTransport } from "./RealtimeClient-CzrWnLtj.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).
|
|
@@ -20,4 +20,30 @@ declare const createPusherTransport: (config: PusherClientConfig) => Promise<Rea
|
|
|
20
20
|
*/
|
|
21
21
|
declare const createFirebaseTransport: (config: FirebaseClientConfig) => Promise<RealtimeTransport>;
|
|
22
22
|
//#endregion
|
|
23
|
-
|
|
23
|
+
//#region src/supersede.d.ts
|
|
24
|
+
/**
|
|
25
|
+
* Fold an incoming notification into a list, honouring tag supersession.
|
|
26
|
+
*
|
|
27
|
+
* A notification carrying a `tag` names the thing it is about rather than the
|
|
28
|
+
* moment it was sent, so a later notification with the same tag is understood as
|
|
29
|
+
* a newer account of the same thing:
|
|
30
|
+
*
|
|
31
|
+
* - **Tagged, already present** — replaces the existing entry *in place*. The
|
|
32
|
+
* entry keeps its position so a list does not reshuffle under someone reading
|
|
33
|
+
* it; only its content changes.
|
|
34
|
+
* - **Tagged, not present** — prepended, like any other notification.
|
|
35
|
+
* - **Retracted** — removes the entry it names and contributes nothing itself. A
|
|
36
|
+
* retraction for something never seen is a no-op, which is the common case when
|
|
37
|
+
* a client connects after the fact.
|
|
38
|
+
* - **Untagged** — prepended. Untagged notifications never supersede anything.
|
|
39
|
+
*
|
|
40
|
+
* Pure and list-in/list-out, so it suits any state container; the React and Vue
|
|
41
|
+
* bindings are thin wrappers over it.
|
|
42
|
+
*
|
|
43
|
+
* @param list The notifications held so far, newest first.
|
|
44
|
+
* @param incoming The notification just received.
|
|
45
|
+
* @param limit Caps the retained list (newest kept) when growing it.
|
|
46
|
+
*/
|
|
47
|
+
declare const supersede: (list: RealtimeNotification[], incoming: RealtimeNotification, limit?: number) => RealtimeNotification[];
|
|
48
|
+
//#endregion
|
|
49
|
+
export { type FirebaseClientConfig, type NotificationHandler, type PusherClientConfig, RealtimeClient, type RealtimeConfig, type RealtimeEventHandler, type RealtimeNotification, type RealtimeSubscription, type RealtimeTransport, type RealtimeTransportName, createFirebaseTransport, createPusherTransport, createRealtime, supersede };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as supersede } from "./supersede-T1ch4wJF.js";
|
|
1
2
|
//#region \0rolldown/runtime.js
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -260,4 +261,4 @@ const createFirebaseTransport = async (config) => {
|
|
|
260
261
|
};
|
|
261
262
|
};
|
|
262
263
|
//#endregion
|
|
263
|
-
export { RealtimeClient, createFirebaseTransport, createPusherTransport, createRealtime };
|
|
264
|
+
export { RealtimeClient, createFirebaseTransport, createPusherTransport, createRealtime, supersede };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as RealtimeNotification, t as RealtimeClient } from "../RealtimeClient-
|
|
1
|
+
import { c as RealtimeNotification, t as RealtimeClient } from "../RealtimeClient-CzrWnLtj.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. */
|
|
@@ -14,6 +14,10 @@ interface UseNotificationsResult {
|
|
|
14
14
|
* notifications (newest first) into state. Automatically unsubscribes on unmount
|
|
15
15
|
* or when `client`/`channel` change.
|
|
16
16
|
*
|
|
17
|
+
* Tagged notifications supersede rather than accumulate: one replaces an earlier
|
|
18
|
+
* notification with the same tag in place, and a retraction removes it. See
|
|
19
|
+
* {@link supersede}.
|
|
20
|
+
*
|
|
17
21
|
* @param client A {@link RealtimeClient} (from `createRealtime`).
|
|
18
22
|
* @param channel The channel to subscribe to, e.g. `client.channelFor(user.id)`.
|
|
19
23
|
* @param options `limit` caps how many notifications are retained.
|
package/dist/react/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as supersede } from "../supersede-T1ch4wJF.js";
|
|
1
2
|
import { useCallback, useEffect, useState } from "react";
|
|
2
3
|
//#region src/react/index.ts
|
|
3
4
|
/**
|
|
@@ -5,6 +6,10 @@ import { useCallback, useEffect, useState } from "react";
|
|
|
5
6
|
* notifications (newest first) into state. Automatically unsubscribes on unmount
|
|
6
7
|
* or when `client`/`channel` change.
|
|
7
8
|
*
|
|
9
|
+
* Tagged notifications supersede rather than accumulate: one replaces an earlier
|
|
10
|
+
* notification with the same tag in place, and a retraction removes it. See
|
|
11
|
+
* {@link supersede}.
|
|
12
|
+
*
|
|
8
13
|
* @param client A {@link RealtimeClient} (from `createRealtime`).
|
|
9
14
|
* @param channel The channel to subscribe to, e.g. `client.channelFor(user.id)`.
|
|
10
15
|
* @param options `limit` caps how many notifications are retained.
|
|
@@ -15,10 +20,7 @@ function useNotifications(client, channel, options = {}) {
|
|
|
15
20
|
useEffect(() => {
|
|
16
21
|
let unsubscribe;
|
|
17
22
|
let cancelled = false;
|
|
18
|
-
const push = (notification) => setNotifications((prev) =>
|
|
19
|
-
const next = [notification, ...prev];
|
|
20
|
-
return limit ? next.slice(0, limit) : next;
|
|
21
|
-
});
|
|
23
|
+
const push = (notification) => setNotifications((prev) => supersede(prev, notification, limit));
|
|
22
24
|
client.subscribe(channel, push).then((off) => {
|
|
23
25
|
if (cancelled) off();
|
|
24
26
|
else unsubscribe = off;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/supersede.ts
|
|
2
|
+
/**
|
|
3
|
+
* Fold an incoming notification into a list, honouring tag supersession.
|
|
4
|
+
*
|
|
5
|
+
* A notification carrying a `tag` names the thing it is about rather than the
|
|
6
|
+
* moment it was sent, so a later notification with the same tag is understood as
|
|
7
|
+
* a newer account of the same thing:
|
|
8
|
+
*
|
|
9
|
+
* - **Tagged, already present** — replaces the existing entry *in place*. The
|
|
10
|
+
* entry keeps its position so a list does not reshuffle under someone reading
|
|
11
|
+
* it; only its content changes.
|
|
12
|
+
* - **Tagged, not present** — prepended, like any other notification.
|
|
13
|
+
* - **Retracted** — removes the entry it names and contributes nothing itself. A
|
|
14
|
+
* retraction for something never seen is a no-op, which is the common case when
|
|
15
|
+
* a client connects after the fact.
|
|
16
|
+
* - **Untagged** — prepended. Untagged notifications never supersede anything.
|
|
17
|
+
*
|
|
18
|
+
* Pure and list-in/list-out, so it suits any state container; the React and Vue
|
|
19
|
+
* bindings are thin wrappers over it.
|
|
20
|
+
*
|
|
21
|
+
* @param list The notifications held so far, newest first.
|
|
22
|
+
* @param incoming The notification just received.
|
|
23
|
+
* @param limit Caps the retained list (newest kept) when growing it.
|
|
24
|
+
*/
|
|
25
|
+
const supersede = (list, incoming, limit) => {
|
|
26
|
+
const { tag, retracted } = incoming;
|
|
27
|
+
if (retracted) return tag ? list.filter((notification) => notification.tag !== tag) : list;
|
|
28
|
+
if (tag) {
|
|
29
|
+
const index = list.findIndex((notification) => notification.tag === tag);
|
|
30
|
+
if (index !== -1) {
|
|
31
|
+
const next = list.slice();
|
|
32
|
+
next[index] = incoming;
|
|
33
|
+
return next;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const next = [incoming, ...list];
|
|
37
|
+
return limit ? next.slice(0, limit) : next;
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { supersede as t };
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as RealtimeNotification, t as RealtimeClient } from "../RealtimeClient-
|
|
1
|
+
import { c as RealtimeNotification, t as RealtimeClient } from "../RealtimeClient-CzrWnLtj.js";
|
|
2
2
|
import { ComputedRef, Ref } from "vue";
|
|
3
3
|
//#region src/vue/index.d.ts
|
|
4
4
|
interface UseNotificationsOptions {
|
|
@@ -16,6 +16,10 @@ interface UseNotificationsResult {
|
|
|
16
16
|
* notifications (newest first) into a ref. Automatically unsubscribes when the
|
|
17
17
|
* scope is disposed (component unmount).
|
|
18
18
|
*
|
|
19
|
+
* Tagged notifications supersede rather than accumulate: one replaces an earlier
|
|
20
|
+
* notification with the same tag in place, and a retraction removes it. See
|
|
21
|
+
* {@link supersede}.
|
|
22
|
+
*
|
|
19
23
|
* @param client A {@link RealtimeClient} (from `createRealtime`).
|
|
20
24
|
* @param channel The channel to subscribe to, e.g. `client.channelFor(user.id)`.
|
|
21
25
|
* @param options `limit` caps how many notifications are retained.
|
package/dist/vue/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as supersede } from "../supersede-T1ch4wJF.js";
|
|
1
2
|
import { computed, onScopeDispose, ref } from "vue";
|
|
2
3
|
//#region src/vue/index.ts
|
|
3
4
|
/**
|
|
@@ -5,6 +6,10 @@ import { computed, onScopeDispose, ref } from "vue";
|
|
|
5
6
|
* notifications (newest first) into a ref. Automatically unsubscribes when the
|
|
6
7
|
* scope is disposed (component unmount).
|
|
7
8
|
*
|
|
9
|
+
* Tagged notifications supersede rather than accumulate: one replaces an earlier
|
|
10
|
+
* notification with the same tag in place, and a retraction removes it. See
|
|
11
|
+
* {@link supersede}.
|
|
12
|
+
*
|
|
8
13
|
* @param client A {@link RealtimeClient} (from `createRealtime`).
|
|
9
14
|
* @param channel The channel to subscribe to, e.g. `client.channelFor(user.id)`.
|
|
10
15
|
* @param options `limit` caps how many notifications are retained.
|
|
@@ -15,8 +20,7 @@ function useNotifications(client, channel, options = {}) {
|
|
|
15
20
|
let unsubscribe;
|
|
16
21
|
let cancelled = false;
|
|
17
22
|
const push = (notification) => {
|
|
18
|
-
|
|
19
|
-
notifications.value = limit ? next.slice(0, limit) : next;
|
|
23
|
+
notifications.value = supersede(notifications.value, notification, limit);
|
|
20
24
|
};
|
|
21
25
|
client.subscribe(channel, push).then((off) => {
|
|
22
26
|
if (cancelled) off();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkstack/realtime",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.8",
|
|
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",
|