applesauce-core 0.0.0-next-20250522030625 → 0.0.0-next-20250526151506
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/helpers/__tests__/exports.test.js +3 -0
- package/dist/helpers/__tests__/groups.test.js +61 -0
- package/dist/helpers/groups.d.ts +5 -0
- package/dist/helpers/groups.js +11 -1
- package/dist/helpers/url.d.ts +4 -0
- package/dist/helpers/url.js +20 -0
- package/package.json +1 -1
- package/dist/__tests__/index.test.js +0 -17
- package/dist/helpers/__tests__/index.test.d.ts +0 -1
- package/dist/helpers/__tests__/index.test.js +0 -220
- package/dist/observable/__tests__/listen-latest-updates.test.d.ts +0 -1
- package/dist/observable/__tests__/listen-latest-updates.test.js +0 -55
- package/dist/observable/listen-latest-updates.d.ts +0 -5
- package/dist/observable/listen-latest-updates.js +0 -12
- /package/dist/{__tests__/index.test.d.ts → helpers/__tests__/groups.test.d.ts} +0 -0
|
@@ -73,6 +73,8 @@ describe("exports", () => {
|
|
|
73
73
|
"decryptDirectMessage",
|
|
74
74
|
"encodeDecodeResult",
|
|
75
75
|
"encodeGroupPointer",
|
|
76
|
+
"ensureProtocol",
|
|
77
|
+
"ensureWebSocketURL",
|
|
76
78
|
"fakeVerifyEvent",
|
|
77
79
|
"getAddressPointerForEvent",
|
|
78
80
|
"getAddressPointerFromATag",
|
|
@@ -109,6 +111,7 @@ describe("exports", () => {
|
|
|
109
111
|
"getGiftWrapEvent",
|
|
110
112
|
"getGiftWrapSeal",
|
|
111
113
|
"getGroupPointerFromGroupTag",
|
|
114
|
+
"getGroupPointerFromHTag",
|
|
112
115
|
"getHandlerDescription",
|
|
113
116
|
"getHandlerLinkTemplate",
|
|
114
117
|
"getHandlerName",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { decodeGroupPointer, encodeGroupPointer } from "../groups.js";
|
|
3
|
+
describe("Group pointer utilities", () => {
|
|
4
|
+
describe("decodeGroupPointer", () => {
|
|
5
|
+
it("should decode a valid group pointer", () => {
|
|
6
|
+
const pointer = decodeGroupPointer("relay.example.com'group123");
|
|
7
|
+
expect(pointer).toEqual({
|
|
8
|
+
relay: "wss://relay.example.com",
|
|
9
|
+
id: "group123",
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
it("should add wss:// protocol if missing", () => {
|
|
13
|
+
const pointer = decodeGroupPointer("relay.example.com'group123");
|
|
14
|
+
expect(pointer.relay).toBe("wss://relay.example.com");
|
|
15
|
+
});
|
|
16
|
+
it("should preserve existing protocol if present", () => {
|
|
17
|
+
const pointer = decodeGroupPointer("wss://relay.example.com'group123");
|
|
18
|
+
expect(pointer.relay).toBe("wss://relay.example.com");
|
|
19
|
+
const wsPointer = decodeGroupPointer("ws://relay.example.com'group123");
|
|
20
|
+
expect(wsPointer.relay).toBe("ws://relay.example.com");
|
|
21
|
+
});
|
|
22
|
+
it("should handle default group id", () => {
|
|
23
|
+
const pointer = decodeGroupPointer("relay.example.com'");
|
|
24
|
+
expect(pointer).toEqual({
|
|
25
|
+
relay: "wss://relay.example.com",
|
|
26
|
+
id: "_",
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
it("should throw error if relay is missing", () => {
|
|
30
|
+
expect(() => decodeGroupPointer("'group123")).toThrow("Group pointer missing relay");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("encodeGroupPointer", () => {
|
|
34
|
+
it("should encode a valid group pointer", () => {
|
|
35
|
+
const pointer = {
|
|
36
|
+
relay: "wss://relay.example.com",
|
|
37
|
+
id: "group123",
|
|
38
|
+
};
|
|
39
|
+
expect(encodeGroupPointer(pointer)).toBe("relay.example.com'group123");
|
|
40
|
+
});
|
|
41
|
+
it("should strip protocol from relay", () => {
|
|
42
|
+
const pointer = {
|
|
43
|
+
relay: "wss://relay.example.com",
|
|
44
|
+
id: "group123",
|
|
45
|
+
};
|
|
46
|
+
expect(encodeGroupPointer(pointer)).toBe("relay.example.com'group123");
|
|
47
|
+
const wsPointer = {
|
|
48
|
+
relay: "ws://relay.example.com",
|
|
49
|
+
id: "group123",
|
|
50
|
+
};
|
|
51
|
+
expect(encodeGroupPointer(wsPointer)).toBe("relay.example.com'group123");
|
|
52
|
+
});
|
|
53
|
+
it("should handle invalid URLs by using the raw value", () => {
|
|
54
|
+
const pointer = {
|
|
55
|
+
relay: "invalid-url",
|
|
56
|
+
id: "group123",
|
|
57
|
+
};
|
|
58
|
+
expect(encodeGroupPointer(pointer)).toBe("invalid-url'group123");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
package/dist/helpers/groups.d.ts
CHANGED
|
@@ -3,8 +3,11 @@ export declare const GROUPS_LIST_KIND = 10009;
|
|
|
3
3
|
export declare const GROUP_MESSAGE_KIND = 9;
|
|
4
4
|
/** NIP-29 group pointer */
|
|
5
5
|
export type GroupPointer = {
|
|
6
|
+
/** the id of the group */
|
|
6
7
|
id: string;
|
|
8
|
+
/** The url to the relay with wss:// or ws:// protocol */
|
|
7
9
|
relay: string;
|
|
10
|
+
/** The name of the group */
|
|
8
11
|
name?: string;
|
|
9
12
|
};
|
|
10
13
|
/**
|
|
@@ -16,6 +19,8 @@ export declare function decodeGroupPointer(str: string): GroupPointer;
|
|
|
16
19
|
export declare function encodeGroupPointer(pointer: GroupPointer): string;
|
|
17
20
|
export declare const GroupsPublicSymbol: unique symbol;
|
|
18
21
|
export declare const GroupsHiddenSymbol: unique symbol;
|
|
22
|
+
/** gets a {@link GroupPointer} from a "h" tag if it has a relay hint */
|
|
23
|
+
export declare function getGroupPointerFromHTag(tag: string[]): GroupPointer | undefined;
|
|
19
24
|
/** gets a {@link GroupPointer} from a "group" tag */
|
|
20
25
|
export declare function getGroupPointerFromGroupTag(tag: string[]): GroupPointer;
|
|
21
26
|
/** Returns all the public groups from a k:10009 list */
|
package/dist/helpers/groups.js
CHANGED
|
@@ -8,9 +8,12 @@ export const GROUP_MESSAGE_KIND = 9;
|
|
|
8
8
|
* @throws
|
|
9
9
|
*/
|
|
10
10
|
export function decodeGroupPointer(str) {
|
|
11
|
-
|
|
11
|
+
let [relay, id] = str.split("'");
|
|
12
12
|
if (!relay)
|
|
13
13
|
throw new Error("Group pointer missing relay");
|
|
14
|
+
// Prepend wss:// if missing
|
|
15
|
+
if (!relay.match(/^wss?:/))
|
|
16
|
+
relay = `wss://${relay}`;
|
|
14
17
|
return { relay, id: id || "_" };
|
|
15
18
|
}
|
|
16
19
|
/** Converts a group pointer into a group identifier */
|
|
@@ -20,6 +23,13 @@ export function encodeGroupPointer(pointer) {
|
|
|
20
23
|
}
|
|
21
24
|
export const GroupsPublicSymbol = Symbol.for("groups-public");
|
|
22
25
|
export const GroupsHiddenSymbol = Symbol.for("groups-hidden");
|
|
26
|
+
/** gets a {@link GroupPointer} from a "h" tag if it has a relay hint */
|
|
27
|
+
export function getGroupPointerFromHTag(tag) {
|
|
28
|
+
const [_, id, relay] = tag;
|
|
29
|
+
if (!id || !relay)
|
|
30
|
+
return undefined;
|
|
31
|
+
return { id, relay };
|
|
32
|
+
}
|
|
23
33
|
/** gets a {@link GroupPointer} from a "group" tag */
|
|
24
34
|
export function getGroupPointerFromGroupTag(tag) {
|
|
25
35
|
const [_, id, relay, name] = tag;
|
package/dist/helpers/url.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ export declare function isStreamURL(url: string | URL): boolean;
|
|
|
14
14
|
export declare function isAudioURL(url: string | URL): boolean;
|
|
15
15
|
/** Tests if two URLs are the same */
|
|
16
16
|
export declare function isSameURL(a: string | URL, b: string | URL): boolean;
|
|
17
|
+
/** Adds a protocol to a URL string if its missing one */
|
|
18
|
+
export declare function ensureProtocol(url: string, protocol?: string): string;
|
|
19
|
+
/** Converts a URL to a WebSocket URL */
|
|
20
|
+
export declare function ensureWebSocketURL<T extends string | URL>(url: T): T;
|
|
17
21
|
/**
|
|
18
22
|
* Normalizes a string into a relay URL
|
|
19
23
|
* Does not remove the trailing slash
|
package/dist/helpers/url.js
CHANGED
|
@@ -39,6 +39,26 @@ export function isSameURL(a, b) {
|
|
|
39
39
|
return false;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
+
/** Adds a protocol to a URL string if its missing one */
|
|
43
|
+
export function ensureProtocol(url, protocol = "https:") {
|
|
44
|
+
// Check if the URL already has a protocol
|
|
45
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]+:/.test(url))
|
|
46
|
+
return url;
|
|
47
|
+
return protocol + "//" + url;
|
|
48
|
+
}
|
|
49
|
+
/** Converts a URL to a WebSocket URL */
|
|
50
|
+
export function ensureWebSocketURL(url) {
|
|
51
|
+
const p = typeof url === "string" ? new URL(ensureProtocol(url, "wss:")) : new URL(url);
|
|
52
|
+
if (p.protocol === "http:")
|
|
53
|
+
p.protocol = "ws:";
|
|
54
|
+
else if (p.protocol === "https:")
|
|
55
|
+
p.protocol = "wss:";
|
|
56
|
+
else
|
|
57
|
+
p.protocol = "wss:";
|
|
58
|
+
// return a string if a string was passed in
|
|
59
|
+
// @ts-expect-error
|
|
60
|
+
return typeof url === "string" ? p.toString() : p;
|
|
61
|
+
}
|
|
42
62
|
/**
|
|
43
63
|
* Normalizes a string into a relay URL
|
|
44
64
|
* Does not remove the trailing slash
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import * as core from "../index.js";
|
|
3
|
-
describe("core", () => {
|
|
4
|
-
it("should export the correct functions", () => {
|
|
5
|
-
expect(Object.keys(core).sort()).toMatchInlineSnapshot(`
|
|
6
|
-
[
|
|
7
|
-
"Database",
|
|
8
|
-
"EventStore",
|
|
9
|
-
"EventStoreSymbol",
|
|
10
|
-
"Helpers",
|
|
11
|
-
"Queries",
|
|
12
|
-
"QueryStore",
|
|
13
|
-
"logger",
|
|
14
|
-
]
|
|
15
|
-
`);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import * as helpers from "../index.js";
|
|
3
|
-
describe("helpers", () => {
|
|
4
|
-
it("should export the correct functions", () => {
|
|
5
|
-
expect(Object.keys(helpers).sort()).toMatchInlineSnapshot(`
|
|
6
|
-
[
|
|
7
|
-
"AUDIO_EXT",
|
|
8
|
-
"BLOSSOM_SERVER_LIST_KIND",
|
|
9
|
-
"BookmarkHiddenSymbol",
|
|
10
|
-
"BookmarkPublicSymbol",
|
|
11
|
-
"COMMENT_KIND",
|
|
12
|
-
"ChannelMetadataSymbol",
|
|
13
|
-
"CommentReplyPointerSymbol",
|
|
14
|
-
"CommentRootPointerSymbol",
|
|
15
|
-
"ContactsRelaysSymbol",
|
|
16
|
-
"EventContentEncryptionMethod",
|
|
17
|
-
"EventIndexableTagsSymbol",
|
|
18
|
-
"EventUIDSymbol",
|
|
19
|
-
"FAVORITE_RELAYS_KIND",
|
|
20
|
-
"FromCacheSymbol",
|
|
21
|
-
"GROUPS_LIST_KIND",
|
|
22
|
-
"GROUP_MESSAGE_KIND",
|
|
23
|
-
"GiftWrapEventSymbol",
|
|
24
|
-
"GiftWrapSealSymbol",
|
|
25
|
-
"GroupsHiddenSymbol",
|
|
26
|
-
"GroupsPublicSymbol",
|
|
27
|
-
"HiddenContactsSymbol",
|
|
28
|
-
"HiddenContentSymbol",
|
|
29
|
-
"HiddenTagsSymbol",
|
|
30
|
-
"IMAGE_EXT",
|
|
31
|
-
"LRU",
|
|
32
|
-
"MailboxesInboxesSymbol",
|
|
33
|
-
"MailboxesOutboxesSymbol",
|
|
34
|
-
"MediaAttachmentsSymbol",
|
|
35
|
-
"MuteHiddenSymbol",
|
|
36
|
-
"MutePublicSymbol",
|
|
37
|
-
"NIP05_REGEX",
|
|
38
|
-
"Nip10ThreadRefsSymbol",
|
|
39
|
-
"PICTURE_POST_KIND",
|
|
40
|
-
"ProfileContentSymbol",
|
|
41
|
-
"PublicContactsSymbol",
|
|
42
|
-
"ReplaceableIdentifierSymbol",
|
|
43
|
-
"STREAM_EXT",
|
|
44
|
-
"SeenRelaysSymbol",
|
|
45
|
-
"SharedEventSymbol",
|
|
46
|
-
"UserStatusPointerSymbol",
|
|
47
|
-
"VIDEO_EXT",
|
|
48
|
-
"ZapAddressPointerSymbol",
|
|
49
|
-
"ZapEventPointerSymbol",
|
|
50
|
-
"ZapFromSymbol",
|
|
51
|
-
"ZapInvoiceSymbol",
|
|
52
|
-
"ZapRequestSymbol",
|
|
53
|
-
"addSeenRelay",
|
|
54
|
-
"areBlossomServersEqual",
|
|
55
|
-
"canHaveHiddenContent",
|
|
56
|
-
"canHaveHiddenTags",
|
|
57
|
-
"convertToUrl",
|
|
58
|
-
"createMutedWordsRegExp",
|
|
59
|
-
"createReplaceableAddress",
|
|
60
|
-
"decodeGroupPointer",
|
|
61
|
-
"decodeLNURL",
|
|
62
|
-
"decryptDirectMessage",
|
|
63
|
-
"encodeDecodeResult",
|
|
64
|
-
"encodeGroupPointer",
|
|
65
|
-
"fakeVerifyEvent",
|
|
66
|
-
"getAddressPointerForEvent",
|
|
67
|
-
"getAddressPointerFromATag",
|
|
68
|
-
"getAddressPointersFromList",
|
|
69
|
-
"getBlossomServersFromList",
|
|
70
|
-
"getBookmarks",
|
|
71
|
-
"getCachedValue",
|
|
72
|
-
"getChannelMetadataContent",
|
|
73
|
-
"getChannelPointer",
|
|
74
|
-
"getCommentAddressPointer",
|
|
75
|
-
"getCommentEventPointer",
|
|
76
|
-
"getCommentExternalPointer",
|
|
77
|
-
"getCommentReplyPointer",
|
|
78
|
-
"getCommentRootPointer",
|
|
79
|
-
"getContacts",
|
|
80
|
-
"getContentWarning",
|
|
81
|
-
"getCoordinateFromAddressPointer",
|
|
82
|
-
"getDeleteCoordinates",
|
|
83
|
-
"getDeleteIds",
|
|
84
|
-
"getDisplayName",
|
|
85
|
-
"getEmojiTag",
|
|
86
|
-
"getEmojis",
|
|
87
|
-
"getEventPointerForEvent",
|
|
88
|
-
"getEventPointerFromETag",
|
|
89
|
-
"getEventPointerFromQTag",
|
|
90
|
-
"getEventPointerFromThreadTag",
|
|
91
|
-
"getEventPointersFromList",
|
|
92
|
-
"getEventUID",
|
|
93
|
-
"getExternalPointerFromTag",
|
|
94
|
-
"getFileMetadata",
|
|
95
|
-
"getFileMetadataFromImetaTag",
|
|
96
|
-
"getGiftWrapEvent",
|
|
97
|
-
"getGiftWrapSeal",
|
|
98
|
-
"getGroupPointerFromGroupTag",
|
|
99
|
-
"getHashtagTag",
|
|
100
|
-
"getHiddenBookmarks",
|
|
101
|
-
"getHiddenContacts",
|
|
102
|
-
"getHiddenContent",
|
|
103
|
-
"getHiddenContentEncryptionMethods",
|
|
104
|
-
"getHiddenGroups",
|
|
105
|
-
"getHiddenMutedThings",
|
|
106
|
-
"getHiddenTags",
|
|
107
|
-
"getHiddenTagsEncryptionMethods",
|
|
108
|
-
"getInboxes",
|
|
109
|
-
"getIndexableTags",
|
|
110
|
-
"getInvoice",
|
|
111
|
-
"getListTags",
|
|
112
|
-
"getMediaAttachments",
|
|
113
|
-
"getMutedThings",
|
|
114
|
-
"getNip10References",
|
|
115
|
-
"getOrComputeCachedValue",
|
|
116
|
-
"getOutboxes",
|
|
117
|
-
"getPackName",
|
|
118
|
-
"getParentEventStore",
|
|
119
|
-
"getPicturePostAttachments",
|
|
120
|
-
"getPointerForEvent",
|
|
121
|
-
"getPointerFromTag",
|
|
122
|
-
"getProfileContent",
|
|
123
|
-
"getProfilePointerFromPTag",
|
|
124
|
-
"getProfilePointersFromList",
|
|
125
|
-
"getPubkeyFromDecodeResult",
|
|
126
|
-
"getPublicBookmarks",
|
|
127
|
-
"getPublicContacts",
|
|
128
|
-
"getPublicGroups",
|
|
129
|
-
"getPublicMutedThings",
|
|
130
|
-
"getRelaysFromContactsEvent",
|
|
131
|
-
"getRelaysFromList",
|
|
132
|
-
"getReplaceableAddress",
|
|
133
|
-
"getReplaceableIdentifier",
|
|
134
|
-
"getReplaceableUID",
|
|
135
|
-
"getSeenRelays",
|
|
136
|
-
"getSha256FromURL",
|
|
137
|
-
"getTagValue",
|
|
138
|
-
"getURLFilename",
|
|
139
|
-
"getUserStatusPointer",
|
|
140
|
-
"getZapAddressPointer",
|
|
141
|
-
"getZapEventPointer",
|
|
142
|
-
"getZapPayment",
|
|
143
|
-
"getZapPreimage",
|
|
144
|
-
"getZapRecipient",
|
|
145
|
-
"getZapRequest",
|
|
146
|
-
"getZapSender",
|
|
147
|
-
"getZapSplits",
|
|
148
|
-
"hasHiddenContent",
|
|
149
|
-
"hasHiddenTags",
|
|
150
|
-
"interpretThreadTags",
|
|
151
|
-
"isATag",
|
|
152
|
-
"isAddressPointer",
|
|
153
|
-
"isAddressPointerInList",
|
|
154
|
-
"isAudioURL",
|
|
155
|
-
"isCommentAddressPointer",
|
|
156
|
-
"isCommentEventPointer",
|
|
157
|
-
"isDTag",
|
|
158
|
-
"isETag",
|
|
159
|
-
"isEvent",
|
|
160
|
-
"isEventPointer",
|
|
161
|
-
"isEventPointerInList",
|
|
162
|
-
"isFilterEqual",
|
|
163
|
-
"isFromCache",
|
|
164
|
-
"isGiftWrapLocked",
|
|
165
|
-
"isHex",
|
|
166
|
-
"isHexKey",
|
|
167
|
-
"isHiddenContentLocked",
|
|
168
|
-
"isHiddenTagsLocked",
|
|
169
|
-
"isImageURL",
|
|
170
|
-
"isNameValueTag",
|
|
171
|
-
"isNip05",
|
|
172
|
-
"isPTag",
|
|
173
|
-
"isProfilePointerInList",
|
|
174
|
-
"isRTag",
|
|
175
|
-
"isReplaceable",
|
|
176
|
-
"isSafeRelayURL",
|
|
177
|
-
"isSameURL",
|
|
178
|
-
"isSha256",
|
|
179
|
-
"isStreamURL",
|
|
180
|
-
"isTTag",
|
|
181
|
-
"isValidList",
|
|
182
|
-
"isValidProfile",
|
|
183
|
-
"isValidZap",
|
|
184
|
-
"isVideoURL",
|
|
185
|
-
"lockHiddenContent",
|
|
186
|
-
"lockHiddenTags",
|
|
187
|
-
"markFromCache",
|
|
188
|
-
"matchFilter",
|
|
189
|
-
"matchFilters",
|
|
190
|
-
"matchMutes",
|
|
191
|
-
"mergeBlossomServers",
|
|
192
|
-
"mergeBookmarks",
|
|
193
|
-
"mergeContacts",
|
|
194
|
-
"mergeFilters",
|
|
195
|
-
"mergeMutes",
|
|
196
|
-
"mergeRelaySets",
|
|
197
|
-
"normalizeURL",
|
|
198
|
-
"parseBolt11",
|
|
199
|
-
"parseBookmarkTags",
|
|
200
|
-
"parseCoordinate",
|
|
201
|
-
"parseExternalPointer",
|
|
202
|
-
"parseFileMetadataTags",
|
|
203
|
-
"parseLNURLOrAddress",
|
|
204
|
-
"parseLightningAddress",
|
|
205
|
-
"parseMutedTags",
|
|
206
|
-
"parseNIP05Address",
|
|
207
|
-
"parseSharedEvent",
|
|
208
|
-
"processTags",
|
|
209
|
-
"safeParse",
|
|
210
|
-
"setCachedValue",
|
|
211
|
-
"setEventContentEncryptionMethod",
|
|
212
|
-
"stripInvisibleChar",
|
|
213
|
-
"unixNow",
|
|
214
|
-
"unlockGiftWrap",
|
|
215
|
-
"unlockHiddenContent",
|
|
216
|
-
"unlockHiddenTags",
|
|
217
|
-
]
|
|
218
|
-
`);
|
|
219
|
-
});
|
|
220
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it } from "vitest";
|
|
2
|
-
import { subscribeSpyTo } from "@hirez_io/observer-spy";
|
|
3
|
-
import { of } from "rxjs";
|
|
4
|
-
import { EventStore } from "../../event-store/event-store.js";
|
|
5
|
-
import { listenLatestUpdates } from "../listen-latest-updates.js";
|
|
6
|
-
import { FakeUser } from "../../__tests__/fixtures.js";
|
|
7
|
-
let eventStore;
|
|
8
|
-
let user;
|
|
9
|
-
let event;
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
eventStore = new EventStore();
|
|
12
|
-
user = new FakeUser();
|
|
13
|
-
event = user.note("original content");
|
|
14
|
-
});
|
|
15
|
-
describe("listenLatestUpdates", () => {
|
|
16
|
-
it("should emit the initial event", () => {
|
|
17
|
-
const source = of(event);
|
|
18
|
-
const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
|
|
19
|
-
expect(spy.getValues()).toEqual([event]);
|
|
20
|
-
});
|
|
21
|
-
it("should emit the event again when it's updated in the event store", () => {
|
|
22
|
-
// Add the event to the store first
|
|
23
|
-
eventStore.add(event);
|
|
24
|
-
// Create a source that emits the event
|
|
25
|
-
const source = of(event);
|
|
26
|
-
const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
|
|
27
|
-
// Create an updated version of the event
|
|
28
|
-
Reflect.set(event, Symbol.for("new-prop"), "testing");
|
|
29
|
-
// Update the event in the store
|
|
30
|
-
eventStore.update(event);
|
|
31
|
-
// Should have received both the original and updated event
|
|
32
|
-
expect(spy.getValues()).toEqual([event, event]);
|
|
33
|
-
});
|
|
34
|
-
it("should not emit updates for other events", () => {
|
|
35
|
-
// Add the event to the store
|
|
36
|
-
eventStore.add(event);
|
|
37
|
-
// Create a source that emits the event
|
|
38
|
-
const source = of(event);
|
|
39
|
-
const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
|
|
40
|
-
// Create a different event
|
|
41
|
-
const otherEvent = user.note("other content");
|
|
42
|
-
// Add the other event to the store
|
|
43
|
-
eventStore.add(otherEvent);
|
|
44
|
-
// Should only have received the original event
|
|
45
|
-
expect(spy.getValues()).toEqual([event]);
|
|
46
|
-
});
|
|
47
|
-
it("should handle undefined initial event", () => {
|
|
48
|
-
const source = of(undefined);
|
|
49
|
-
const spy = subscribeSpyTo(source.pipe(listenLatestUpdates(eventStore)));
|
|
50
|
-
expect(spy.getValues()).toEqual([undefined]);
|
|
51
|
-
// Adding events to the store should not trigger emissions
|
|
52
|
-
eventStore.add(event);
|
|
53
|
-
expect(spy.getValues()).toEqual([undefined]);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { MonoTypeOperatorFunction } from "rxjs";
|
|
3
|
-
import { IStreamEventStore } from "../event-store/interface.js";
|
|
4
|
-
/** Lists for any updates to the latest event and remits it */
|
|
5
|
-
export declare function listenLatestUpdates(eventStore: IStreamEventStore): MonoTypeOperatorFunction<NostrEvent | undefined>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { filter, merge, tap } from "rxjs";
|
|
2
|
-
/** Lists for any updates to the latest event and remits it */
|
|
3
|
-
export function listenLatestUpdates(eventStore) {
|
|
4
|
-
return (source) => {
|
|
5
|
-
let latest;
|
|
6
|
-
return merge(
|
|
7
|
-
// Get the latest event
|
|
8
|
-
source.pipe(tap((value) => (latest = value))),
|
|
9
|
-
// listen for updates
|
|
10
|
-
eventStore.updates.pipe(filter((e) => e.id === latest?.id)));
|
|
11
|
-
};
|
|
12
|
-
}
|
|
File without changes
|