@marinoscar/platform-api 0.1.0-next.22 → 0.1.0-next.24
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/CHANGELOG.md +25 -0
- package/dist/core/data-access/access-reason.registry.d.ts +4 -1
- package/dist/core/data-access/access-reason.registry.d.ts.map +1 -1
- package/dist/core/data-access/access-reason.registry.js +5 -0
- package/dist/core/data-access/access-reason.registry.js.map +1 -1
- package/dist/core/testing/vocabulary-conformance.js +2 -2
- package/dist/core/testing/vocabulary-conformance.js.map +1 -1
- package/dist/notifications/channels/browser-notification.channel.d.ts +11 -0
- package/dist/notifications/channels/browser-notification.channel.d.ts.map +1 -1
- package/dist/notifications/channels/browser-notification.channel.js +71 -48
- package/dist/notifications/channels/browser-notification.channel.js.map +1 -1
- package/dist/notifications/data/notifications-db.d.ts +19 -0
- package/dist/notifications/data/notifications-db.d.ts.map +1 -1
- package/dist/notifications/dto/notification.dto.d.ts +4 -0
- package/dist/notifications/dto/notification.dto.d.ts.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/notification-inbox-writer.d.ts +112 -0
- package/dist/notifications/notification-inbox-writer.d.ts.map +1 -0
- package/dist/notifications/notification-inbox-writer.js +217 -0
- package/dist/notifications/notification-inbox-writer.js.map +1 -0
- package/dist/notifications/notification-store.service.d.ts +10 -0
- package/dist/notifications/notification-store.service.d.ts.map +1 -1
- package/dist/notifications/notification-store.service.js +55 -10
- package/dist/notifications/notification-store.service.js.map +1 -1
- package/dist/notifications/notification-stream.service.d.ts +8 -0
- package/dist/notifications/notification-stream.service.d.ts.map +1 -1
- package/dist/notifications/notification-stream.service.js.map +1 -1
- package/dist/notifications/notification.types.d.ts +74 -0
- package/dist/notifications/notification.types.d.ts.map +1 -1
- package/dist/notifications/notification.types.js.map +1 -1
- package/dist/notifications/notifications.controller.d.ts +1 -0
- package/dist/notifications/notifications.controller.d.ts.map +1 -1
- package/dist/notifications/notifications.controller.js +23 -0
- package/dist/notifications/notifications.controller.js.map +1 -1
- package/dist/notifications/notifications.service.d.ts +56 -1
- package/dist/notifications/notifications.service.d.ts.map +1 -1
- package/dist/notifications/notifications.service.js +122 -0
- package/dist/notifications/notifications.service.js.map +1 -1
- package/dist/notifications/registry/event.registry.d.ts +15 -0
- package/dist/notifications/registry/event.registry.d.ts.map +1 -1
- package/dist/notifications/registry/event.registry.js +3 -0
- package/dist/notifications/registry/event.registry.js.map +1 -1
- package/dist/notifications/retention/notification-inbox-purge.handler.d.ts.map +1 -1
- package/dist/notifications/retention/notification-inbox-purge.handler.js +16 -4
- package/dist/notifications/retention/notification-inbox-purge.handler.js.map +1 -1
- package/dist/notifications/testing/index.d.ts +2 -0
- package/dist/notifications/testing/index.d.ts.map +1 -1
- package/dist/notifications/testing/index.js +5 -1
- package/dist/notifications/testing/index.js.map +1 -1
- package/dist/sharing/events.d.ts +23 -0
- package/dist/sharing/events.d.ts.map +1 -1
- package/dist/sharing/events.js +1 -0
- package/dist/sharing/events.js.map +1 -1
- package/dist/sharing/groups/group-common.d.ts +1 -1
- package/dist/sharing/groups/group-common.d.ts.map +1 -1
- package/dist/sharing/groups/group-common.js.map +1 -1
- package/dist/sharing/groups/group-invites.service.d.ts +77 -2
- package/dist/sharing/groups/group-invites.service.d.ts.map +1 -1
- package/dist/sharing/groups/group-invites.service.js +181 -0
- package/dist/sharing/groups/group-invites.service.js.map +1 -1
- package/dist/sharing/groups/invite-auto-accept.listener.d.ts +37 -0
- package/dist/sharing/groups/invite-auto-accept.listener.d.ts.map +1 -0
- package/dist/sharing/groups/invite-auto-accept.listener.js +115 -0
- package/dist/sharing/groups/invite-auto-accept.listener.js.map +1 -0
- package/dist/sharing/index.d.ts +5 -3
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +6 -3
- package/dist/sharing/index.js.map +1 -1
- package/dist/sharing/metrics.d.ts +1 -1
- package/dist/sharing/metrics.d.ts.map +1 -1
- package/dist/sharing/metrics.js +1 -0
- package/dist/sharing/metrics.js.map +1 -1
- package/dist/sharing/ports.d.ts +3 -2
- package/dist/sharing/ports.d.ts.map +1 -1
- package/dist/sharing/ports.js.map +1 -1
- package/dist/sharing/sharing.module.d.ts.map +1 -1
- package/dist/sharing/sharing.module.js +3 -0
- package/dist/sharing/sharing.module.js.map +1 -1
- package/dist/sharing/sharing.options.d.ts +39 -5
- package/dist/sharing/sharing.options.d.ts.map +1 -1
- package/dist/sharing/sharing.options.js +17 -8
- package/dist/sharing/sharing.options.js.map +1 -1
- package/dist/storage/config/storage-config.service.d.ts +24 -0
- package/dist/storage/config/storage-config.service.d.ts.map +1 -1
- package/dist/storage/config/storage-config.service.js +31 -5
- package/dist/storage/config/storage-config.service.js.map +1 -1
- package/dist/storage/handlers/storage-cleanup.handler.d.ts +3 -1
- package/dist/storage/handlers/storage-cleanup.handler.d.ts.map +1 -1
- package/dist/storage/handlers/storage-cleanup.handler.js +10 -3
- package/dist/storage/handlers/storage-cleanup.handler.js.map +1 -1
- package/dist/storage/index.d.ts +5 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +12 -3
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/objects/dto/get-part-urls.dto.d.ts +26 -0
- package/dist/storage/objects/dto/get-part-urls.dto.d.ts.map +1 -0
- package/dist/storage/objects/dto/get-part-urls.dto.js +25 -0
- package/dist/storage/objects/dto/get-part-urls.dto.js.map +1 -0
- package/dist/storage/objects/dto/init-upload.dto.d.ts +2 -1
- package/dist/storage/objects/dto/init-upload.dto.d.ts.map +1 -1
- package/dist/storage/objects/objects.controller.d.ts +13 -1
- package/dist/storage/objects/objects.controller.d.ts.map +1 -1
- package/dist/storage/objects/objects.controller.js +88 -1
- package/dist/storage/objects/objects.controller.js.map +1 -1
- package/dist/storage/objects/objects.service.d.ts +46 -1
- package/dist/storage/objects/objects.service.d.ts.map +1 -1
- package/dist/storage/objects/objects.service.js +277 -23
- package/dist/storage/objects/objects.service.js.map +1 -1
- package/dist/storage/objects/part-body-parser.d.ts +30 -0
- package/dist/storage/objects/part-body-parser.d.ts.map +1 -0
- package/dist/storage/objects/part-body-parser.js +45 -0
- package/dist/storage/objects/part-body-parser.js.map +1 -0
- package/dist/storage/objects/part-body.d.ts +23 -0
- package/dist/storage/objects/part-body.d.ts.map +1 -0
- package/dist/storage/objects/part-body.js +48 -0
- package/dist/storage/objects/part-body.js.map +1 -0
- package/dist/storage/processing/object-processing.service.d.ts +4 -1
- package/dist/storage/processing/object-processing.service.d.ts.map +1 -1
- package/dist/storage/processing/object-processing.service.js +11 -3
- package/dist/storage/processing/object-processing.service.js.map +1 -1
- package/dist/storage/profile-image/avatar.service.d.ts +3 -1
- package/dist/storage/profile-image/avatar.service.d.ts.map +1 -1
- package/dist/storage/profile-image/avatar.service.js +8 -3
- package/dist/storage/profile-image/avatar.service.js.map +1 -1
- package/dist/storage/profile-image/profile-image.service.d.ts +4 -1
- package/dist/storage/profile-image/profile-image.service.d.ts.map +1 -1
- package/dist/storage/profile-image/profile-image.service.js +11 -5
- package/dist/storage/profile-image/profile-image.service.js.map +1 -1
- package/dist/storage/providers/index.d.ts +3 -1
- package/dist/storage/providers/index.d.ts.map +1 -1
- package/dist/storage/providers/index.js +8 -1
- package/dist/storage/providers/index.js.map +1 -1
- package/dist/storage/providers/resolving-storage.provider.d.ts +11 -0
- package/dist/storage/providers/resolving-storage.provider.d.ts.map +1 -1
- package/dist/storage/providers/resolving-storage.provider.js +13 -0
- package/dist/storage/providers/resolving-storage.provider.js.map +1 -1
- package/dist/storage/providers/s3/s3-storage.provider.d.ts +9 -1
- package/dist/storage/providers/s3/s3-storage.provider.d.ts.map +1 -1
- package/dist/storage/providers/s3/s3-storage.provider.js +37 -0
- package/dist/storage/providers/s3/s3-storage.provider.js.map +1 -1
- package/dist/storage/providers/storage-provider-router.d.ts +64 -0
- package/dist/storage/providers/storage-provider-router.d.ts.map +1 -0
- package/dist/storage/providers/storage-provider-router.js +161 -0
- package/dist/storage/providers/storage-provider-router.js.map +1 -0
- package/dist/storage/providers/storage-provider.interface.d.ts +34 -1
- package/dist/storage/providers/storage-provider.interface.d.ts.map +1 -1
- package/dist/storage/providers/storage-provider.interface.js.map +1 -1
- package/dist/storage/providers/storage-provider.types.d.ts +86 -0
- package/dist/storage/providers/storage-provider.types.d.ts.map +1 -1
- package/dist/storage/providers/storage-provider.types.js +78 -0
- package/dist/storage/providers/storage-provider.types.js.map +1 -1
- package/dist/storage/providers/storage-providers.module.d.ts.map +1 -1
- package/dist/storage/providers/storage-providers.module.js +3 -1
- package/dist/storage/providers/storage-providers.module.js.map +1 -1
- package/dist/storage/testing/conformance.d.ts +12 -0
- package/dist/storage/testing/conformance.d.ts.map +1 -1
- package/dist/storage/testing/conformance.js +112 -0
- package/dist/storage/testing/conformance.js.map +1 -1
- package/dist/storage/testing/driver-conformance.d.ts +13 -1
- package/dist/storage/testing/driver-conformance.d.ts.map +1 -1
- package/dist/storage/testing/driver-conformance.js +134 -0
- package/dist/storage/testing/driver-conformance.js.map +1 -1
- package/dist/storage/testing/index.d.ts +1 -1
- package/dist/storage/testing/index.d.ts.map +1 -1
- package/dist/storage/testing/index.js +2 -1
- package/dist/storage/testing/index.js.map +1 -1
- package/dist/telemetry/stack/dto/telemetry-stack.dto.d.ts +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { NotificationsPrisma } from './data/notifications-db';
|
|
2
|
+
import type { InboxWrite } from './notification.types';
|
|
3
|
+
/**
|
|
4
|
+
* What a template produced, already length-capped and link-sanitised.
|
|
5
|
+
*
|
|
6
|
+
* @stability experimental
|
|
7
|
+
*/
|
|
8
|
+
export interface InboxContent {
|
|
9
|
+
/** The title. */
|
|
10
|
+
title: string;
|
|
11
|
+
/** The body. */
|
|
12
|
+
body: string;
|
|
13
|
+
/** A sanitised root-relative link, or null. */
|
|
14
|
+
link: string | null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Why an inbox write changed what the user sees.
|
|
18
|
+
*
|
|
19
|
+
* @stability experimental
|
|
20
|
+
*/
|
|
21
|
+
export type InboxWriteReason = 'created' | 'incremented' | 'reunread';
|
|
22
|
+
/**
|
|
23
|
+
* The outcome of one STATE or COUNTED write.
|
|
24
|
+
*
|
|
25
|
+
* @stability experimental
|
|
26
|
+
*/
|
|
27
|
+
export interface InboxWriteResult {
|
|
28
|
+
/** The row's id. */
|
|
29
|
+
id: string;
|
|
30
|
+
/** When the row was first created. */
|
|
31
|
+
createdAt: Date;
|
|
32
|
+
/** When this write refreshed it. */
|
|
33
|
+
updatedAt: Date;
|
|
34
|
+
/** The row's `data.count` after the write. */
|
|
35
|
+
count: number;
|
|
36
|
+
/** The row's scope, or null. */
|
|
37
|
+
scopeId: string | null;
|
|
38
|
+
/** Why this is news: a new row, a row that grew, or a read row that is unread again. */
|
|
39
|
+
reason: InboxWriteReason;
|
|
40
|
+
/** True when the row did not change what the user sees (a STATE refresh with an unchanged count). */
|
|
41
|
+
quiet: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Renders the row from the final payload; may throw (the writer lets it propagate before writing).
|
|
45
|
+
*
|
|
46
|
+
* @stability experimental
|
|
47
|
+
*/
|
|
48
|
+
export type InboxRender = (data: Record<string, unknown>) => InboxContent;
|
|
49
|
+
/**
|
|
50
|
+
* Builds the dedup key of a STATE row: one per `(eventKey, scopeId)`.
|
|
51
|
+
*
|
|
52
|
+
* @stability experimental
|
|
53
|
+
*/
|
|
54
|
+
export declare function stateDedupKey(eventKey: string, scopeId: string | null): string;
|
|
55
|
+
/**
|
|
56
|
+
* Builds the dedup key of a COUNTED row: one per `(eventKey, scopeId, match)`.
|
|
57
|
+
* The match object is serialised with sorted keys, so `{a, b}` and `{b, a}`
|
|
58
|
+
* fold together.
|
|
59
|
+
*
|
|
60
|
+
* @stability experimental
|
|
61
|
+
*/
|
|
62
|
+
export declare function countedDedupKey(eventKey: string, scopeId: string | null, match: Readonly<Record<string, string | number | boolean>> | undefined): string;
|
|
63
|
+
/**
|
|
64
|
+
* Writes STATE and COUNTED inbox rows.
|
|
65
|
+
*
|
|
66
|
+
* Exported for an app's own unit tests (`@marinoscar/platform-api/notifications/testing`); not an extension point: reach it through `NotificationsService.notifyState` and `notifyCounted`.
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
export declare class NotificationInboxWriter {
|
|
71
|
+
private readonly prisma;
|
|
72
|
+
constructor(prisma: NotificationsPrisma);
|
|
73
|
+
/**
|
|
74
|
+
* Upserts the single live STATE row, or returns null when `mode.count` is
|
|
75
|
+
* not positive (use {@link dismissLive} for that).
|
|
76
|
+
*
|
|
77
|
+
* The refresh replaces title, body, link and `data` wholesale, carrying
|
|
78
|
+
* `countAtRead` forward (replacing `data` would otherwise silently disable the
|
|
79
|
+
* re-unread rule until the row is next read). A READ row is re-marked unread
|
|
80
|
+
* only when `reunreadWhen` is `count-increased`, the new count exceeds a
|
|
81
|
+
* recorded `countAtRead`, and nothing else: never on a decrease, never on an
|
|
82
|
+
* equal count, never on a row with no `countAtRead` (absent means "already
|
|
83
|
+
* seen"; re-unreading on it would re-nag every legacy row on every refresh).
|
|
84
|
+
*/
|
|
85
|
+
upsertState(userId: string, eventKey: string, mode: Extract<InboxWrite, {
|
|
86
|
+
kind: 'state';
|
|
87
|
+
}>, data: Record<string, unknown>, render: InboxRender): Promise<InboxWriteResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Folds one occurrence into the live COUNTED row, or starts a new row.
|
|
90
|
+
*
|
|
91
|
+
* Inside the window (or with none) the live row's `data.count` grows by
|
|
92
|
+
* `increment`, its text is re-rendered with the new total, and `readAt` is
|
|
93
|
+
* cleared so continued activity re-badges the bell. Outside the window the
|
|
94
|
+
* old row is RETIRED (its `dedup_key` becomes `retired:<id>` so the key is free; it stays in
|
|
95
|
+
* the inbox as the record of that batch) and a fresh row starts at
|
|
96
|
+
* `increment`.
|
|
97
|
+
*/
|
|
98
|
+
upsertCounted(userId: string, eventKey: string, mode: Extract<InboxWrite, {
|
|
99
|
+
kind: 'counted';
|
|
100
|
+
}>, data: Record<string, unknown>, render: InboxRender, now?: Date): Promise<InboxWriteResult>;
|
|
101
|
+
/**
|
|
102
|
+
* Dismisses the live row of `dedupKey` (a STATE row whose count drained to
|
|
103
|
+
* zero). Dismissal implies read. Returns whether a row was dismissed.
|
|
104
|
+
*/
|
|
105
|
+
dismissLive(userId: string, dedupKey: string): Promise<boolean>;
|
|
106
|
+
/** Runs `work` in a transaction holding the advisory lock of `(userId, dedupKey)`. */
|
|
107
|
+
private locked;
|
|
108
|
+
/** One retry on a unique violation: the winner's row exists now, so the retry folds into it. */
|
|
109
|
+
private withRetry;
|
|
110
|
+
private findLive;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=notification-inbox-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-inbox-writer.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-inbox-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,mBAAmB,EAEpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAuDvD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,SAAS,EAAE,IAAI,CAAC;IAChB,oCAAoC;IACpC,SAAS,EAAE,IAAI,CAAC;IAChB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wFAAwF;IACxF,MAAM,EAAE,gBAAgB,CAAC;IACzB,qGAAqG;IACrG,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,YAAY,CAAC;AAQ1E;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,GACrE,MAAM,CAIR;AAmBD;;;;;;GAMG;AACH,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,mBAAmB;IAExD;;;;;;;;;;;OAWG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,EAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,gBAAgB,CAAC;IAsD5B;;;;;;;;;OASG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,EAC9C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,WAAW,EACnB,GAAG,GAAE,IAAiB,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAqD5B;;;OAGG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUrE,sFAAsF;IACtF,OAAO,CAAC,MAAM;IAQd,gGAAgG;YAClF,SAAS;IASvB,OAAO,CAAC,QAAQ;CAGjB"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NotificationInboxWriter = void 0;
|
|
4
|
+
exports.stateDedupKey = stateDedupKey;
|
|
5
|
+
exports.countedDedupKey = countedDedupKey;
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
/** Longest dedup key stored; longer keys are hashed. */
|
|
8
|
+
const MAX_DEDUP_KEY_LENGTH = 200;
|
|
9
|
+
/** Prisma's unique-violation code. */
|
|
10
|
+
const UNIQUE_VIOLATION = 'P2002';
|
|
11
|
+
/**
|
|
12
|
+
* Builds the dedup key of a STATE row: one per `(eventKey, scopeId)`.
|
|
13
|
+
*
|
|
14
|
+
* @stability experimental
|
|
15
|
+
*/
|
|
16
|
+
function stateDedupKey(eventKey, scopeId) {
|
|
17
|
+
return capKey(`state:${eventKey}:${scopeId ?? '-'}`);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds the dedup key of a COUNTED row: one per `(eventKey, scopeId, match)`.
|
|
21
|
+
* The match object is serialised with sorted keys, so `{a, b}` and `{b, a}`
|
|
22
|
+
* fold together.
|
|
23
|
+
*
|
|
24
|
+
* @stability experimental
|
|
25
|
+
*/
|
|
26
|
+
function countedDedupKey(eventKey, scopeId, match) {
|
|
27
|
+
const entries = Object.entries(match ?? {}).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
28
|
+
const suffix = entries.length === 0 ? '' : `:${JSON.stringify(entries)}`;
|
|
29
|
+
return capKey(`counted:${eventKey}:${scopeId ?? '-'}${suffix}`);
|
|
30
|
+
}
|
|
31
|
+
function capKey(key) {
|
|
32
|
+
if (key.length <= MAX_DEDUP_KEY_LENGTH)
|
|
33
|
+
return key;
|
|
34
|
+
return `${key.slice(0, 120)}#${(0, node_crypto_1.createHash)('sha256').update(key).digest('hex').slice(0, 40)}`;
|
|
35
|
+
}
|
|
36
|
+
function asRecord(value) {
|
|
37
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) ? { ...value } : {};
|
|
38
|
+
}
|
|
39
|
+
function asCount(value) {
|
|
40
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
41
|
+
}
|
|
42
|
+
function isUniqueViolation(err) {
|
|
43
|
+
return typeof err === 'object' && err !== null && err.code === UNIQUE_VIOLATION;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Writes STATE and COUNTED inbox rows.
|
|
47
|
+
*
|
|
48
|
+
* Exported for an app's own unit tests (`@marinoscar/platform-api/notifications/testing`); not an extension point: reach it through `NotificationsService.notifyState` and `notifyCounted`.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
class NotificationInboxWriter {
|
|
53
|
+
prisma;
|
|
54
|
+
constructor(prisma) {
|
|
55
|
+
this.prisma = prisma;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Upserts the single live STATE row, or returns null when `mode.count` is
|
|
59
|
+
* not positive (use {@link dismissLive} for that).
|
|
60
|
+
*
|
|
61
|
+
* The refresh replaces title, body, link and `data` wholesale, carrying
|
|
62
|
+
* `countAtRead` forward (replacing `data` would otherwise silently disable the
|
|
63
|
+
* re-unread rule until the row is next read). A READ row is re-marked unread
|
|
64
|
+
* only when `reunreadWhen` is `count-increased`, the new count exceeds a
|
|
65
|
+
* recorded `countAtRead`, and nothing else: never on a decrease, never on an
|
|
66
|
+
* equal count, never on a row with no `countAtRead` (absent means "already
|
|
67
|
+
* seen"; re-unreading on it would re-nag every legacy row on every refresh).
|
|
68
|
+
*/
|
|
69
|
+
async upsertState(userId, eventKey, mode, data, render) {
|
|
70
|
+
return this.withRetry(() => this.locked(userId, mode.dedupKey, async (tx) => {
|
|
71
|
+
const live = await this.findLive(tx, userId, mode.dedupKey);
|
|
72
|
+
const payload = { ...data, count: mode.count };
|
|
73
|
+
if (!live) {
|
|
74
|
+
const content = render(payload);
|
|
75
|
+
const created = await tx.notification.create({
|
|
76
|
+
data: {
|
|
77
|
+
userId,
|
|
78
|
+
eventKey,
|
|
79
|
+
...content,
|
|
80
|
+
scopeId: mode.scopeId,
|
|
81
|
+
data: payload,
|
|
82
|
+
dedupKey: mode.dedupKey,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
return result(created, mode.count, 'created', false);
|
|
86
|
+
}
|
|
87
|
+
const previous = asRecord(live.data);
|
|
88
|
+
const previousCount = asCount(previous['count']);
|
|
89
|
+
const countAtRead = asCount(previous['countAtRead']);
|
|
90
|
+
const grew = previousCount === null ? true : mode.count > previousCount;
|
|
91
|
+
const reunread = live.readAt !== null &&
|
|
92
|
+
mode.reunreadWhen === 'count-increased' &&
|
|
93
|
+
countAtRead !== null &&
|
|
94
|
+
mode.count > countAtRead;
|
|
95
|
+
const merged = { ...payload };
|
|
96
|
+
if (countAtRead !== null)
|
|
97
|
+
merged['countAtRead'] = countAtRead;
|
|
98
|
+
const content = render(merged);
|
|
99
|
+
const updated = await tx.notification.update({
|
|
100
|
+
where: { id: live.id },
|
|
101
|
+
data: {
|
|
102
|
+
...content,
|
|
103
|
+
scopeId: mode.scopeId,
|
|
104
|
+
data: merged,
|
|
105
|
+
...(reunread ? { readAt: null } : {}),
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
// Quiet: nothing for the user to notice (same count, still as read or
|
|
109
|
+
// unread as before). The row is refreshed but no stream frame is sent.
|
|
110
|
+
const quiet = !reunread && !(grew && live.readAt === null);
|
|
111
|
+
return result(updated, mode.count, reunread ? 'reunread' : 'incremented', quiet);
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Folds one occurrence into the live COUNTED row, or starts a new row.
|
|
116
|
+
*
|
|
117
|
+
* Inside the window (or with none) the live row's `data.count` grows by
|
|
118
|
+
* `increment`, its text is re-rendered with the new total, and `readAt` is
|
|
119
|
+
* cleared so continued activity re-badges the bell. Outside the window the
|
|
120
|
+
* old row is RETIRED (its `dedup_key` becomes `retired:<id>` so the key is free; it stays in
|
|
121
|
+
* the inbox as the record of that batch) and a fresh row starts at
|
|
122
|
+
* `increment`.
|
|
123
|
+
*/
|
|
124
|
+
async upsertCounted(userId, eventKey, mode, data, render, now = new Date()) {
|
|
125
|
+
return this.withRetry(() => this.locked(userId, mode.dedupKey, async (tx) => {
|
|
126
|
+
let live = await this.findLive(tx, userId, mode.dedupKey);
|
|
127
|
+
if (live && mode.windowMs !== null && now.getTime() - live.updatedAt.getTime() > mode.windowMs) {
|
|
128
|
+
// Retire, do not delete or dismiss: the user still sees that batch.
|
|
129
|
+
// The key becomes 'retired:<id>', unique to the row, so the live key
|
|
130
|
+
// is free and the row still reads as a folded one (non-null key) to
|
|
131
|
+
// the retention sweep. Raw: Prisma's `update` would also bump
|
|
132
|
+
// `updated_at`, rewriting the timestamp this row is evidence of.
|
|
133
|
+
await tx.$executeRaw `UPDATE notifications SET dedup_key = ${`retired:${live.id}`} WHERE id = ${live.id}::uuid`;
|
|
134
|
+
live = null;
|
|
135
|
+
}
|
|
136
|
+
if (!live) {
|
|
137
|
+
const payload = { ...data, count: mode.increment };
|
|
138
|
+
const content = render(payload);
|
|
139
|
+
const created = await tx.notification.create({
|
|
140
|
+
data: {
|
|
141
|
+
userId,
|
|
142
|
+
eventKey,
|
|
143
|
+
...content,
|
|
144
|
+
scopeId: mode.scopeId,
|
|
145
|
+
data: payload,
|
|
146
|
+
dedupKey: mode.dedupKey,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
return result(created, mode.increment, 'created', false);
|
|
150
|
+
}
|
|
151
|
+
const previous = asRecord(live.data);
|
|
152
|
+
const total = (asCount(previous['count']) ?? 0) + mode.increment;
|
|
153
|
+
// The latest occurrence's fields win; the count accumulates and any
|
|
154
|
+
// `countAtRead` is untouched.
|
|
155
|
+
const merged = { ...previous, ...data, count: total };
|
|
156
|
+
const content = render(merged);
|
|
157
|
+
const wasRead = live.readAt !== null;
|
|
158
|
+
const updated = await tx.notification.update({
|
|
159
|
+
where: { id: live.id },
|
|
160
|
+
data: {
|
|
161
|
+
...content,
|
|
162
|
+
data: merged,
|
|
163
|
+
readAt: null,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
return result(updated, total, wasRead ? 'reunread' : 'incremented', false);
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Dismisses the live row of `dedupKey` (a STATE row whose count drained to
|
|
171
|
+
* zero). Dismissal implies read. Returns whether a row was dismissed.
|
|
172
|
+
*/
|
|
173
|
+
async dismissLive(userId, dedupKey) {
|
|
174
|
+
return this.locked(userId, dedupKey, async (tx) => {
|
|
175
|
+
const touched = await tx.$executeRaw `
|
|
176
|
+
UPDATE notifications
|
|
177
|
+
SET dismissed_at = now(), read_at = COALESCE(read_at, now()), updated_at = now()
|
|
178
|
+
WHERE user_id = ${userId}::uuid AND dedup_key = ${dedupKey} AND dismissed_at IS NULL`;
|
|
179
|
+
return touched > 0;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/** Runs `work` in a transaction holding the advisory lock of `(userId, dedupKey)`. */
|
|
183
|
+
locked(userId, dedupKey, work) {
|
|
184
|
+
const lockKey = `${userId}|${dedupKey}`;
|
|
185
|
+
return this.prisma.$transaction(async (tx) => {
|
|
186
|
+
await tx.$executeRaw `SELECT pg_advisory_xact_lock(hashtext(${lockKey}))`;
|
|
187
|
+
return work(tx);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/** One retry on a unique violation: the winner's row exists now, so the retry folds into it. */
|
|
191
|
+
async withRetry(attempt) {
|
|
192
|
+
try {
|
|
193
|
+
return await attempt();
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
if (!isUniqueViolation(err))
|
|
197
|
+
throw err;
|
|
198
|
+
return attempt();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
findLive(tx, userId, dedupKey) {
|
|
202
|
+
return tx.notification.findFirst({ where: { userId, dedupKey, dismissedAt: null } });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.NotificationInboxWriter = NotificationInboxWriter;
|
|
206
|
+
function result(row, count, reason, quiet) {
|
|
207
|
+
return {
|
|
208
|
+
id: row.id,
|
|
209
|
+
createdAt: row.createdAt,
|
|
210
|
+
updatedAt: row.updatedAt,
|
|
211
|
+
count,
|
|
212
|
+
scopeId: row.scopeId ?? null,
|
|
213
|
+
reason,
|
|
214
|
+
quiet,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=notification-inbox-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-inbox-writer.js","sourceRoot":"","sources":["../../src/notifications/notification-inbox-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -68,5 +68,15 @@ export declare class NotificationStoreService {
|
|
|
68
68
|
* be showing 1.
|
|
69
69
|
*/
|
|
70
70
|
markAllRead(userId: string): Promise<number>;
|
|
71
|
+
/**
|
|
72
|
+
* Dismiss one notification ("stop showing me this") and report the badge.
|
|
73
|
+
*
|
|
74
|
+
* Dismissal implies read, so the row never lingers in the unread count. The
|
|
75
|
+
* row leaves the list; the retention sweep deletes it by age. Idempotent, and
|
|
76
|
+
* ownership-scoped exactly like {@link markRead}: another user's id is a 404.
|
|
77
|
+
*
|
|
78
|
+
* @throws NotFoundException when the id belongs to nobody, or to somebody else.
|
|
79
|
+
*/
|
|
80
|
+
dismiss(userId: string, id: string): Promise<number>;
|
|
71
81
|
}
|
|
72
82
|
//# sourceMappingURL=notification-store.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-store.service.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-store.service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiC,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EAEzB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"notification-store.service.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-store.service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiC,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EAEzB,MAAM,wBAAwB,CAAC;AA4DhC;;;;GAIG;AACH,qBACa,wBAAwB;IACE,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,mBAAmB;IAEjF;;;;;;;;;;;;;;OAcG;IACG,IAAI,CACR,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,wBAAwB,CAAC;IA+BpC;;;;;;;;;;OAUG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMlD;;;;;;;;;;;;;;;;;;OAkBG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC3D;;;;;;;;;;OAUG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAYlD;;;;;;;;OAQG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgB3D"}
|
|
@@ -66,6 +66,10 @@ const NOTIFICATION_FIELDS = {
|
|
|
66
66
|
link: true,
|
|
67
67
|
readAt: true,
|
|
68
68
|
createdAt: true,
|
|
69
|
+
data: true,
|
|
70
|
+
scopeId: true,
|
|
71
|
+
dismissedAt: true,
|
|
72
|
+
updatedAt: true,
|
|
69
73
|
};
|
|
70
74
|
/**
|
|
71
75
|
* Exported for an app's own unit tests (`@marinoscar/platform-api/notifications/testing`); not an extension point: reach it through `NotificationsModule` and its documented seams.
|
|
@@ -95,8 +99,10 @@ let NotificationStoreService = class NotificationStoreService {
|
|
|
95
99
|
async list(userId, query) {
|
|
96
100
|
const { page, pageSize, unreadOnly } = query;
|
|
97
101
|
// `userId` is in the where clause, not applied afterwards. See the header.
|
|
102
|
+
// A dismissed row is "stop showing me this": never listed (issue #1077).
|
|
98
103
|
const where = {
|
|
99
104
|
userId,
|
|
105
|
+
dismissedAt: null,
|
|
100
106
|
...(unreadOnly ? { readAt: null } : {}),
|
|
101
107
|
};
|
|
102
108
|
const [items, total] = await this.prisma.$transaction([
|
|
@@ -130,7 +136,7 @@ let NotificationStoreService = class NotificationStoreService {
|
|
|
130
136
|
*/
|
|
131
137
|
async unreadCount(userId) {
|
|
132
138
|
return this.prisma.notification.count({
|
|
133
|
-
where: { userId, readAt: null },
|
|
139
|
+
where: { userId, readAt: null, dismissedAt: null },
|
|
134
140
|
});
|
|
135
141
|
}
|
|
136
142
|
/**
|
|
@@ -153,11 +159,19 @@ let NotificationStoreService = class NotificationStoreService {
|
|
|
153
159
|
* else. The two are deliberately indistinguishable.
|
|
154
160
|
*/
|
|
155
161
|
async markRead(userId, id) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
// Raw, for two reasons. `data.countAtRead` snapshots the count the user
|
|
163
|
+
// saw (the re-unread rule of a STATE row compares against it), which
|
|
164
|
+
// `updateMany` cannot do per row; and Prisma's `@updatedAt` would move
|
|
165
|
+
// `updated_at`, the rolling-window anchor of a COUNTED row, so merely
|
|
166
|
+
// reading a row would keep its window open.
|
|
167
|
+
const touched = await this.prisma.$executeRaw `
|
|
168
|
+
UPDATE notifications
|
|
169
|
+
SET read_at = now(),
|
|
170
|
+
data = CASE WHEN jsonb_typeof(data -> 'count') = 'number'
|
|
171
|
+
THEN jsonb_set(data, '{countAtRead}', data -> 'count')
|
|
172
|
+
ELSE data END
|
|
173
|
+
WHERE id = ${id}::uuid AND user_id = ${userId}::uuid AND read_at IS NULL`;
|
|
174
|
+
if (touched === 0) {
|
|
161
175
|
// Nothing was updated: either the notification is already read (fine,
|
|
162
176
|
// idempotent) or it is not this user's to touch. Distinguished by a
|
|
163
177
|
// second query that is ITSELF scoped to the user, so the answer never
|
|
@@ -187,10 +201,36 @@ let NotificationStoreService = class NotificationStoreService {
|
|
|
187
201
|
* be showing 1.
|
|
188
202
|
*/
|
|
189
203
|
async markAllRead(userId) {
|
|
190
|
-
await this.prisma
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
204
|
+
await this.prisma.$executeRaw `
|
|
205
|
+
UPDATE notifications
|
|
206
|
+
SET read_at = now(),
|
|
207
|
+
data = CASE WHEN jsonb_typeof(data -> 'count') = 'number'
|
|
208
|
+
THEN jsonb_set(data, '{countAtRead}', data -> 'count')
|
|
209
|
+
ELSE data END
|
|
210
|
+
WHERE user_id = ${userId}::uuid AND read_at IS NULL AND dismissed_at IS NULL`;
|
|
211
|
+
return this.unreadCount(userId);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Dismiss one notification ("stop showing me this") and report the badge.
|
|
215
|
+
*
|
|
216
|
+
* Dismissal implies read, so the row never lingers in the unread count. The
|
|
217
|
+
* row leaves the list; the retention sweep deletes it by age. Idempotent, and
|
|
218
|
+
* ownership-scoped exactly like {@link markRead}: another user's id is a 404.
|
|
219
|
+
*
|
|
220
|
+
* @throws NotFoundException when the id belongs to nobody, or to somebody else.
|
|
221
|
+
*/
|
|
222
|
+
async dismiss(userId, id) {
|
|
223
|
+
const touched = await this.prisma.$executeRaw `
|
|
224
|
+
UPDATE notifications
|
|
225
|
+
SET dismissed_at = now(),
|
|
226
|
+
read_at = COALESCE(read_at, now())
|
|
227
|
+
WHERE id = ${id}::uuid AND user_id = ${userId}::uuid AND dismissed_at IS NULL`;
|
|
228
|
+
if (touched === 0) {
|
|
229
|
+
const exists = await this.prisma.notification.count({ where: { id, userId } });
|
|
230
|
+
if (exists === 0) {
|
|
231
|
+
throw new common_1.NotFoundException('Notification not found');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
194
234
|
return this.unreadCount(userId);
|
|
195
235
|
}
|
|
196
236
|
};
|
|
@@ -209,6 +249,7 @@ exports.NotificationStoreService = NotificationStoreService = __decorate([
|
|
|
209
249
|
* into the list it fetched without a second mapping.
|
|
210
250
|
*/
|
|
211
251
|
function toResponse(row) {
|
|
252
|
+
const count = row.data?.count;
|
|
212
253
|
return {
|
|
213
254
|
id: row.id,
|
|
214
255
|
eventKey: row.eventKey,
|
|
@@ -217,6 +258,10 @@ function toResponse(row) {
|
|
|
217
258
|
link: row.link,
|
|
218
259
|
readAt: row.readAt ? row.readAt.toISOString() : null,
|
|
219
260
|
createdAt: row.createdAt.toISOString(),
|
|
261
|
+
count: typeof count === 'number' ? count : null,
|
|
262
|
+
scopeId: row.scopeId,
|
|
263
|
+
dismissedAt: row.dismissedAt ? row.dismissedAt.toISOString() : null,
|
|
264
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
220
265
|
};
|
|
221
266
|
}
|
|
222
267
|
//# sourceMappingURL=notification-store.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-store.service.js","sourceRoot":"","sources":["../../src/notifications/notification-store.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAuE;AAEvE,yCAAgD;AAQhD,gFAAgF;AAChF,wEAAwE;AACxE,0BAA0B;AAC1B,gFAAgF;AAChF,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,QAAQ;AACR,EAAE;AACF,gFAAgF;AAChF,mEAAmE;AACnE,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,UAAU;AACV,EAAE;AACF,8EAA8E;AAC9E,+DAA+D;AAC/D,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,+EAA+E;AAC/E,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAC7E,0EAA0E;AAC1E,uCAAuC;AACvC,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG;IAC1B,EAAE,EAAE,IAAI;IACR,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;CACP,CAAC;AAEX;;;;GAIG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;IACmB;IAAtD,YAAsD,MAA2B;QAA3B,WAAM,GAAN,MAAM,CAAqB;IAAG,CAAC;IAErF;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,IAAI,CACR,MAAc,EACd,KAA+B;QAE/B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;QAE7C,2EAA2E;QAC3E,MAAM,KAAK,GAAG;YACZ,MAAM;YACN,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC;QAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAO,IAAI,CAAC,MAAmD,CAAC,YAAY,CAAC;YAClG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;gBAChC,KAAK;gBACL,MAAM,EAAE,mBAAmB;gBAC3B,OAAO,EAAE,EAAE,SAAS,EAAE,MAAe,EAAE;gBACvC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ;gBAC3B,IAAI,EAAE,QAAQ;aACf,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC,CAAC;QAEH,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;YAC5B,KAAK;YACL,IAAI;YACJ,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;SACxC,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC;YACpC,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"notification-store.service.js","sourceRoot":"","sources":["../../src/notifications/notification-store.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -76,6 +76,14 @@ export interface NotificationStreamEvent {
|
|
|
76
76
|
* change what `toast` means.
|
|
77
77
|
*/
|
|
78
78
|
pushed: boolean;
|
|
79
|
+
/** The occurrence count of a STATE or COUNTED row (issue #1077); absent for a plain row. */
|
|
80
|
+
count?: number | null;
|
|
81
|
+
/** The scope of a STATE or COUNTED row, or null. */
|
|
82
|
+
scopeId?: string | null;
|
|
83
|
+
/** Last refresh (ISO 8601). */
|
|
84
|
+
updatedAt?: string;
|
|
85
|
+
/** Why the frame was sent; absent means `created`. */
|
|
86
|
+
reason?: 'created' | 'incremented' | 'reunread';
|
|
79
87
|
}
|
|
80
88
|
/**
|
|
81
89
|
* SSE `event:` name carrying a new notification.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-stream.service.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-stream.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAmB,MAAM,MAAM,CAAC;AAEnD,OAAO,EAEL,+BAA+B,EAE/B,KAAK,qBAAqB,EAE3B,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAmGnE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;;;;;;;;;;;OAYG;IACH,MAAM,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"notification-stream.service.d.ts","sourceRoot":"","sources":["../../src/notifications/notification-stream.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-stream.service.js","sourceRoot":"","sources":["../../src/notifications/notification-stream.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"notification-stream.service.js","sourceRoot":"","sources":["../../src/notifications/notification-stream.service.ts"],"names":[],"mappings":"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"}
|