applesauce-core 0.0.0-next-20241128172721 → 0.0.0-next-20241204152949
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/pointers.d.ts +9 -0
- package/dist/helpers/pointers.js +41 -1
- package/package.json +1 -1
- package/dist/helpers/channel.d.ts +0 -15
- package/dist/helpers/channel.js +0 -27
- package/dist/helpers/mute.d.ts +0 -21
- package/dist/helpers/mute.js +0 -52
- package/dist/helpers/symbols.d.ts +0 -6
- package/dist/helpers/symbols.js +0 -2
- package/dist/helpers/user-status.d.ts +0 -22
- package/dist/helpers/user-status.js +0 -24
- package/dist/observable/getValue.d.ts +0 -2
- package/dist/observable/getValue.js +0 -13
- package/dist/observable/stateful.d.ts +0 -10
- package/dist/observable/stateful.js +0 -60
- package/dist/observable/throttle.d.ts +0 -3
- package/dist/observable/throttle.js +0 -23
- package/dist/queries/channel.d.ts +0 -11
- package/dist/queries/channel.js +0 -72
- package/dist/queries/mute.d.ts +0 -7
- package/dist/queries/mute.js +0 -16
- package/dist/queries/user-status.d.ts +0 -11
- package/dist/queries/user-status.js +0 -35
- package/dist/query-store/queries/TimelineQuery.d.ts +0 -1
- package/dist/query-store/queries/TimelineQuery.js +0 -1
- package/dist/query-store/queries/channel.d.ts +0 -11
- package/dist/query-store/queries/channel.js +0 -72
- package/dist/query-store/queries/index.d.ts +0 -7
- package/dist/query-store/queries/index.js +0 -7
- package/dist/query-store/queries/mailboxes.d.ts +0 -5
- package/dist/query-store/queries/mailboxes.js +0 -11
- package/dist/query-store/queries/mute.d.ts +0 -7
- package/dist/query-store/queries/mute.js +0 -16
- package/dist/query-store/queries/profile.d.ts +0 -3
- package/dist/query-store/queries/profile.js +0 -10
- package/dist/query-store/queries/reactions.d.ts +0 -4
- package/dist/query-store/queries/reactions.js +0 -19
- package/dist/query-store/queries/simple.d.ts +0 -5
- package/dist/query-store/queries/simple.js +0 -20
- package/dist/query-store/queries/thread.d.ts +0 -20
- package/dist/query-store/queries/thread.js +0 -60
- package/dist/query-store/queries/timeline.d.ts +0 -3
- package/dist/query-store/queries/timeline.js +0 -3
- package/dist/utils/lru.d.ts +0 -32
- package/dist/utils/lru.js +0 -148
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { AddressPointer, DecodeResult, EventPointer, ProfilePointer } from "nostr-tools/nip19";
|
|
2
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
3
|
export type AddressPointerWithoutD = Omit<AddressPointer, "identifier"> & {
|
|
3
4
|
identifier?: string;
|
|
4
5
|
};
|
|
6
|
+
/** Parse the value of an "a" tag into an AddressPointer */
|
|
5
7
|
export declare function parseCoordinate(a: string): AddressPointerWithoutD | null;
|
|
6
8
|
export declare function parseCoordinate(a: string, requireD: false): AddressPointerWithoutD | null;
|
|
7
9
|
export declare function parseCoordinate(a: string, requireD: true): AddressPointer | null;
|
|
@@ -9,14 +11,21 @@ export declare function parseCoordinate(a: string, requireD: false, silent: fals
|
|
|
9
11
|
export declare function parseCoordinate(a: string, requireD: true, silent: false): AddressPointer;
|
|
10
12
|
export declare function parseCoordinate(a: string, requireD: true, silent: true): AddressPointer | null;
|
|
11
13
|
export declare function parseCoordinate(a: string, requireD: false, silent: true): AddressPointerWithoutD | null;
|
|
14
|
+
/** Extra a pubkey from the result of nip19.decode */
|
|
12
15
|
export declare function getPubkeyFromDecodeResult(result?: DecodeResult): string | undefined;
|
|
16
|
+
/** Encodes the result of nip19.decode */
|
|
13
17
|
export declare function encodeDecodeResult(result: DecodeResult): "" | `nprofile1${string}` | `nevent1${string}` | `naddr1${string}` | `nsec1${string}` | `npub1${string}` | `note1${string}`;
|
|
14
18
|
export declare function getEventPointerFromTag(tag: string[]): EventPointer;
|
|
15
19
|
export declare function getAddressPointerFromTag(tag: string[]): AddressPointer;
|
|
16
20
|
export declare function getProfilePointerFromTag(tag: string[]): ProfilePointer;
|
|
21
|
+
/** Parses a tag into a pointer */
|
|
17
22
|
export declare function getPointerFromTag(tag: string[]): DecodeResult | null;
|
|
18
23
|
export declare function isAddressPointer(pointer: DecodeResult["data"]): pointer is AddressPointer;
|
|
19
24
|
export declare function isEventPointer(pointer: DecodeResult["data"]): pointer is EventPointer;
|
|
20
25
|
export declare function getCoordinateFromAddressPointer(pointer: AddressPointer): string;
|
|
26
|
+
/** Returns a tag for an address pointer */
|
|
21
27
|
export declare function getATagFromAddressPointer(pointer: AddressPointer): ["a", ...string[]];
|
|
28
|
+
/** Returns a tag for an event pointer */
|
|
22
29
|
export declare function getETagFromEventPointer(pointer: EventPointer): ["e", ...string[]];
|
|
30
|
+
/** Returns a pointer for a given event */
|
|
31
|
+
export declare function getPointerForEvent(event: NostrEvent, relays?: string[]): DecodeResult;
|
package/dist/helpers/pointers.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode, } from "nostr-tools/nip19";
|
|
2
|
-
import { getPublicKey } from "nostr-tools";
|
|
2
|
+
import { getPublicKey, kinds } from "nostr-tools";
|
|
3
3
|
import { safeRelayUrls } from "./relays.js";
|
|
4
|
+
import { getTagValue } from "./index.js";
|
|
4
5
|
export function parseCoordinate(a, requireD = false, silent = true) {
|
|
5
6
|
const parts = a.split(":");
|
|
6
7
|
const kind = parts[0] && parseInt(parts[0]);
|
|
@@ -30,6 +31,7 @@ export function parseCoordinate(a, requireD = false, silent = true) {
|
|
|
30
31
|
identifier: d,
|
|
31
32
|
};
|
|
32
33
|
}
|
|
34
|
+
/** Extra a pubkey from the result of nip19.decode */
|
|
33
35
|
export function getPubkeyFromDecodeResult(result) {
|
|
34
36
|
if (!result)
|
|
35
37
|
return;
|
|
@@ -45,6 +47,7 @@ export function getPubkeyFromDecodeResult(result) {
|
|
|
45
47
|
return undefined;
|
|
46
48
|
}
|
|
47
49
|
}
|
|
50
|
+
/** Encodes the result of nip19.decode */
|
|
48
51
|
export function encodeDecodeResult(result) {
|
|
49
52
|
switch (result.type) {
|
|
50
53
|
case "naddr":
|
|
@@ -68,6 +71,9 @@ export function getEventPointerFromTag(tag) {
|
|
|
68
71
|
let pointer = { id: tag[1] };
|
|
69
72
|
if (tag[2])
|
|
70
73
|
pointer.relays = safeRelayUrls([tag[2]]);
|
|
74
|
+
// get author from NIP-18 quote tags
|
|
75
|
+
if (tag[0] === "q" && tag[3] && tag[3].length === 64)
|
|
76
|
+
pointer.author = tag[3];
|
|
71
77
|
return pointer;
|
|
72
78
|
}
|
|
73
79
|
export function getAddressPointerFromTag(tag) {
|
|
@@ -86,6 +92,7 @@ export function getProfilePointerFromTag(tag) {
|
|
|
86
92
|
pointer.relays = safeRelayUrls([tag[2]]);
|
|
87
93
|
return pointer;
|
|
88
94
|
}
|
|
95
|
+
/** Parses a tag into a pointer */
|
|
89
96
|
export function getPointerFromTag(tag) {
|
|
90
97
|
try {
|
|
91
98
|
switch (tag[0]) {
|
|
@@ -98,6 +105,9 @@ export function getPointerFromTag(tag) {
|
|
|
98
105
|
};
|
|
99
106
|
case "p":
|
|
100
107
|
return { type: "nprofile", data: getProfilePointerFromTag(tag) };
|
|
108
|
+
// NIP-18 quote tags
|
|
109
|
+
case "q":
|
|
110
|
+
return { type: "nevent", data: getEventPointerFromTag(tag) };
|
|
101
111
|
}
|
|
102
112
|
}
|
|
103
113
|
catch (error) { }
|
|
@@ -115,11 +125,41 @@ export function isEventPointer(pointer) {
|
|
|
115
125
|
export function getCoordinateFromAddressPointer(pointer) {
|
|
116
126
|
return `${pointer.kind}:${pointer.pubkey}:${pointer.identifier}`;
|
|
117
127
|
}
|
|
128
|
+
/** Returns a tag for an address pointer */
|
|
118
129
|
export function getATagFromAddressPointer(pointer) {
|
|
119
130
|
const relay = pointer.relays?.[0];
|
|
120
131
|
const coordinate = getCoordinateFromAddressPointer(pointer);
|
|
121
132
|
return relay ? ["a", coordinate, relay] : ["a", coordinate];
|
|
122
133
|
}
|
|
134
|
+
/** Returns a tag for an event pointer */
|
|
123
135
|
export function getETagFromEventPointer(pointer) {
|
|
124
136
|
return pointer.relays?.length ? ["e", pointer.id, pointer.relays[0]] : ["e", pointer.id];
|
|
125
137
|
}
|
|
138
|
+
/** Returns a pointer for a given event */
|
|
139
|
+
export function getPointerForEvent(event, relays) {
|
|
140
|
+
if (kinds.isParameterizedReplaceableKind(event.kind)) {
|
|
141
|
+
const d = getTagValue(event, "d");
|
|
142
|
+
if (!d)
|
|
143
|
+
throw new Error("Event missing identifier");
|
|
144
|
+
return {
|
|
145
|
+
type: "naddr",
|
|
146
|
+
data: {
|
|
147
|
+
identifier: d,
|
|
148
|
+
kind: event.kind,
|
|
149
|
+
pubkey: event.pubkey,
|
|
150
|
+
relays,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return {
|
|
156
|
+
type: "nevent",
|
|
157
|
+
data: {
|
|
158
|
+
id: event.id,
|
|
159
|
+
kind: event.kind,
|
|
160
|
+
author: event.pubkey,
|
|
161
|
+
relays,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { nip19, NostrEvent } from "nostr-tools";
|
|
2
|
-
import { ChannelMetadata } from "nostr-tools/nip28";
|
|
3
|
-
export declare const ChannelMetadataSymbol: unique symbol;
|
|
4
|
-
declare module "nostr-tools" {
|
|
5
|
-
interface Event {
|
|
6
|
-
[ChannelMetadataSymbol]?: ChannelMetadataContent;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export type ChannelMetadataContent = ChannelMetadata & {
|
|
10
|
-
relays?: string[];
|
|
11
|
-
};
|
|
12
|
-
/** Gets the parsed metadata on a channel creation or channel metadata event */
|
|
13
|
-
export declare function getChannelMetadataContent(channel: NostrEvent): ChannelMetadataContent;
|
|
14
|
-
/** gets the EventPointer for a channel message or metadata event */
|
|
15
|
-
export declare function getChannelPointer(event: NostrEvent): nip19.EventPointer | undefined;
|
package/dist/helpers/channel.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export const ChannelMetadataSymbol = Symbol.for("channel-metadata");
|
|
2
|
-
function parseChannelMetadataContent(channel) {
|
|
3
|
-
const metadata = JSON.parse(channel.content);
|
|
4
|
-
if (metadata.name === undefined)
|
|
5
|
-
throw new Error("Missing name");
|
|
6
|
-
if (metadata.about === undefined)
|
|
7
|
-
throw new Error("Missing about");
|
|
8
|
-
if (metadata.picture === undefined)
|
|
9
|
-
throw new Error("Missing picture");
|
|
10
|
-
if (metadata.relays && !Array.isArray(metadata.relays))
|
|
11
|
-
throw new Error("Invalid relays");
|
|
12
|
-
return metadata;
|
|
13
|
-
}
|
|
14
|
-
/** Gets the parsed metadata on a channel creation or channel metadata event */
|
|
15
|
-
export function getChannelMetadataContent(channel) {
|
|
16
|
-
let metadata = channel[ChannelMetadataSymbol];
|
|
17
|
-
if (!metadata)
|
|
18
|
-
metadata = channel[ChannelMetadataSymbol] = parseChannelMetadataContent(channel);
|
|
19
|
-
return metadata;
|
|
20
|
-
}
|
|
21
|
-
/** gets the EventPointer for a channel message or metadata event */
|
|
22
|
-
export function getChannelPointer(event) {
|
|
23
|
-
const tag = event.tags.find((t) => t[0] === "e" && t[1]);
|
|
24
|
-
if (!tag)
|
|
25
|
-
return undefined;
|
|
26
|
-
return tag[2] ? { id: tag[1], relays: [tag[2]] } : { id: tag[1] };
|
|
27
|
-
}
|
package/dist/helpers/mute.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
export declare const MutePubkeysSymbol: unique symbol;
|
|
3
|
-
export declare const MuteThreadsSymbol: unique symbol;
|
|
4
|
-
export declare const MuteHashtagsSymbol: unique symbol;
|
|
5
|
-
export declare const MuteWordsSymbol: unique symbol;
|
|
6
|
-
declare module "nostr-tools" {
|
|
7
|
-
interface Event {
|
|
8
|
-
[MutePubkeysSymbol]?: Set<string>;
|
|
9
|
-
[MuteThreadsSymbol]?: Set<string>;
|
|
10
|
-
[MuteHashtagsSymbol]?: Set<string>;
|
|
11
|
-
[MuteWordsSymbol]?: Set<string>;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/** Returns a set of muted pubkeys */
|
|
15
|
-
export declare function getMutedPubkeys(mute: NostrEvent): Set<string>;
|
|
16
|
-
/** Returns a set of muted threads */
|
|
17
|
-
export declare function getMutedThreads(mute: NostrEvent): Set<string>;
|
|
18
|
-
/** Returns a set of muted words ( lowercase ) */
|
|
19
|
-
export declare function getMutedWords(mute: NostrEvent): Set<string>;
|
|
20
|
-
/** Returns a set of muted hashtags ( lowercase ) */
|
|
21
|
-
export declare function getMutedHashtags(mute: NostrEvent): Set<string>;
|
package/dist/helpers/mute.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export const MutePubkeysSymbol = Symbol.for("mute-pubkeys");
|
|
2
|
-
export const MuteThreadsSymbol = Symbol.for("mute-threads");
|
|
3
|
-
export const MuteHashtagsSymbol = Symbol.for("mute-hashtags");
|
|
4
|
-
export const MuteWordsSymbol = Symbol.for("mute-words");
|
|
5
|
-
/** Returns a set of muted pubkeys */
|
|
6
|
-
export function getMutedPubkeys(mute) {
|
|
7
|
-
let pubkeys = mute[MutePubkeysSymbol];
|
|
8
|
-
if (!pubkeys) {
|
|
9
|
-
pubkeys = mute[MutePubkeysSymbol] = new Set();
|
|
10
|
-
for (const tag of mute.tags) {
|
|
11
|
-
if (tag[0] === "p" && tag[1])
|
|
12
|
-
pubkeys.add(tag[1]);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return pubkeys;
|
|
16
|
-
}
|
|
17
|
-
/** Returns a set of muted threads */
|
|
18
|
-
export function getMutedThreads(mute) {
|
|
19
|
-
let threads = mute[MuteThreadsSymbol];
|
|
20
|
-
if (!threads) {
|
|
21
|
-
threads = mute[MuteThreadsSymbol] = new Set();
|
|
22
|
-
for (const tag of mute.tags) {
|
|
23
|
-
if (tag[0] === "e" && tag[1])
|
|
24
|
-
threads.add(tag[1]);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return threads;
|
|
28
|
-
}
|
|
29
|
-
/** Returns a set of muted words ( lowercase ) */
|
|
30
|
-
export function getMutedWords(mute) {
|
|
31
|
-
let words = mute[MuteWordsSymbol];
|
|
32
|
-
if (!words) {
|
|
33
|
-
words = mute[MuteWordsSymbol] = new Set();
|
|
34
|
-
for (const tag of mute.tags) {
|
|
35
|
-
if (tag[0] === "word" && tag[1])
|
|
36
|
-
words.add(tag[1].toLocaleLowerCase());
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return words;
|
|
40
|
-
}
|
|
41
|
-
/** Returns a set of muted hashtags ( lowercase ) */
|
|
42
|
-
export function getMutedHashtags(mute) {
|
|
43
|
-
let hashtags = mute[MuteHashtagsSymbol];
|
|
44
|
-
if (!hashtags) {
|
|
45
|
-
hashtags = mute[MuteHashtagsSymbol] = new Set();
|
|
46
|
-
for (const tag of mute.tags) {
|
|
47
|
-
if (tag[0] === "t" && tag[1])
|
|
48
|
-
hashtags.add(tag[1].toLocaleLowerCase());
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return hashtags;
|
|
52
|
-
}
|
package/dist/helpers/symbols.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { AddressPointer, EventPointer, ProfilePointer } from "nostr-tools/nip19";
|
|
3
|
-
export declare const UserStatusPointerSymbol: unique symbol;
|
|
4
|
-
declare module "nostr-tools" {
|
|
5
|
-
interface Event {
|
|
6
|
-
[UserStatusPointerSymbol]?: UserStatusPointer | null;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export type UserStatusPointer = {
|
|
10
|
-
type: "nevent";
|
|
11
|
-
data: EventPointer;
|
|
12
|
-
} | {
|
|
13
|
-
type: "nprofile";
|
|
14
|
-
data: ProfilePointer;
|
|
15
|
-
} | {
|
|
16
|
-
type: "naddr";
|
|
17
|
-
data: AddressPointer;
|
|
18
|
-
} | {
|
|
19
|
-
type: "url";
|
|
20
|
-
data: string;
|
|
21
|
-
};
|
|
22
|
-
export declare function getUserStatusPointer(status: NostrEvent): UserStatusPointer | null;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { getAddressPointerFromTag, getEventPointerFromTag, getProfilePointerFromTag } from "./pointers.js";
|
|
2
|
-
export const UserStatusPointerSymbol = Symbol.for("user-status-pointer");
|
|
3
|
-
function getStatusPointer(status) {
|
|
4
|
-
const pTag = status.tags.find((t) => t[0] === "p" && t[1]);
|
|
5
|
-
if (pTag)
|
|
6
|
-
return { type: "nprofile", data: getProfilePointerFromTag(pTag) };
|
|
7
|
-
const eTag = status.tags.find((t) => t[0] === "e" && t[1]);
|
|
8
|
-
if (eTag)
|
|
9
|
-
return { type: "nevent", data: getEventPointerFromTag(eTag) };
|
|
10
|
-
const aTag = status.tags.find((t) => t[0] === "a" && t[1]);
|
|
11
|
-
if (aTag)
|
|
12
|
-
return { type: "naddr", data: getAddressPointerFromTag(aTag) };
|
|
13
|
-
const rTag = status.tags.find((t) => t[0] === "r" && t[1]);
|
|
14
|
-
if (rTag)
|
|
15
|
-
return { type: "url", data: rTag[1] };
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
export function getUserStatusPointer(status) {
|
|
19
|
-
let pointer = status[UserStatusPointerSymbol];
|
|
20
|
-
if (pointer === undefined) {
|
|
21
|
-
pointer = status[UserStatusPointerSymbol] = getStatusPointer(status);
|
|
22
|
-
}
|
|
23
|
-
return pointer;
|
|
24
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { BehaviorSubject } from "rxjs";
|
|
2
|
-
export function getValue(observable) {
|
|
3
|
-
if (observable instanceof BehaviorSubject)
|
|
4
|
-
return observable.value;
|
|
5
|
-
if (Reflect.has(observable, "value"))
|
|
6
|
-
return Reflect.get(observable, "value");
|
|
7
|
-
return new Promise((res) => {
|
|
8
|
-
const sub = observable.subscribe((v) => {
|
|
9
|
-
res(v);
|
|
10
|
-
sub.unsubscribe();
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import Observable from "zen-observable";
|
|
2
|
-
export type StatefulObservable<T> = Observable<T> & {
|
|
3
|
-
_stateful?: true;
|
|
4
|
-
value?: T;
|
|
5
|
-
error?: Error;
|
|
6
|
-
complete?: boolean;
|
|
7
|
-
};
|
|
8
|
-
/** Wraps an {@link Observable} and makes it stateful */
|
|
9
|
-
export declare function stateful<T extends unknown>(observable: Observable<T>, cleanup?: boolean): StatefulObservable<T>;
|
|
10
|
-
export declare function isStateful<T extends unknown>(observable: Observable<T> | StatefulObservable<T>): observable is StatefulObservable<T>;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import Observable from "zen-observable";
|
|
2
|
-
/** Wraps an {@link Observable} and makes it stateful */
|
|
3
|
-
export function stateful(observable, cleanup = false) {
|
|
4
|
-
let subscription = undefined;
|
|
5
|
-
let observers = [];
|
|
6
|
-
const self = new Observable((observer) => {
|
|
7
|
-
// add observer to list
|
|
8
|
-
observers.push(observer);
|
|
9
|
-
// pass any cached values
|
|
10
|
-
if (self.value)
|
|
11
|
-
observer.next(self.value);
|
|
12
|
-
if (self.error)
|
|
13
|
-
observer.error(self.error);
|
|
14
|
-
if (self.complete)
|
|
15
|
-
observer.complete();
|
|
16
|
-
// subscribe if not already
|
|
17
|
-
if (!subscription) {
|
|
18
|
-
subscription = observable.subscribe({
|
|
19
|
-
next: (v) => {
|
|
20
|
-
self.value = v;
|
|
21
|
-
for (const observer of observers)
|
|
22
|
-
observer.next(v);
|
|
23
|
-
},
|
|
24
|
-
error: (err) => {
|
|
25
|
-
self.error = err;
|
|
26
|
-
for (const observer of observers)
|
|
27
|
-
observer.error(err);
|
|
28
|
-
},
|
|
29
|
-
complete: () => {
|
|
30
|
-
self.complete = true;
|
|
31
|
-
for (const observer of observers)
|
|
32
|
-
observer.complete();
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
return () => {
|
|
37
|
-
let i = observers.indexOf(observer);
|
|
38
|
-
if (i !== -1) {
|
|
39
|
-
// remove observer from list
|
|
40
|
-
observers.splice(i, 1);
|
|
41
|
-
if (subscription && observers.length === 0) {
|
|
42
|
-
subscription.unsubscribe();
|
|
43
|
-
subscription = undefined;
|
|
44
|
-
// reset cached values
|
|
45
|
-
if (cleanup) {
|
|
46
|
-
delete self.value;
|
|
47
|
-
delete self.error;
|
|
48
|
-
delete self.complete;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
});
|
|
54
|
-
self._stateful = true;
|
|
55
|
-
return self;
|
|
56
|
-
}
|
|
57
|
-
export function isStateful(observable) {
|
|
58
|
-
// @ts-expect-error
|
|
59
|
-
return observable._stateful;
|
|
60
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import Observable from "zen-observable";
|
|
2
|
-
/** Throttles an {@link Observable} */
|
|
3
|
-
export function throttle(source, interval) {
|
|
4
|
-
return new Observable((observer) => {
|
|
5
|
-
let lastEmissionTime = 0;
|
|
6
|
-
let subscription = source.subscribe({
|
|
7
|
-
next(value) {
|
|
8
|
-
const currentTime = Date.now();
|
|
9
|
-
if (currentTime - lastEmissionTime >= interval) {
|
|
10
|
-
lastEmissionTime = currentTime;
|
|
11
|
-
observer.next(value);
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
error(err) {
|
|
15
|
-
observer.error(err);
|
|
16
|
-
},
|
|
17
|
-
complete() {
|
|
18
|
-
observer.complete();
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
return () => subscription.unsubscribe();
|
|
22
|
-
});
|
|
23
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { Query } from "../query-store/index.js";
|
|
3
|
-
import { ChannelMetadataContent } from "../helpers/channel.js";
|
|
4
|
-
/** Creates a query that returns the latest parsed metadata */
|
|
5
|
-
export declare function ChannelMetadataQuery(channel: NostrEvent): Query<ChannelMetadataContent | undefined>;
|
|
6
|
-
/** Creates a query that returns a map of hidden messages Map<id, reason> */
|
|
7
|
-
export declare function ChannelHiddenQuery(channel: NostrEvent, authors?: string[]): Query<Map<string, string>>;
|
|
8
|
-
/** Creates a query that returns a map of muted users Map<pubkey, reason> */
|
|
9
|
-
export declare function ChannelMutedQuery(channel: NostrEvent, authors?: string[]): Query<Map<string, string>>;
|
|
10
|
-
/** Creates a query that returns all messages in a channel */
|
|
11
|
-
export declare function ChannelMessagesQuery(channel: NostrEvent): Query<NostrEvent[]>;
|
package/dist/queries/channel.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getChannelMetadataContent } from "../helpers/channel.js";
|
|
3
|
-
import { safeParse } from "../helpers/json.js";
|
|
4
|
-
/** Creates a query that returns the latest parsed metadata */
|
|
5
|
-
export function ChannelMetadataQuery(channel) {
|
|
6
|
-
return {
|
|
7
|
-
key: channel.id,
|
|
8
|
-
run: (events) => {
|
|
9
|
-
const filters = [
|
|
10
|
-
{ ids: [channel.id] },
|
|
11
|
-
{ kinds: [kinds.ChannelMetadata], "#e": [channel.id], authors: [channel.pubkey] },
|
|
12
|
-
];
|
|
13
|
-
let latest = channel;
|
|
14
|
-
return events.stream(filters).map((event) => {
|
|
15
|
-
try {
|
|
16
|
-
if (event.pubkey === latest.pubkey && event.created_at > latest.created_at) {
|
|
17
|
-
latest = event;
|
|
18
|
-
}
|
|
19
|
-
return getChannelMetadataContent(latest);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
/** Creates a query that returns a map of hidden messages Map<id, reason> */
|
|
29
|
-
export function ChannelHiddenQuery(channel, authors = []) {
|
|
30
|
-
return {
|
|
31
|
-
key: channel.id,
|
|
32
|
-
run: (events) => {
|
|
33
|
-
const hidden = new Map();
|
|
34
|
-
return events
|
|
35
|
-
.stream([{ kinds: [kinds.ChannelHideMessage], "#e": [channel.id], authors: [channel.pubkey, ...authors] }])
|
|
36
|
-
.map((event) => {
|
|
37
|
-
const reason = safeParse(event.content)?.reason;
|
|
38
|
-
for (const tag of event.tags) {
|
|
39
|
-
if (tag[0] === "e" && tag[1])
|
|
40
|
-
hidden.set(tag[1], reason ?? "");
|
|
41
|
-
}
|
|
42
|
-
return hidden;
|
|
43
|
-
});
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
/** Creates a query that returns a map of muted users Map<pubkey, reason> */
|
|
48
|
-
export function ChannelMutedQuery(channel, authors = []) {
|
|
49
|
-
return {
|
|
50
|
-
key: channel.id + authors.join(","),
|
|
51
|
-
run: (events) => {
|
|
52
|
-
const muted = new Map();
|
|
53
|
-
return events
|
|
54
|
-
.stream([{ kinds: [kinds.ChannelMuteUser], "#e": [channel.id], authors: [channel.pubkey, ...authors] }])
|
|
55
|
-
.map((event) => {
|
|
56
|
-
const reason = safeParse(event.content)?.reason;
|
|
57
|
-
for (const tag of event.tags) {
|
|
58
|
-
if (tag[0] === "p" && tag[1])
|
|
59
|
-
muted.set(tag[1], reason ?? "");
|
|
60
|
-
}
|
|
61
|
-
return muted;
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/** Creates a query that returns all messages in a channel */
|
|
67
|
-
export function ChannelMessagesQuery(channel) {
|
|
68
|
-
return {
|
|
69
|
-
key: channel.id,
|
|
70
|
-
run: (events) => events.timeline([{ kinds: [kinds.ChannelMessage], "#e": [channel.id] }]),
|
|
71
|
-
};
|
|
72
|
-
}
|
package/dist/queries/mute.d.ts
DELETED
package/dist/queries/mute.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getMutedHashtags, getMutedPubkeys, getMutedThreads, getMutedWords } from "../helpers/mute.js";
|
|
3
|
-
export function UserMuteQuery(pubkey) {
|
|
4
|
-
return {
|
|
5
|
-
key: pubkey,
|
|
6
|
-
run: (store) => store.replaceable(kinds.Mutelist, pubkey).map((event) => {
|
|
7
|
-
if (!event)
|
|
8
|
-
return;
|
|
9
|
-
const pubkeys = getMutedPubkeys(event);
|
|
10
|
-
const threads = getMutedThreads(event);
|
|
11
|
-
const hashtags = getMutedHashtags(event);
|
|
12
|
-
const words = getMutedWords(event);
|
|
13
|
-
return { pubkeys, threads, hashtags, words };
|
|
14
|
-
}),
|
|
15
|
-
};
|
|
16
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { UserStatusPointer } from "../helpers/user-status.js";
|
|
3
|
-
import { Query } from "../query-store/index.js";
|
|
4
|
-
export type UserStatus = UserStatusPointer & {
|
|
5
|
-
event: NostrEvent;
|
|
6
|
-
content: string;
|
|
7
|
-
};
|
|
8
|
-
/** Creates a Query that returns a parsed {@link UserStatus} for a certain type */
|
|
9
|
-
export declare function UserStatusQuery(pubkey: string, type?: string): Query<UserStatus | undefined | null>;
|
|
10
|
-
/** Creates a Query that returns a directory of parsed {@link UserStatus} for a pubkey */
|
|
11
|
-
export declare function UserStatusesQuery(pubkey: string): Query<Record<string, UserStatus>>;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getUserStatusPointer } from "../helpers/user-status.js";
|
|
3
|
-
import { getTagValue } from "../helpers/event.js";
|
|
4
|
-
/** Creates a Query that returns a parsed {@link UserStatus} for a certain type */
|
|
5
|
-
export function UserStatusQuery(pubkey, type = "general") {
|
|
6
|
-
return {
|
|
7
|
-
key: pubkey,
|
|
8
|
-
run: (events) => events.replaceable(kinds.UserStatuses, pubkey, type).map((event) => {
|
|
9
|
-
if (!event)
|
|
10
|
-
return undefined;
|
|
11
|
-
const pointer = getUserStatusPointer(event);
|
|
12
|
-
if (!pointer)
|
|
13
|
-
return null;
|
|
14
|
-
return {
|
|
15
|
-
...pointer,
|
|
16
|
-
event,
|
|
17
|
-
content: event.content,
|
|
18
|
-
};
|
|
19
|
-
}),
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/** Creates a Query that returns a directory of parsed {@link UserStatus} for a pubkey */
|
|
23
|
-
export function UserStatusesQuery(pubkey) {
|
|
24
|
-
return {
|
|
25
|
-
key: pubkey,
|
|
26
|
-
run: (events) => events.timeline([{ kinds: [kinds.UserStatuses], authors: [pubkey] }]).map((events) => {
|
|
27
|
-
return events.reduce((dir, event) => {
|
|
28
|
-
const d = getTagValue(event, "d");
|
|
29
|
-
if (!d)
|
|
30
|
-
return dir;
|
|
31
|
-
return { ...dir, [d]: { event, ...getUserStatusPointer(event), content: event.content } };
|
|
32
|
-
}, {});
|
|
33
|
-
}),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { Query } from "../index.js";
|
|
3
|
-
import { ChannelMetadataContent } from "../../helpers/channel.js";
|
|
4
|
-
/** Creates a query that returns the latest parsed metadata */
|
|
5
|
-
export declare function ChannelMetadataQuery(channel: NostrEvent): Query<ChannelMetadataContent | undefined>;
|
|
6
|
-
/** Creates a query that returns a map of hidden messages Map<id, reason> */
|
|
7
|
-
export declare function ChannelHiddenQuery(channel: NostrEvent, authors?: string[]): Query<Map<string, string>>;
|
|
8
|
-
/** Creates a query that returns a map of muted users Map<pubkey, reason> */
|
|
9
|
-
export declare function ChannelMutedQuery(channel: NostrEvent, authors?: string[]): Query<Map<string, string>>;
|
|
10
|
-
/** Creates a query that returns all messages in a channel */
|
|
11
|
-
export declare function ChannelMessagesQuery(channel: NostrEvent): Query<NostrEvent[]>;
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getChannelMetadataContent } from "../../helpers/channel.js";
|
|
3
|
-
import { safeParse } from "../../helpers/json.js";
|
|
4
|
-
/** Creates a query that returns the latest parsed metadata */
|
|
5
|
-
export function ChannelMetadataQuery(channel) {
|
|
6
|
-
return {
|
|
7
|
-
key: channel.id,
|
|
8
|
-
run: (events) => {
|
|
9
|
-
const filters = [
|
|
10
|
-
{ ids: [channel.id] },
|
|
11
|
-
{ kinds: [kinds.ChannelMetadata], "#e": [channel.id], authors: [channel.pubkey] },
|
|
12
|
-
];
|
|
13
|
-
let latest = channel;
|
|
14
|
-
return events.stream(filters).map((event) => {
|
|
15
|
-
try {
|
|
16
|
-
if (event.pubkey === latest.pubkey && event.created_at > latest.created_at) {
|
|
17
|
-
latest = event;
|
|
18
|
-
}
|
|
19
|
-
return getChannelMetadataContent(latest);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
/** Creates a query that returns a map of hidden messages Map<id, reason> */
|
|
29
|
-
export function ChannelHiddenQuery(channel, authors = []) {
|
|
30
|
-
return {
|
|
31
|
-
key: channel.id,
|
|
32
|
-
run: (events) => {
|
|
33
|
-
const hidden = new Map();
|
|
34
|
-
return events
|
|
35
|
-
.stream([{ kinds: [kinds.ChannelHideMessage], "#e": [channel.id], authors: [channel.pubkey, ...authors] }])
|
|
36
|
-
.map((event) => {
|
|
37
|
-
const reason = safeParse(event.content)?.reason;
|
|
38
|
-
for (const tag of event.tags) {
|
|
39
|
-
if (tag[0] === "e" && tag[1])
|
|
40
|
-
hidden.set(tag[1], reason ?? "");
|
|
41
|
-
}
|
|
42
|
-
return hidden;
|
|
43
|
-
});
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
/** Creates a query that returns a map of muted users Map<pubkey, reason> */
|
|
48
|
-
export function ChannelMutedQuery(channel, authors = []) {
|
|
49
|
-
return {
|
|
50
|
-
key: channel.id + authors.join(","),
|
|
51
|
-
run: (events) => {
|
|
52
|
-
const muted = new Map();
|
|
53
|
-
return events
|
|
54
|
-
.stream([{ kinds: [kinds.ChannelMuteUser], "#e": [channel.id], authors: [channel.pubkey, ...authors] }])
|
|
55
|
-
.map((event) => {
|
|
56
|
-
const reason = safeParse(event.content)?.reason;
|
|
57
|
-
for (const tag of event.tags) {
|
|
58
|
-
if (tag[0] === "p" && tag[1])
|
|
59
|
-
muted.set(tag[1], reason ?? "");
|
|
60
|
-
}
|
|
61
|
-
return muted;
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/** Creates a query that returns all messages in a channel */
|
|
67
|
-
export function ChannelMessagesQuery(channel) {
|
|
68
|
-
return {
|
|
69
|
-
key: channel.id,
|
|
70
|
-
run: (events) => events.timeline([{ kinds: [kinds.ChannelMessage], "#e": [channel.id] }]),
|
|
71
|
-
};
|
|
72
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getInboxes, getOutboxes } from "../../helpers/mailboxes.js";
|
|
3
|
-
export function MailboxesQuery(pubkey) {
|
|
4
|
-
return {
|
|
5
|
-
key: pubkey,
|
|
6
|
-
run: (events) => events.replaceable(kinds.RelayList, pubkey).map((event) => event && {
|
|
7
|
-
inboxes: getInboxes(event),
|
|
8
|
-
outboxes: getOutboxes(event),
|
|
9
|
-
}),
|
|
10
|
-
};
|
|
11
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getMutedHashtags, getMutedPubkeys, getMutedThreads, getMutedWords } from "../../helpers/mute.js";
|
|
3
|
-
export function UserMuteQuery(pubkey) {
|
|
4
|
-
return {
|
|
5
|
-
key: pubkey,
|
|
6
|
-
run: (store) => store.replaceable(kinds.Mutelist, pubkey).map((event) => {
|
|
7
|
-
if (!event)
|
|
8
|
-
return;
|
|
9
|
-
const pubkeys = getMutedPubkeys(event);
|
|
10
|
-
const threads = getMutedThreads(event);
|
|
11
|
-
const hashtags = getMutedHashtags(event);
|
|
12
|
-
const words = getMutedWords(event);
|
|
13
|
-
return { pubkeys, threads, hashtags, words };
|
|
14
|
-
}),
|
|
15
|
-
};
|
|
16
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getProfileContent } from "../../helpers/profile.js";
|
|
3
|
-
export function ProfileQuery(pubkey) {
|
|
4
|
-
return {
|
|
5
|
-
key: pubkey,
|
|
6
|
-
run: (events) => {
|
|
7
|
-
return events.replaceable(kinds.Metadata, pubkey).map((event) => event && getProfileContent(event));
|
|
8
|
-
},
|
|
9
|
-
};
|
|
10
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getEventUID, isReplaceable } from "../../helpers/event.js";
|
|
3
|
-
/** Creates a query that returns all reactions to an event (supports replaceable events) */
|
|
4
|
-
export function ReactionsQuery(event) {
|
|
5
|
-
return {
|
|
6
|
-
key: getEventUID(event),
|
|
7
|
-
run: (events) => events.timeline(isReplaceable(event.kind)
|
|
8
|
-
? [
|
|
9
|
-
{ kinds: [kinds.Reaction], "#e": [event.id] },
|
|
10
|
-
{ kinds: [kinds.Reaction], "#a": [getEventUID(event)] },
|
|
11
|
-
]
|
|
12
|
-
: [
|
|
13
|
-
{
|
|
14
|
-
kinds: [kinds.Reaction],
|
|
15
|
-
"#e": [event.id],
|
|
16
|
-
},
|
|
17
|
-
]),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { Filter, NostrEvent } from "nostr-tools";
|
|
2
|
-
import { Query } from "../index.js";
|
|
3
|
-
export declare function SingleEventQuery(uid: string): Query<NostrEvent | undefined>;
|
|
4
|
-
export declare function ReplaceableQuery(kind: number, pubkey: string, d?: string): Query<NostrEvent | undefined>;
|
|
5
|
-
export declare function TimelineQuery(filters: Filter | Filter[]): Query<NostrEvent[]>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import stringify from "json-stringify-deterministic";
|
|
2
|
-
import { getReplaceableUID } from "../../helpers/event.js";
|
|
3
|
-
export function SingleEventQuery(uid) {
|
|
4
|
-
return {
|
|
5
|
-
key: uid,
|
|
6
|
-
run: (events) => events.event(uid),
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
export function ReplaceableQuery(kind, pubkey, d) {
|
|
10
|
-
return {
|
|
11
|
-
key: getReplaceableUID(kind, pubkey, d),
|
|
12
|
-
run: (events) => events.replaceable(kind, pubkey, d),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export function TimelineQuery(filters) {
|
|
16
|
-
return {
|
|
17
|
-
key: stringify(filters),
|
|
18
|
-
run: (events) => events.timeline(Array.isArray(filters) ? filters : [filters]),
|
|
19
|
-
};
|
|
20
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
|
|
3
|
-
import { Query } from "../index.js";
|
|
4
|
-
export type ThreadItem = {
|
|
5
|
-
/** underlying nostr event */
|
|
6
|
-
event: NostrEvent;
|
|
7
|
-
/** the thread root, according to this event */
|
|
8
|
-
root?: ThreadItem;
|
|
9
|
-
/** the parent event this is replying to */
|
|
10
|
-
parent?: ThreadItem;
|
|
11
|
-
/** direct child replies */
|
|
12
|
-
replies: Set<ThreadItem>;
|
|
13
|
-
};
|
|
14
|
-
export type ThreadQueryOptions = {
|
|
15
|
-
kinds?: number[];
|
|
16
|
-
};
|
|
17
|
-
export declare function ThreadQuery(root: string | AddressPointer | EventPointer, opts?: ThreadQueryOptions): Query<{
|
|
18
|
-
root?: ThreadItem;
|
|
19
|
-
all: ThreadItem[];
|
|
20
|
-
}>;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { getNip10References } from "../../helpers/threading.js";
|
|
3
|
-
import { getCoordinateFromAddressPointer, isAddressPointer } from "../../helpers/pointers.js";
|
|
4
|
-
import { getEventUID } from "../../helpers/event.js";
|
|
5
|
-
const defaultOptions = {
|
|
6
|
-
kinds: [kinds.ShortTextNote],
|
|
7
|
-
};
|
|
8
|
-
export function ThreadQuery(root, opts) {
|
|
9
|
-
const parentReferences = new Map();
|
|
10
|
-
const items = new Map();
|
|
11
|
-
const { kinds } = { ...defaultOptions, ...opts };
|
|
12
|
-
let rootUID = "";
|
|
13
|
-
const rootFilter = {};
|
|
14
|
-
const replyFilter = { kinds };
|
|
15
|
-
if (isAddressPointer(root)) {
|
|
16
|
-
rootUID = getCoordinateFromAddressPointer(root);
|
|
17
|
-
rootFilter.kinds = [root.kind];
|
|
18
|
-
rootFilter.authors = [root.pubkey];
|
|
19
|
-
rootFilter["#d"] = [root.identifier];
|
|
20
|
-
replyFilter["#a"] = [rootUID];
|
|
21
|
-
}
|
|
22
|
-
else if (typeof root === "string") {
|
|
23
|
-
rootUID = root;
|
|
24
|
-
rootFilter.ids = [root];
|
|
25
|
-
replyFilter["#e"] = [root];
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
rootUID = root.id;
|
|
29
|
-
rootFilter.ids = [root.id];
|
|
30
|
-
replyFilter["#e"] = [root.id];
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
key: `${root}-${kinds.join(",")}`,
|
|
34
|
-
run: (events) => events.stream([rootFilter, replyFilter]).map((event) => {
|
|
35
|
-
const refs = getNip10References(event);
|
|
36
|
-
const replies = parentReferences.get(getEventUID(event)) || new Set();
|
|
37
|
-
const item = { event, replies };
|
|
38
|
-
// add item to parent
|
|
39
|
-
if (refs.reply?.e || refs.reply?.a) {
|
|
40
|
-
let uid = refs.reply.e ? refs.reply.e.id : getCoordinateFromAddressPointer(refs.reply.a);
|
|
41
|
-
const parent = items.get(uid);
|
|
42
|
-
if (parent) {
|
|
43
|
-
parent.replies.add(item);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
// parent isn't created yet, store ref for later
|
|
47
|
-
let set = parentReferences.get(uid);
|
|
48
|
-
if (!set) {
|
|
49
|
-
set = new Set();
|
|
50
|
-
parentReferences.set(uid, set);
|
|
51
|
-
}
|
|
52
|
-
set.add(item);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// add item to map
|
|
56
|
-
items.set(getEventUID(event), item);
|
|
57
|
-
return { root: items.get(rootUID), all: Array.from(items.values()) };
|
|
58
|
-
}),
|
|
59
|
-
};
|
|
60
|
-
}
|
package/dist/utils/lru.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
type Item<T> = {
|
|
2
|
-
key: string;
|
|
3
|
-
prev: Item<T> | null;
|
|
4
|
-
value: T;
|
|
5
|
-
next: Item<T> | null;
|
|
6
|
-
expiry: number;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Copied from tiny-lru and modified to support typescript
|
|
10
|
-
* @see https://github.com/avoidwork/tiny-lru/blob/master/src/lru.js
|
|
11
|
-
*/
|
|
12
|
-
export declare class LRU<T extends unknown> {
|
|
13
|
-
first: Item<T> | null;
|
|
14
|
-
items: Record<string, Item<T>>;
|
|
15
|
-
last: Item<T> | null;
|
|
16
|
-
max: number;
|
|
17
|
-
resetTtl: boolean;
|
|
18
|
-
size: number;
|
|
19
|
-
ttl: number;
|
|
20
|
-
constructor(max?: number, ttl?: number, resetTtl?: boolean);
|
|
21
|
-
clear(): this;
|
|
22
|
-
delete(key: string): this;
|
|
23
|
-
entries(keys?: string[]): (string | T | undefined)[][];
|
|
24
|
-
evict(bypass?: boolean): this;
|
|
25
|
-
expiresAt(key: string): number | undefined;
|
|
26
|
-
get(key: string): T | undefined;
|
|
27
|
-
has(key: string): boolean;
|
|
28
|
-
keys(): string[];
|
|
29
|
-
set(key: string, value: T, bypass?: boolean, resetTtl?: boolean): this;
|
|
30
|
-
values(keys?: string[]): NonNullable<T>[];
|
|
31
|
-
}
|
|
32
|
-
export {};
|
package/dist/utils/lru.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copied from tiny-lru and modified to support typescript
|
|
3
|
-
* @see https://github.com/avoidwork/tiny-lru/blob/master/src/lru.js
|
|
4
|
-
*/
|
|
5
|
-
export class LRU {
|
|
6
|
-
first = null;
|
|
7
|
-
items = Object.create(null);
|
|
8
|
-
last = null;
|
|
9
|
-
max;
|
|
10
|
-
resetTtl;
|
|
11
|
-
size;
|
|
12
|
-
ttl;
|
|
13
|
-
constructor(max = 0, ttl = 0, resetTtl = false) {
|
|
14
|
-
this.first = null;
|
|
15
|
-
this.items = Object.create(null);
|
|
16
|
-
this.last = null;
|
|
17
|
-
this.max = max;
|
|
18
|
-
this.resetTtl = resetTtl;
|
|
19
|
-
this.size = 0;
|
|
20
|
-
this.ttl = ttl;
|
|
21
|
-
}
|
|
22
|
-
clear() {
|
|
23
|
-
this.first = null;
|
|
24
|
-
this.items = Object.create(null);
|
|
25
|
-
this.last = null;
|
|
26
|
-
this.size = 0;
|
|
27
|
-
return this;
|
|
28
|
-
}
|
|
29
|
-
delete(key) {
|
|
30
|
-
if (this.has(key)) {
|
|
31
|
-
const item = this.items[key];
|
|
32
|
-
delete this.items[key];
|
|
33
|
-
this.size--;
|
|
34
|
-
if (item.prev !== null) {
|
|
35
|
-
item.prev.next = item.next;
|
|
36
|
-
}
|
|
37
|
-
if (item.next !== null) {
|
|
38
|
-
item.next.prev = item.prev;
|
|
39
|
-
}
|
|
40
|
-
if (this.first === item) {
|
|
41
|
-
this.first = item.next;
|
|
42
|
-
}
|
|
43
|
-
if (this.last === item) {
|
|
44
|
-
this.last = item.prev;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return this;
|
|
48
|
-
}
|
|
49
|
-
entries(keys = this.keys()) {
|
|
50
|
-
return keys.map((key) => [key, this.get(key)]);
|
|
51
|
-
}
|
|
52
|
-
evict(bypass = false) {
|
|
53
|
-
if (bypass || this.size > 0) {
|
|
54
|
-
const item = this.first;
|
|
55
|
-
delete this.items[item.key];
|
|
56
|
-
if (--this.size === 0) {
|
|
57
|
-
this.first = null;
|
|
58
|
-
this.last = null;
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
this.first = item.next;
|
|
62
|
-
this.first.prev = null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
expiresAt(key) {
|
|
68
|
-
let result;
|
|
69
|
-
if (this.has(key)) {
|
|
70
|
-
result = this.items[key].expiry;
|
|
71
|
-
}
|
|
72
|
-
return result;
|
|
73
|
-
}
|
|
74
|
-
get(key) {
|
|
75
|
-
let result;
|
|
76
|
-
if (this.has(key)) {
|
|
77
|
-
const item = this.items[key];
|
|
78
|
-
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
79
|
-
this.delete(key);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
result = item.value;
|
|
83
|
-
this.set(key, result, true);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
has(key) {
|
|
89
|
-
return key in this.items;
|
|
90
|
-
}
|
|
91
|
-
keys() {
|
|
92
|
-
const result = [];
|
|
93
|
-
let x = this.first;
|
|
94
|
-
while (x !== null) {
|
|
95
|
-
result.push(x.key);
|
|
96
|
-
x = x.next;
|
|
97
|
-
}
|
|
98
|
-
return result;
|
|
99
|
-
}
|
|
100
|
-
set(key, value, bypass = false, resetTtl = this.resetTtl) {
|
|
101
|
-
let item;
|
|
102
|
-
if (bypass || this.has(key)) {
|
|
103
|
-
item = this.items[key];
|
|
104
|
-
item.value = value;
|
|
105
|
-
if (bypass === false && resetTtl) {
|
|
106
|
-
item.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
107
|
-
}
|
|
108
|
-
if (this.last !== item) {
|
|
109
|
-
const last = this.last, next = item.next, prev = item.prev;
|
|
110
|
-
if (this.first === item) {
|
|
111
|
-
this.first = item.next;
|
|
112
|
-
}
|
|
113
|
-
item.next = null;
|
|
114
|
-
item.prev = this.last;
|
|
115
|
-
last.next = item;
|
|
116
|
-
if (prev !== null) {
|
|
117
|
-
prev.next = next;
|
|
118
|
-
}
|
|
119
|
-
if (next !== null) {
|
|
120
|
-
next.prev = prev;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
if (this.max > 0 && this.size === this.max) {
|
|
126
|
-
this.evict(true);
|
|
127
|
-
}
|
|
128
|
-
item = this.items[key] = {
|
|
129
|
-
expiry: this.ttl > 0 ? Date.now() + this.ttl : this.ttl,
|
|
130
|
-
key: key,
|
|
131
|
-
prev: this.last,
|
|
132
|
-
next: null,
|
|
133
|
-
value,
|
|
134
|
-
};
|
|
135
|
-
if (++this.size === 1) {
|
|
136
|
-
this.first = item;
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.last.next = item;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
this.last = item;
|
|
143
|
-
return this;
|
|
144
|
-
}
|
|
145
|
-
values(keys = this.keys()) {
|
|
146
|
-
return keys.map((key) => this.get(key));
|
|
147
|
-
}
|
|
148
|
-
}
|