applesauce-core 0.0.0-next-20241210193522 → 0.0.0-next-20241212192616
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/README.md +1 -1
- package/dist/helpers/comment.js +8 -7
- package/dist/helpers/delete.d.ts +1 -3
- package/dist/helpers/delete.js +0 -31
- package/dist/helpers/hidden-tags.test.js +1 -0
- package/dist/helpers/mailboxes.test.js +13 -12
- package/dist/helpers/pointers.d.ts +30 -10
- package/dist/helpers/pointers.js +60 -21
- package/dist/helpers/threading.d.ts +6 -6
- package/dist/helpers/threading.js +30 -9
- package/dist/helpers/threading.test.d.ts +1 -0
- package/dist/helpers/threading.test.js +41 -0
- package/dist/helpers/zap.js +3 -3
- package/dist/queries/thread.d.ts +1 -1
- package/dist/queries/thread.js +4 -3
- package/package.json +5 -16
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# applesauce-core
|
|
2
2
|
|
|
3
|
-
AppleSauce Core is an interpretation layer for nostr clients, Push events into the in-memory [database](https://hzrd149.github.io/applesauce/classes/Database.html) and get nicely formatted data out with [queries](https://hzrd149.github.io/applesauce/modules/Queries)
|
|
3
|
+
AppleSauce Core is an interpretation layer for nostr clients, Push events into the in-memory [database](https://hzrd149.github.io/applesauce/typedoc/classes/Database.html) and get nicely formatted data out with [queries](https://hzrd149.github.io/applesauce/typedoc/modules/Queries)
|
|
4
4
|
|
|
5
5
|
# Example
|
|
6
6
|
|
package/dist/helpers/comment.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getExternalPointerFromTag } from "./external-id.js";
|
|
2
2
|
import { getOrComputeCachedValue } from "./cache.js";
|
|
3
|
-
import {
|
|
3
|
+
import { getAddressPointerFromATag } from "./pointers.js";
|
|
4
|
+
import { safeRelayUrl } from "./relays.js";
|
|
4
5
|
export const COMMENT_KIND = 1111;
|
|
5
6
|
export const CommentRootPointerSymbol = Symbol.for("comment-root-pointer");
|
|
6
7
|
export const CommentReplyPointerSymbol = Symbol.for("comment-reply-pointer");
|
|
@@ -14,13 +15,13 @@ export function getCommentEventPointer(tags, root = false) {
|
|
|
14
15
|
if (tag) {
|
|
15
16
|
if (!kind)
|
|
16
17
|
throw new Error("Missing kind tag");
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
id: eventPointer.id,
|
|
18
|
+
const pointer = {
|
|
19
|
+
id: tag[1],
|
|
20
20
|
kind: parseInt(kind),
|
|
21
|
-
pubkey:
|
|
22
|
-
relay:
|
|
21
|
+
pubkey: tag[3] || undefined,
|
|
22
|
+
relay: tag[2] && (safeRelayUrl(tag[2]) ?? undefined),
|
|
23
23
|
};
|
|
24
|
+
return pointer;
|
|
24
25
|
}
|
|
25
26
|
return null;
|
|
26
27
|
}
|
|
@@ -37,7 +38,7 @@ export function getCommentAddressPointer(tags, root = false) {
|
|
|
37
38
|
throw new Error("Missing kind tag");
|
|
38
39
|
const pointer = {
|
|
39
40
|
id,
|
|
40
|
-
...
|
|
41
|
+
...getAddressPointerFromATag(tag),
|
|
41
42
|
kind: parseInt(kind),
|
|
42
43
|
};
|
|
43
44
|
return pointer;
|
package/dist/helpers/delete.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NostrEvent } from "nostr-tools";
|
|
2
2
|
export declare function getDeleteIds(deleteEvent: NostrEvent): string[];
|
|
3
3
|
export declare function getDeleteCoordinates(deleteEvent: NostrEvent): string[];
|
|
4
|
-
/** Creates a NIP-09 delete event for an array of events */
|
|
5
|
-
export declare function createDeleteEvent(events: NostrEvent[], message?: string): EventTemplate;
|
package/dist/helpers/delete.js
CHANGED
|
@@ -1,38 +1,7 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { isParameterizedReplaceableKind } from "nostr-tools/kinds";
|
|
3
1
|
import { isATag, isETag } from "./tags.js";
|
|
4
|
-
import { unixNow } from "./time.js";
|
|
5
|
-
import { getATagFromAddressPointer, getETagFromEventPointer } from "./pointers.js";
|
|
6
|
-
import { getTagValue } from "./index.js";
|
|
7
2
|
export function getDeleteIds(deleteEvent) {
|
|
8
3
|
return deleteEvent.tags.filter(isETag).map((t) => t[1]);
|
|
9
4
|
}
|
|
10
5
|
export function getDeleteCoordinates(deleteEvent) {
|
|
11
6
|
return deleteEvent.tags.filter(isATag).map((t) => t[1]);
|
|
12
7
|
}
|
|
13
|
-
/** Creates a NIP-09 delete event for an array of events */
|
|
14
|
-
export function createDeleteEvent(events, message) {
|
|
15
|
-
const eventPointers = [];
|
|
16
|
-
const addressPointers = [];
|
|
17
|
-
const eventKinds = new Set();
|
|
18
|
-
for (const event of events) {
|
|
19
|
-
eventKinds.add(event.kind);
|
|
20
|
-
eventPointers.push({ id: event.id });
|
|
21
|
-
if (isParameterizedReplaceableKind(event.kind)) {
|
|
22
|
-
const identifier = getTagValue(event, "d");
|
|
23
|
-
if (!identifier)
|
|
24
|
-
throw new Error("Event missing identifier");
|
|
25
|
-
addressPointers.push({ pubkey: event.pubkey, kind: event.kind, identifier });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
kind: kinds.EventDeletion,
|
|
30
|
-
content: message ?? "",
|
|
31
|
-
tags: [
|
|
32
|
-
...eventPointers.map(getETagFromEventPointer),
|
|
33
|
-
...addressPointers.map(getATagFromAddressPointer),
|
|
34
|
-
...Array.from(eventKinds).map((k) => ["k", String(k)]),
|
|
35
|
-
],
|
|
36
|
-
created_at: unixNow(),
|
|
37
|
-
};
|
|
38
|
-
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
1
2
|
import { getInboxes, getOutboxes } from "./mailboxes.js";
|
|
2
3
|
const emptyEvent = {
|
|
3
4
|
kind: 10002,
|
|
@@ -14,33 +15,33 @@ describe("Mailboxes", () => {
|
|
|
14
15
|
expect(Array.from(getInboxes({
|
|
15
16
|
...emptyEvent,
|
|
16
17
|
tags: [["r", "wss://inbox.com"]],
|
|
17
|
-
}))).
|
|
18
|
+
}))).toEqual(expect.arrayContaining(["wss://inbox.com/"]));
|
|
18
19
|
});
|
|
19
20
|
test("should remove bad urls", () => {
|
|
20
21
|
expect(Array.from(getInboxes({
|
|
21
22
|
...emptyEvent,
|
|
22
23
|
tags: [["r", "bad://inbox.com"]],
|
|
23
|
-
}))).
|
|
24
|
+
}))).toHaveLength(0);
|
|
24
25
|
expect(Array.from(getInboxes({
|
|
25
26
|
...emptyEvent,
|
|
26
27
|
tags: [["r", "something that is not a url"]],
|
|
27
|
-
}))).
|
|
28
|
+
}))).toHaveLength(0);
|
|
28
29
|
expect(Array.from(getInboxes({
|
|
29
30
|
...emptyEvent,
|
|
30
31
|
tags: [["r", "wss://inbox.com,wss://inbox.org"]],
|
|
31
|
-
}))).
|
|
32
|
+
}))).toHaveLength(0);
|
|
32
33
|
});
|
|
33
34
|
test("without marker", () => {
|
|
34
35
|
expect(Array.from(getInboxes({
|
|
35
36
|
...emptyEvent,
|
|
36
37
|
tags: [["r", "wss://inbox.com/"]],
|
|
37
|
-
}))).
|
|
38
|
+
}))).toEqual(expect.arrayContaining(["wss://inbox.com/"]));
|
|
38
39
|
});
|
|
39
40
|
test("with marker", () => {
|
|
40
41
|
expect(Array.from(getInboxes({
|
|
41
42
|
...emptyEvent,
|
|
42
43
|
tags: [["r", "wss://inbox.com/", "read"]],
|
|
43
|
-
}))).
|
|
44
|
+
}))).toEqual(expect.arrayContaining(["wss://inbox.com/"]));
|
|
44
45
|
});
|
|
45
46
|
});
|
|
46
47
|
describe("getOutboxes", () => {
|
|
@@ -48,33 +49,33 @@ describe("Mailboxes", () => {
|
|
|
48
49
|
expect(Array.from(getOutboxes({
|
|
49
50
|
...emptyEvent,
|
|
50
51
|
tags: [["r", "wss://outbox.com"]],
|
|
51
|
-
}))).
|
|
52
|
+
}))).toEqual(expect.arrayContaining(["wss://outbox.com/"]));
|
|
52
53
|
});
|
|
53
54
|
test("should remove bad urls", () => {
|
|
54
55
|
expect(Array.from(getOutboxes({
|
|
55
56
|
...emptyEvent,
|
|
56
57
|
tags: [["r", "bad://inbox.com"]],
|
|
57
|
-
}))).
|
|
58
|
+
}))).toHaveLength(0);
|
|
58
59
|
expect(Array.from(getOutboxes({
|
|
59
60
|
...emptyEvent,
|
|
60
61
|
tags: [["r", "something that is not a url"]],
|
|
61
|
-
}))).
|
|
62
|
+
}))).toHaveLength(0);
|
|
62
63
|
expect(Array.from(getOutboxes({
|
|
63
64
|
...emptyEvent,
|
|
64
65
|
tags: [["r", "wss://outbox.com,wss://inbox.org"]],
|
|
65
|
-
}))).
|
|
66
|
+
}))).toHaveLength(0);
|
|
66
67
|
});
|
|
67
68
|
test("without marker", () => {
|
|
68
69
|
expect(Array.from(getOutboxes({
|
|
69
70
|
...emptyEvent,
|
|
70
71
|
tags: [["r", "wss://outbox.com/"]],
|
|
71
|
-
}))).
|
|
72
|
+
}))).toEqual(expect.arrayContaining(["wss://outbox.com/"]));
|
|
72
73
|
});
|
|
73
74
|
test("with marker", () => {
|
|
74
75
|
expect(Array.from(getOutboxes({
|
|
75
76
|
...emptyEvent,
|
|
76
77
|
tags: [["r", "wss://outbox.com/", "write"]],
|
|
77
|
-
}))).
|
|
78
|
+
}))).toEqual(expect.arrayContaining(["wss://outbox.com/"]));
|
|
78
79
|
});
|
|
79
80
|
});
|
|
80
81
|
});
|
|
@@ -15,21 +15,41 @@ export declare function parseCoordinate(a: string, requireD: false, silent: true
|
|
|
15
15
|
export declare function getPubkeyFromDecodeResult(result?: DecodeResult): string | undefined;
|
|
16
16
|
/** Encodes the result of nip19.decode */
|
|
17
17
|
export declare function encodeDecodeResult(result: DecodeResult): "" | `nprofile1${string}` | `nevent1${string}` | `naddr1${string}` | `nsec1${string}` | `npub1${string}` | `note1${string}`;
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Gets an EventPointer form a common "e" tag
|
|
20
|
+
* @throws
|
|
21
|
+
*/
|
|
22
|
+
export declare function getEventPointerFromETag(tag: string[]): EventPointer;
|
|
23
|
+
/**
|
|
24
|
+
* Gets an EventPointer form a "q" tag
|
|
25
|
+
* @throws
|
|
26
|
+
*/
|
|
27
|
+
export declare function getEventPointerFromQTag(tag: string[]): EventPointer;
|
|
28
|
+
/**
|
|
29
|
+
* Get an AddressPointer from an "a" tag
|
|
30
|
+
* @throws
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAddressPointerFromATag(tag: string[]): AddressPointer;
|
|
33
|
+
/**
|
|
34
|
+
* Gets a ProfilePointer from a "p" tag
|
|
35
|
+
* @throws
|
|
36
|
+
*/
|
|
37
|
+
export declare function getProfilePointerFromPTag(tag: string[]): ProfilePointer;
|
|
24
38
|
/** Parses "e", "a", "p", and "q" tags into a pointer */
|
|
25
39
|
export declare function getPointerFromTag(tag: string[]): DecodeResult | null;
|
|
26
40
|
export declare function isAddressPointer(pointer: DecodeResult["data"]): pointer is AddressPointer;
|
|
27
41
|
export declare function isEventPointer(pointer: DecodeResult["data"]): pointer is EventPointer;
|
|
28
42
|
/** Returns the coordinate string for an AddressPointer */
|
|
29
43
|
export declare function getCoordinateFromAddressPointer(pointer: AddressPointer): string;
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Returns an AddressPointer for a replaceable event
|
|
46
|
+
* @throws
|
|
47
|
+
*/
|
|
48
|
+
export declare function getAddressPointerForEvent(event: NostrEvent, relays?: string[]): AddressPointer;
|
|
49
|
+
/**
|
|
50
|
+
* Returns an EventPointer for an event
|
|
51
|
+
* @throws
|
|
52
|
+
*/
|
|
53
|
+
export declare function getEventPointerForEvent(event: NostrEvent, relays?: string[]): EventPointer;
|
|
34
54
|
/** Returns a pointer for a given event */
|
|
35
55
|
export declare function getPointerForEvent(event: NostrEvent, relays?: string[]): DecodeResult;
|
package/dist/helpers/pointers.js
CHANGED
|
@@ -2,6 +2,7 @@ import { naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsec
|
|
|
2
2
|
import { getPublicKey, kinds } from "nostr-tools";
|
|
3
3
|
import { safeRelayUrls } from "./relays.js";
|
|
4
4
|
import { getTagValue } from "./index.js";
|
|
5
|
+
import { isParameterizedReplaceableKind } from "nostr-tools/kinds";
|
|
5
6
|
export function parseCoordinate(a, requireD = false, silent = true) {
|
|
6
7
|
const parts = a.split(":");
|
|
7
8
|
const kind = parts[0] && parseInt(parts[0]);
|
|
@@ -65,21 +66,37 @@ export function encodeDecodeResult(result) {
|
|
|
65
66
|
}
|
|
66
67
|
return "";
|
|
67
68
|
}
|
|
68
|
-
/**
|
|
69
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Gets an EventPointer form a common "e" tag
|
|
71
|
+
* @throws
|
|
72
|
+
*/
|
|
73
|
+
export function getEventPointerFromETag(tag) {
|
|
70
74
|
if (!tag[1])
|
|
71
75
|
throw new Error("Missing event id in tag");
|
|
72
76
|
let pointer = { id: tag[1] };
|
|
73
77
|
if (tag[2])
|
|
74
78
|
pointer.relays = safeRelayUrls([tag[2]]);
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
return pointer;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Gets an EventPointer form a "q" tag
|
|
83
|
+
* @throws
|
|
84
|
+
*/
|
|
85
|
+
export function getEventPointerFromQTag(tag) {
|
|
86
|
+
if (!tag[1])
|
|
87
|
+
throw new Error("Missing event id in tag");
|
|
88
|
+
let pointer = { id: tag[1] };
|
|
89
|
+
if (tag[2])
|
|
90
|
+
pointer.relays = safeRelayUrls([tag[2]]);
|
|
91
|
+
if (tag[3] && tag[3].length === 64)
|
|
77
92
|
pointer.author = tag[3];
|
|
78
|
-
}
|
|
79
93
|
return pointer;
|
|
80
94
|
}
|
|
81
|
-
/**
|
|
82
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Get an AddressPointer from an "a" tag
|
|
97
|
+
* @throws
|
|
98
|
+
*/
|
|
99
|
+
export function getAddressPointerFromATag(tag) {
|
|
83
100
|
if (!tag[1])
|
|
84
101
|
throw new Error("Missing coordinate in tag");
|
|
85
102
|
const pointer = parseCoordinate(tag[1], true, false);
|
|
@@ -87,8 +104,11 @@ export function getAddressPointerFromTag(tag) {
|
|
|
87
104
|
pointer.relays = safeRelayUrls([tag[2]]);
|
|
88
105
|
return pointer;
|
|
89
106
|
}
|
|
90
|
-
/**
|
|
91
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Gets a ProfilePointer from a "p" tag
|
|
109
|
+
* @throws
|
|
110
|
+
*/
|
|
111
|
+
export function getProfilePointerFromPTag(tag) {
|
|
92
112
|
if (!tag[1])
|
|
93
113
|
throw new Error("Missing pubkey in tag");
|
|
94
114
|
const pointer = { pubkey: tag[1] };
|
|
@@ -101,17 +121,17 @@ export function getPointerFromTag(tag) {
|
|
|
101
121
|
try {
|
|
102
122
|
switch (tag[0]) {
|
|
103
123
|
case "e":
|
|
104
|
-
return { type: "nevent", data:
|
|
124
|
+
return { type: "nevent", data: getEventPointerFromETag(tag) };
|
|
105
125
|
case "a":
|
|
106
126
|
return {
|
|
107
127
|
type: "naddr",
|
|
108
|
-
data:
|
|
128
|
+
data: getAddressPointerFromATag(tag),
|
|
109
129
|
};
|
|
110
130
|
case "p":
|
|
111
|
-
return { type: "nprofile", data:
|
|
131
|
+
return { type: "nprofile", data: getProfilePointerFromPTag(tag) };
|
|
112
132
|
// NIP-18 quote tags
|
|
113
133
|
case "q":
|
|
114
|
-
return { type: "nevent", data:
|
|
134
|
+
return { type: "nevent", data: getEventPointerFromETag(tag) };
|
|
115
135
|
}
|
|
116
136
|
}
|
|
117
137
|
catch (error) { }
|
|
@@ -130,15 +150,34 @@ export function isEventPointer(pointer) {
|
|
|
130
150
|
export function getCoordinateFromAddressPointer(pointer) {
|
|
131
151
|
return `${pointer.kind}:${pointer.pubkey}:${pointer.identifier}`;
|
|
132
152
|
}
|
|
133
|
-
/**
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Returns an AddressPointer for a replaceable event
|
|
155
|
+
* @throws
|
|
156
|
+
*/
|
|
157
|
+
export function getAddressPointerForEvent(event, relays) {
|
|
158
|
+
if (!isParameterizedReplaceableKind(event.kind))
|
|
159
|
+
throw new Error("Cant get AddressPointer for non-replaceable event");
|
|
160
|
+
const d = getTagValue(event, "d");
|
|
161
|
+
if (!d)
|
|
162
|
+
throw new Error("Event missing identifier");
|
|
163
|
+
return {
|
|
164
|
+
identifier: d,
|
|
165
|
+
kind: event.kind,
|
|
166
|
+
pubkey: event.pubkey,
|
|
167
|
+
relays,
|
|
168
|
+
};
|
|
138
169
|
}
|
|
139
|
-
/**
|
|
140
|
-
|
|
141
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Returns an EventPointer for an event
|
|
172
|
+
* @throws
|
|
173
|
+
*/
|
|
174
|
+
export function getEventPointerForEvent(event, relays) {
|
|
175
|
+
return {
|
|
176
|
+
id: event.id,
|
|
177
|
+
kind: event.kind,
|
|
178
|
+
author: event.pubkey,
|
|
179
|
+
relays,
|
|
180
|
+
};
|
|
142
181
|
}
|
|
143
182
|
/** Returns a pointer for a given event */
|
|
144
183
|
export function getPointerForEvent(event, relays) {
|
|
@@ -23,13 +23,13 @@ export type ThreadReferences = {
|
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
export declare const Nip10ThreadRefsSymbol: unique symbol;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Gets an EventPointer form a NIP-10 threading "e" tag
|
|
28
|
+
* @throws
|
|
29
|
+
*/
|
|
30
|
+
export declare function getEventPointerFromThreadTag(tag: string[]): EventPointer;
|
|
31
31
|
/** Parses NIP-10 tags and handles legacy behavior */
|
|
32
|
-
export declare function interpretThreadTags(
|
|
32
|
+
export declare function interpretThreadTags(tags: string[][]): {
|
|
33
33
|
root?: {
|
|
34
34
|
e: string[];
|
|
35
35
|
a: undefined;
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAddressPointerFromATag } from "./pointers.js";
|
|
2
2
|
import { getOrComputeCachedValue } from "./cache.js";
|
|
3
|
+
import { safeRelayUrls } from "./relays.js";
|
|
3
4
|
export const Nip10ThreadRefsSymbol = Symbol.for("nip10-thread-refs");
|
|
5
|
+
/**
|
|
6
|
+
* Gets an EventPointer form a NIP-10 threading "e" tag
|
|
7
|
+
* @throws
|
|
8
|
+
*/
|
|
9
|
+
export function getEventPointerFromThreadTag(tag) {
|
|
10
|
+
if (!tag[1])
|
|
11
|
+
throw new Error("Missing event id in tag");
|
|
12
|
+
let pointer = { id: tag[1] };
|
|
13
|
+
if (tag[2])
|
|
14
|
+
pointer.relays = safeRelayUrls([tag[2]]);
|
|
15
|
+
// get author from NIP-18 quote tags, nip-22 comments tags, or nip-10 thread tags
|
|
16
|
+
if (tag[0] === "e" &&
|
|
17
|
+
(tag[3] === "root" || tag[3] === "reply" || tag[3] === "mention") &&
|
|
18
|
+
tag[4] &&
|
|
19
|
+
tag[4].length === 64) {
|
|
20
|
+
// NIP-10 "e" tag
|
|
21
|
+
pointer.author = tag[4];
|
|
22
|
+
}
|
|
23
|
+
return pointer;
|
|
24
|
+
}
|
|
4
25
|
/** Parses NIP-10 tags and handles legacy behavior */
|
|
5
|
-
export function interpretThreadTags(
|
|
6
|
-
const eTags =
|
|
7
|
-
const aTags =
|
|
26
|
+
export function interpretThreadTags(tags) {
|
|
27
|
+
const eTags = tags.filter((t) => t[0] === "e" && t[1]);
|
|
28
|
+
const aTags = tags.filter((t) => t[0] === "a" && t[1]);
|
|
8
29
|
// find the root and reply tags.
|
|
9
30
|
let rootETag = eTags.find((t) => t[3] === "root");
|
|
10
31
|
let replyETag = eTags.find((t) => t[3] === "reply");
|
|
@@ -44,13 +65,13 @@ export function interpretThreadTags(event) {
|
|
|
44
65
|
/** Returns the parsed NIP-10 tags for an event */
|
|
45
66
|
export function getNip10References(event) {
|
|
46
67
|
return getOrComputeCachedValue(event, Nip10ThreadRefsSymbol, () => {
|
|
47
|
-
const tags = interpretThreadTags(event);
|
|
68
|
+
const tags = interpretThreadTags(event.tags);
|
|
48
69
|
let root;
|
|
49
70
|
if (tags.root) {
|
|
50
71
|
try {
|
|
51
72
|
root = {
|
|
52
|
-
e: tags.root.e &&
|
|
53
|
-
a: tags.root.a &&
|
|
73
|
+
e: tags.root.e && getEventPointerFromThreadTag(tags.root.e),
|
|
74
|
+
a: tags.root.a && getAddressPointerFromATag(tags.root.a),
|
|
54
75
|
};
|
|
55
76
|
}
|
|
56
77
|
catch (error) { }
|
|
@@ -59,8 +80,8 @@ export function getNip10References(event) {
|
|
|
59
80
|
if (tags.reply) {
|
|
60
81
|
try {
|
|
61
82
|
reply = {
|
|
62
|
-
e: tags.reply.e &&
|
|
63
|
-
a: tags.reply.a &&
|
|
83
|
+
e: tags.reply.e && getEventPointerFromThreadTag(tags.reply.e),
|
|
84
|
+
a: tags.reply.a && getAddressPointerFromATag(tags.reply.a),
|
|
64
85
|
};
|
|
65
86
|
}
|
|
66
87
|
catch (error) { }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { interpretThreadTags } from "./threading.js";
|
|
3
|
+
describe("threading helpers", () => {
|
|
4
|
+
describe("interpretThreadTags", () => {
|
|
5
|
+
it("should handle legacy tags", () => {
|
|
6
|
+
expect(interpretThreadTags([
|
|
7
|
+
["e", "root-id"],
|
|
8
|
+
["e", "reply-id"],
|
|
9
|
+
])).toEqual({ root: { a: undefined, e: ["e", "root-id"] }, reply: { a: undefined, e: ["e", "reply-id"] } });
|
|
10
|
+
});
|
|
11
|
+
it("should handle nip-10 tags", () => {
|
|
12
|
+
expect(interpretThreadTags([
|
|
13
|
+
["e", "root-id", "relay", "root"],
|
|
14
|
+
["e", "reply-id", "relay", "reply"],
|
|
15
|
+
])).toEqual({
|
|
16
|
+
root: { a: undefined, e: ["e", "root-id", "relay", "root"] },
|
|
17
|
+
reply: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it("should ignore mention nip-10 tags", () => {
|
|
21
|
+
expect(interpretThreadTags([
|
|
22
|
+
["e", "root-id", "relay", "root"],
|
|
23
|
+
["e", "mention-id", "relay", "mention"],
|
|
24
|
+
["e", "reply-id", "relay", "reply"],
|
|
25
|
+
])).toEqual({
|
|
26
|
+
root: { a: undefined, e: ["e", "root-id", "relay", "root"] },
|
|
27
|
+
reply: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
it("should handle single nip-10 tags", () => {
|
|
31
|
+
expect(interpretThreadTags([["e", "root-id", "relay", "root"]])).toEqual({
|
|
32
|
+
root: { a: undefined, e: ["e", "root-id", "relay", "root"] },
|
|
33
|
+
reply: { a: undefined, e: ["e", "root-id", "relay", "root"] },
|
|
34
|
+
});
|
|
35
|
+
expect(interpretThreadTags([["e", "reply-id", "relay", "reply"]])).toEqual({
|
|
36
|
+
root: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
|
|
37
|
+
reply: { a: undefined, e: ["e", "reply-id", "relay", "reply"] },
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
package/dist/helpers/zap.js
CHANGED
|
@@ -2,7 +2,7 @@ import { kinds, nip57 } from "nostr-tools";
|
|
|
2
2
|
import { getOrComputeCachedValue } from "./cache.js";
|
|
3
3
|
import { getTagValue } from "./event.js";
|
|
4
4
|
import { isATag, isETag } from "./tags.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getAddressPointerFromATag, getEventPointerFromETag } from "./pointers.js";
|
|
6
6
|
import { parseBolt11 } from "./bolt11.js";
|
|
7
7
|
export const ZapRequestSymbol = Symbol.for("zap-request");
|
|
8
8
|
export const ZapFromSymbol = Symbol.for("zap-from");
|
|
@@ -34,14 +34,14 @@ export function getZapPayment(zap) {
|
|
|
34
34
|
export function getZapAddressPointer(zap) {
|
|
35
35
|
return getOrComputeCachedValue(zap, ZapAddressPointerSymbol, () => {
|
|
36
36
|
const a = zap.tags.find(isATag);
|
|
37
|
-
return a ?
|
|
37
|
+
return a ? getAddressPointerFromATag(a) : null;
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
/** Gets the EventPointer that was zapped */
|
|
41
41
|
export function getZapEventPointer(zap) {
|
|
42
42
|
return getOrComputeCachedValue(zap, ZapEventPointerSymbol, () => {
|
|
43
43
|
const e = zap.tags.find(isETag);
|
|
44
|
-
return e ?
|
|
44
|
+
return e ? getEventPointerFromETag(e) : null;
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
/** Gets the preimage for the bolt11 invoice */
|
package/dist/queries/thread.d.ts
CHANGED
|
@@ -21,5 +21,5 @@ export type ThreadQueryOptions = {
|
|
|
21
21
|
kinds?: number[];
|
|
22
22
|
};
|
|
23
23
|
export declare function ThreadQuery(root: string | AddressPointer | EventPointer, opts?: ThreadQueryOptions): Query<Thread>;
|
|
24
|
-
/** A query that gets all legacy and NIP-10 replies for an event */
|
|
24
|
+
/** A query that gets all legacy and NIP-10, and NIP-22 replies for an event */
|
|
25
25
|
export declare function RepliesQuery(event: NostrEvent, overrideKinds?: number[]): Query<NostrEvent[]>;
|
package/dist/queries/thread.js
CHANGED
|
@@ -4,6 +4,7 @@ import { map } from "rxjs/operators";
|
|
|
4
4
|
import { getNip10References, interpretThreadTags } from "../helpers/threading.js";
|
|
5
5
|
import { getCoordinateFromAddressPointer, isAddressPointer, isEventPointer } from "../helpers/pointers.js";
|
|
6
6
|
import { getEventUID, getReplaceableUID, getTagValue, isEvent } from "../helpers/event.js";
|
|
7
|
+
import { COMMENT_KIND } from "../helpers/comment.js";
|
|
7
8
|
const defaultOptions = {
|
|
8
9
|
kinds: [kinds.ShortTextNote],
|
|
9
10
|
};
|
|
@@ -65,12 +66,12 @@ export function ThreadQuery(root, opts) {
|
|
|
65
66
|
})),
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
|
-
/** A query that gets all legacy and NIP-10 replies for an event */
|
|
69
|
+
/** A query that gets all legacy and NIP-10, and NIP-22 replies for an event */
|
|
69
70
|
export function RepliesQuery(event, overrideKinds) {
|
|
70
71
|
return {
|
|
71
72
|
key: getEventUID(event),
|
|
72
73
|
run: (events) => {
|
|
73
|
-
const kinds = overrideKinds || event.kind === 1 ? [1,
|
|
74
|
+
const kinds = overrideKinds || event.kind === 1 ? [1, COMMENT_KIND] : [COMMENT_KIND];
|
|
74
75
|
const filter = { kinds };
|
|
75
76
|
if (isEvent(parent) || isEventPointer(event))
|
|
76
77
|
filter["#e"] = [event.id];
|
|
@@ -82,7 +83,7 @@ export function RepliesQuery(event, overrideKinds) {
|
|
|
82
83
|
}
|
|
83
84
|
return events.timeline(filter).pipe(map((events) => {
|
|
84
85
|
return events.filter((e) => {
|
|
85
|
-
const refs = interpretThreadTags(e);
|
|
86
|
+
const refs = interpretThreadTags(e.tags);
|
|
86
87
|
return refs.reply?.e?.[1] === event.id || refs.reply?.a?.[1] === address;
|
|
87
88
|
});
|
|
88
89
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-core",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20241212192616",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -62,21 +62,10 @@
|
|
|
62
62
|
"rxjs": "^7.8.1"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@jest/globals": "^29.7.0",
|
|
66
65
|
"@types/debug": "^4.1.12",
|
|
67
66
|
"@types/hash-sum": "^1.0.2",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"jest-extended": "^4.0.2",
|
|
71
|
-
"typescript": "^5.6.3"
|
|
72
|
-
},
|
|
73
|
-
"jest": {
|
|
74
|
-
"roots": [
|
|
75
|
-
"dist"
|
|
76
|
-
],
|
|
77
|
-
"setupFilesAfterEnv": [
|
|
78
|
-
"jest-extended/all"
|
|
79
|
-
]
|
|
67
|
+
"typescript": "^5.6.3",
|
|
68
|
+
"vitest": "^2.1.8"
|
|
80
69
|
},
|
|
81
70
|
"funding": {
|
|
82
71
|
"type": "lightning",
|
|
@@ -85,7 +74,7 @@
|
|
|
85
74
|
"scripts": {
|
|
86
75
|
"build": "tsc",
|
|
87
76
|
"watch:build": "tsc --watch > /dev/null",
|
|
88
|
-
"test": "
|
|
89
|
-
"watch:test": "
|
|
77
|
+
"test": "vitest run --passWithNoTests",
|
|
78
|
+
"watch:test": "vitest"
|
|
90
79
|
}
|
|
91
80
|
}
|