applesauce-common 0.0.0-next-20251209200210 → 0.0.0-next-20251220152312
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/blueprints/__register__.d.ts +6 -0
- package/dist/blueprints/__register__.js +7 -0
- package/dist/blueprints/group-mangement.d.ts +25 -0
- package/dist/blueprints/group-mangement.js +40 -0
- package/dist/blueprints/index.d.ts +1 -0
- package/dist/blueprints/index.js +1 -0
- package/dist/casts/article.d.ts +17 -0
- package/dist/casts/article.js +41 -0
- package/dist/casts/bookmarks.d.ts +35 -0
- package/dist/casts/bookmarks.js +79 -0
- package/dist/casts/cast.d.ts +30 -0
- package/dist/casts/cast.js +67 -0
- package/dist/casts/comment.d.ts +16 -0
- package/dist/casts/comment.js +49 -0
- package/dist/casts/index.d.ts +12 -0
- package/dist/casts/index.js +12 -0
- package/dist/casts/mutes.d.ts +23 -0
- package/dist/casts/mutes.js +54 -0
- package/dist/casts/note.d.ts +17 -0
- package/dist/casts/note.js +46 -0
- package/dist/casts/profile.d.ts +16 -0
- package/dist/casts/profile.js +40 -0
- package/dist/casts/relay-lists.d.ts +33 -0
- package/dist/casts/relay-lists.js +72 -0
- package/dist/casts/share.d.ts +13 -0
- package/dist/casts/share.js +28 -0
- package/dist/casts/stream.d.ts +43 -0
- package/dist/casts/stream.js +116 -0
- package/dist/casts/user.d.ts +38 -0
- package/dist/casts/user.js +169 -0
- package/dist/casts/zap.d.ts +17 -0
- package/dist/casts/zap.js +47 -0
- package/dist/helpers/bookmark.d.ts +18 -17
- package/dist/helpers/bookmark.js +36 -49
- package/dist/helpers/encrypted-content-cache.js +23 -25
- package/dist/helpers/gift-wrap.js +11 -5
- package/dist/helpers/groups.d.ts +118 -6
- package/dist/helpers/groups.js +287 -10
- package/dist/helpers/index.d.ts +1 -1
- package/dist/helpers/index.js +1 -1
- package/dist/helpers/lists.d.ts +0 -1
- package/dist/helpers/lists.js +4 -5
- package/dist/helpers/mute.d.ts +14 -11
- package/dist/helpers/mute.js +9 -4
- package/dist/helpers/relay-list.d.ts +14 -0
- package/dist/helpers/relay-list.js +18 -0
- package/dist/helpers/stream-chat.d.ts +4 -1
- package/dist/helpers/stream-chat.js +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/__register__.d.ts +5 -0
- package/dist/models/__register__.js +6 -0
- package/dist/models/bookmarks.d.ts +3 -5
- package/dist/models/bookmarks.js +2 -10
- package/dist/models/index.d.ts +3 -1
- package/dist/models/index.js +4 -1
- package/dist/models/mutes.d.ts +5 -5
- package/dist/models/{relays.js → relay-lists.js} +2 -1
- package/dist/models/shares.d.ts +3 -0
- package/dist/models/shares.js +5 -0
- package/dist/models/thread.js +30 -24
- package/dist/observable/cast-stream.d.ts +8 -0
- package/dist/observable/cast-stream.js +29 -0
- package/dist/observable/chainable.d.ts +50 -0
- package/dist/observable/chainable.js +79 -0
- package/dist/observable/index.d.ts +2 -0
- package/dist/observable/index.js +2 -0
- package/dist/operations/group.d.ts +14 -1
- package/dist/operations/group.js +42 -4
- package/dist/operations/index.d.ts +1 -1
- package/dist/operations/index.js +1 -1
- package/dist/operations/tag/bookmarks.d.ts +3 -2
- package/dist/operations/tag/bookmarks.js +34 -14
- package/dist/register.d.ts +2 -11
- package/dist/register.js +2 -11
- package/package.json +12 -2
- package/dist/helpers/mailboxes.d.ts +0 -7
- package/dist/helpers/mailboxes.js +0 -49
- /package/dist/models/{relays.d.ts → relay-lists.d.ts} +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { GroupMetadata, GroupPointer } from "../helpers/groups.js";
|
|
3
|
+
/** Options for group membership blueprints that support previous references */
|
|
4
|
+
export type GroupMembershipOptions = {
|
|
5
|
+
previous?: NostrEvent[];
|
|
6
|
+
reason?: string;
|
|
7
|
+
};
|
|
8
|
+
/** A blueprint for a NIP-29 join request (kind 9021) */
|
|
9
|
+
export declare function GroupJoinRequestBlueprint(group: GroupPointer, reason?: string, inviteCode?: string): import("applesauce-core/event-factory").EventBlueprint;
|
|
10
|
+
/** A blueprint for a NIP-29 leave request (kind 9022) */
|
|
11
|
+
export declare function GroupLeaveRequestBlueprint(group: GroupPointer, reason?: string): import("applesauce-core/event-factory").EventBlueprint;
|
|
12
|
+
/** A blueprint for a NIP-29 put user moderation event (kind 9000) */
|
|
13
|
+
export declare function PutUserBlueprint(group: GroupPointer, pubkey: string, roles?: string[], options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
14
|
+
/** A blueprint for a NIP-29 remove user moderation event (kind 9001) */
|
|
15
|
+
export declare function GroupRemoveUserBlueprint(group: GroupPointer, pubkey: string, options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
16
|
+
/** A blueprint for a NIP-29 edit metadata moderation event (kind 9002) */
|
|
17
|
+
export declare function GroupEditMetadataBlueprint(group: GroupPointer, fields: Partial<GroupMetadata>, options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
18
|
+
/** A blueprint for a NIP-29 delete event moderation event (kind 9005) */
|
|
19
|
+
export declare function GroupDeleteEventBlueprint(group: GroupPointer, eventId: string, options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
20
|
+
/** A blueprint for a NIP-29 create group moderation event (kind 9007) */
|
|
21
|
+
export declare function GroupCreateGroupBlueprint(group: GroupPointer, options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
22
|
+
/** A blueprint for a NIP-29 delete group moderation event (kind 9008) */
|
|
23
|
+
export declare function GroupDeleteGroupBlueprint(group: GroupPointer, options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
24
|
+
/** A blueprint for a NIP-29 create invite moderation event (kind 9009) */
|
|
25
|
+
export declare function GroupCreateInviteBlueprint(group: GroupPointer, options?: GroupMembershipOptions): import("applesauce-core/event-factory").EventBlueprint;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { blueprint } from "applesauce-core/event-factory";
|
|
2
|
+
import { setContent } from "applesauce-core/operations/content";
|
|
3
|
+
import { CREATE_GROUP_KIND, CREATE_INVITE_KIND, DELETE_EVENT_KIND, DELETE_GROUP_KIND, EDIT_METADATA_KIND, JOIN_REQUEST_KIND, LEAVE_REQUEST_KIND, PUT_USER_KIND, REMOVE_USER_KIND, } from "../helpers/groups.js";
|
|
4
|
+
import { addPreviousRefs, setDeleteEventTags, setEditMetadataTags, setGroupPointer, setJoinRequestTags, setLeaveRequestTags, setPutUserTags, setRemoveUserTags, } from "../operations/group.js";
|
|
5
|
+
/** A blueprint for a NIP-29 join request (kind 9021) */
|
|
6
|
+
export function GroupJoinRequestBlueprint(group, reason, inviteCode) {
|
|
7
|
+
return blueprint(JOIN_REQUEST_KIND, setGroupPointer(group), setJoinRequestTags(group, inviteCode), reason ? setContent(reason) : undefined);
|
|
8
|
+
}
|
|
9
|
+
/** A blueprint for a NIP-29 leave request (kind 9022) */
|
|
10
|
+
export function GroupLeaveRequestBlueprint(group, reason) {
|
|
11
|
+
return blueprint(LEAVE_REQUEST_KIND, setGroupPointer(group), setLeaveRequestTags(group), reason ? setContent(reason) : undefined);
|
|
12
|
+
}
|
|
13
|
+
/** A blueprint for a NIP-29 put user moderation event (kind 9000) */
|
|
14
|
+
export function PutUserBlueprint(group, pubkey, roles, options) {
|
|
15
|
+
return blueprint(PUT_USER_KIND, setGroupPointer(group), setPutUserTags(pubkey, roles), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
16
|
+
}
|
|
17
|
+
/** A blueprint for a NIP-29 remove user moderation event (kind 9001) */
|
|
18
|
+
export function GroupRemoveUserBlueprint(group, pubkey, options) {
|
|
19
|
+
return blueprint(REMOVE_USER_KIND, setGroupPointer(group), setRemoveUserTags(pubkey), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
20
|
+
}
|
|
21
|
+
/** A blueprint for a NIP-29 edit metadata moderation event (kind 9002) */
|
|
22
|
+
export function GroupEditMetadataBlueprint(group, fields, options) {
|
|
23
|
+
return blueprint(EDIT_METADATA_KIND, setGroupPointer(group), setEditMetadataTags(fields), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
24
|
+
}
|
|
25
|
+
/** A blueprint for a NIP-29 delete event moderation event (kind 9005) */
|
|
26
|
+
export function GroupDeleteEventBlueprint(group, eventId, options) {
|
|
27
|
+
return blueprint(DELETE_EVENT_KIND, setGroupPointer(group), setDeleteEventTags(eventId), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
28
|
+
}
|
|
29
|
+
/** A blueprint for a NIP-29 create group moderation event (kind 9007) */
|
|
30
|
+
export function GroupCreateGroupBlueprint(group, options) {
|
|
31
|
+
return blueprint(CREATE_GROUP_KIND, setGroupPointer(group), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
32
|
+
}
|
|
33
|
+
/** A blueprint for a NIP-29 delete group moderation event (kind 9008) */
|
|
34
|
+
export function GroupDeleteGroupBlueprint(group, options) {
|
|
35
|
+
return blueprint(DELETE_GROUP_KIND, setGroupPointer(group), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
36
|
+
}
|
|
37
|
+
/** A blueprint for a NIP-29 create invite moderation event (kind 9009) */
|
|
38
|
+
export function GroupCreateInviteBlueprint(group, options) {
|
|
39
|
+
return blueprint(CREATE_INVITE_KIND, setGroupPointer(group), options?.previous && options.previous.length > 0 ? addPreviousRefs(options.previous) : undefined, options?.reason ? setContent(options.reason) : undefined);
|
|
40
|
+
}
|
|
@@ -7,6 +7,7 @@ export * from "./file-metadata.js";
|
|
|
7
7
|
export * from "./follow-set.js";
|
|
8
8
|
export * from "./gift-wrap.js";
|
|
9
9
|
export * from "./group.js";
|
|
10
|
+
export * from "./group-mangement.js";
|
|
10
11
|
export * from "./delete.js";
|
|
11
12
|
export * from "./highlight.js";
|
|
12
13
|
export * from "./legacy-message.js";
|
package/dist/blueprints/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./file-metadata.js";
|
|
|
7
7
|
export * from "./follow-set.js";
|
|
8
8
|
export * from "./gift-wrap.js";
|
|
9
9
|
export * from "./group.js";
|
|
10
|
+
export * from "./group-mangement.js";
|
|
10
11
|
export * from "./delete.js";
|
|
11
12
|
export * from "./highlight.js";
|
|
12
13
|
export * from "./legacy-message.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers";
|
|
2
|
+
import { ArticleEvent } from "../helpers/article.js";
|
|
3
|
+
import { CastRefEventStore, EventCast } from "./cast.js";
|
|
4
|
+
export declare class Article extends EventCast<ArticleEvent> {
|
|
5
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
6
|
+
get title(): string;
|
|
7
|
+
get image(): string | undefined;
|
|
8
|
+
get summary(): string | undefined;
|
|
9
|
+
get published(): number;
|
|
10
|
+
get publishedDate(): Date;
|
|
11
|
+
get pointer(): import("nostr-tools/nip19").AddressPointer;
|
|
12
|
+
/** An observable of the address with relay hints from the authors outboxes */
|
|
13
|
+
get pointer$(): import("applesauce-core").Observable<import("nostr-tools/nip19").AddressPointer>;
|
|
14
|
+
get address(): `naddr1${string}`;
|
|
15
|
+
/** An observable of the address with relay hints from the authors outboxes */
|
|
16
|
+
get address$(): import("applesauce-core").Observable<`naddr1${string}`>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { withImmediateValueOrDefault } from "applesauce-core";
|
|
2
|
+
import { addRelayHintsToPointer, getAddressPointerForEvent, naddrEncode } from "applesauce-core/helpers";
|
|
3
|
+
import { map } from "rxjs";
|
|
4
|
+
import { getArticleImage, getArticlePublished, getArticleSummary, getArticleTitle, isValidArticle, } from "../helpers/article.js";
|
|
5
|
+
import { EventCast } from "./cast.js";
|
|
6
|
+
export class Article extends EventCast {
|
|
7
|
+
constructor(event, store) {
|
|
8
|
+
if (!isValidArticle(event))
|
|
9
|
+
throw new Error("Invalid article");
|
|
10
|
+
super(event, store);
|
|
11
|
+
}
|
|
12
|
+
get title() {
|
|
13
|
+
return getArticleTitle(this.event);
|
|
14
|
+
}
|
|
15
|
+
get image() {
|
|
16
|
+
return getArticleImage(this.event);
|
|
17
|
+
}
|
|
18
|
+
get summary() {
|
|
19
|
+
return getArticleSummary(this.event);
|
|
20
|
+
}
|
|
21
|
+
get published() {
|
|
22
|
+
return getArticlePublished(this.event);
|
|
23
|
+
}
|
|
24
|
+
get publishedDate() {
|
|
25
|
+
return new Date(this.published * 1000);
|
|
26
|
+
}
|
|
27
|
+
get pointer() {
|
|
28
|
+
return getAddressPointerForEvent(this.event);
|
|
29
|
+
}
|
|
30
|
+
/** An observable of the address with relay hints from the authors outboxes */
|
|
31
|
+
get pointer$() {
|
|
32
|
+
return this.author.outboxes$.pipe(withImmediateValueOrDefault(undefined), map((outboxes) => (outboxes ? addRelayHintsToPointer(this.pointer, outboxes.slice(0, 3)) : this.pointer)));
|
|
33
|
+
}
|
|
34
|
+
get address() {
|
|
35
|
+
return naddrEncode(this.pointer);
|
|
36
|
+
}
|
|
37
|
+
/** An observable of the address with relay hints from the authors outboxes */
|
|
38
|
+
get address$() {
|
|
39
|
+
return this.pointer$.pipe(map((pointer) => naddrEncode(pointer)));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { HiddenContentSigner, NostrEvent } from "applesauce-core/helpers";
|
|
2
|
+
import { BookmarkListEvent, BookmarkSetEvent } from "../helpers/bookmark.js";
|
|
3
|
+
import { Article } from "./article.js";
|
|
4
|
+
import { CastRefEventStore, EventCast } from "./cast.js";
|
|
5
|
+
import { Note } from "./note.js";
|
|
6
|
+
/** Base class for bookmarks lists and sets */
|
|
7
|
+
declare class BookmarksListBase<T extends BookmarkListEvent | BookmarkSetEvent> extends EventCast<T> {
|
|
8
|
+
constructor(event: T, store: CastRefEventStore);
|
|
9
|
+
get bookmarks(): import("../helpers/bookmark.js").BookmarkPointer[];
|
|
10
|
+
get articles(): import("nostr-tools/nip19").AddressPointer[];
|
|
11
|
+
get notes(): import("nostr-tools/nip19").EventPointer[];
|
|
12
|
+
get notes$(): import("../observable/chainable.js").ChainableObservable<Note[]>;
|
|
13
|
+
get articles$(): import("../observable/chainable.js").ChainableObservable<Article[]>;
|
|
14
|
+
/** Get the unlocked hidden bookmarks */
|
|
15
|
+
get hidden(): import("../helpers/bookmark.js").BookmarkPointer[] | undefined;
|
|
16
|
+
/** An observable that updates when hidden bookmarks are unlocked */
|
|
17
|
+
get hidden$(): import("../observable/chainable.js").ChainableObservable<import("../helpers/bookmark.js").BookmarkPointer[]>;
|
|
18
|
+
get hiddenNotes$(): import("../observable/chainable.js").ChainableObservable<Note[]>;
|
|
19
|
+
get hiddenArticles$(): import("../observable/chainable.js").ChainableObservable<Article[]>;
|
|
20
|
+
/** Whether the bookmark set has hidden bookmarks */
|
|
21
|
+
get hasHidden(): boolean;
|
|
22
|
+
/** Whether the bookmark set is unlocked */
|
|
23
|
+
get unlocked(): boolean;
|
|
24
|
+
/** Unlocks the hidden bookmarks on the bookmark set */
|
|
25
|
+
unlock(signer: HiddenContentSigner): Promise<import("../helpers/bookmark.js").BookmarkPointer[]>;
|
|
26
|
+
}
|
|
27
|
+
/** A class for bookmarks lists (kind 10003) */
|
|
28
|
+
export declare class BookmarksList extends BookmarksListBase<BookmarkListEvent> {
|
|
29
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
30
|
+
}
|
|
31
|
+
/** A class for bookmarks sets (kind 30003) */
|
|
32
|
+
export declare class BookmarksSet extends BookmarksListBase<BookmarkSetEvent> {
|
|
33
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { hasHiddenContent, isAddressPointer, isEventPointer, } from "applesauce-core/helpers";
|
|
2
|
+
import { defined, watchEventUpdates } from "applesauce-core/observable";
|
|
3
|
+
import { combineLatest, map, of, switchMap } from "rxjs";
|
|
4
|
+
import { getBookmarks, getHiddenBookmarks, isHiddenBookmarksUnlocked, isValidBookmarkList, isValidBookmarkSet, unlockHiddenBookmarks, } from "../helpers/bookmark.js";
|
|
5
|
+
import { castTimelineStream } from "../observable/cast-stream.js";
|
|
6
|
+
import { Article } from "./article.js";
|
|
7
|
+
import { EventCast } from "./cast.js";
|
|
8
|
+
import { Note } from "./note.js";
|
|
9
|
+
/** Base class for bookmarks lists and sets */
|
|
10
|
+
class BookmarksListBase extends EventCast {
|
|
11
|
+
constructor(event, store) {
|
|
12
|
+
if (!isValidBookmarkList(event) && !isValidBookmarkSet(event))
|
|
13
|
+
throw new Error("Invalid bookmark list or set");
|
|
14
|
+
super(event, store);
|
|
15
|
+
}
|
|
16
|
+
get bookmarks() {
|
|
17
|
+
return getBookmarks(this.event);
|
|
18
|
+
}
|
|
19
|
+
get articles() {
|
|
20
|
+
return this.bookmarks.filter((pointer) => isAddressPointer(pointer));
|
|
21
|
+
}
|
|
22
|
+
get notes() {
|
|
23
|
+
return this.bookmarks.filter((pointer) => isEventPointer(pointer));
|
|
24
|
+
}
|
|
25
|
+
get notes$() {
|
|
26
|
+
return this.$$ref("notes$", (store) => combineLatest(this.notes.map((pointer) => store.event(pointer))).pipe(map((arr) => arr.filter((e) => !!e)), castTimelineStream(Note, store)));
|
|
27
|
+
}
|
|
28
|
+
get articles$() {
|
|
29
|
+
return this.$$ref("articles$", (store) => combineLatest(this.articles.map((pointer) => store.replaceable(pointer))).pipe(map((arr) => arr.filter((e) => !!e)), castTimelineStream(Article, store)));
|
|
30
|
+
}
|
|
31
|
+
/** Get the unlocked hidden bookmarks */
|
|
32
|
+
get hidden() {
|
|
33
|
+
return getHiddenBookmarks(this.event);
|
|
34
|
+
}
|
|
35
|
+
/** An observable that updates when hidden bookmarks are unlocked */
|
|
36
|
+
get hidden$() {
|
|
37
|
+
return this.$$ref("hidden$", (store) => of(this.event).pipe(
|
|
38
|
+
// Watch for event updates
|
|
39
|
+
watchEventUpdates(store),
|
|
40
|
+
// Get hidden bookmarks
|
|
41
|
+
map((event) => event && getHiddenBookmarks(event)),
|
|
42
|
+
/** Only emit when the hidden bookmarks are unlocked */
|
|
43
|
+
defined()));
|
|
44
|
+
}
|
|
45
|
+
get hiddenNotes$() {
|
|
46
|
+
return this.$$ref("hiddenNotes$", (store) => this.hidden$.pipe(switchMap((hidden) => combineLatest(hidden.filter((pointer) => isEventPointer(pointer)).map((pointer) => store.event(pointer)))), map((arr) => arr.filter((e) => !!e)), castTimelineStream(Note, store)));
|
|
47
|
+
}
|
|
48
|
+
get hiddenArticles$() {
|
|
49
|
+
return this.$$ref("hiddenArticles$", (store) => this.hidden$.pipe(switchMap((hidden) => combineLatest(hidden.filter((pointer) => isAddressPointer(pointer)).map((pointer) => store.replaceable(pointer)))), map((arr) => arr.filter((e) => !!e)), castTimelineStream(Article, store)));
|
|
50
|
+
}
|
|
51
|
+
/** Whether the bookmark set has hidden bookmarks */
|
|
52
|
+
get hasHidden() {
|
|
53
|
+
return hasHiddenContent(this.event);
|
|
54
|
+
}
|
|
55
|
+
/** Whether the bookmark set is unlocked */
|
|
56
|
+
get unlocked() {
|
|
57
|
+
return isHiddenBookmarksUnlocked(this.event);
|
|
58
|
+
}
|
|
59
|
+
/** Unlocks the hidden bookmarks on the bookmark set */
|
|
60
|
+
async unlock(signer) {
|
|
61
|
+
return unlockHiddenBookmarks(this.event, signer);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** A class for bookmarks lists (kind 10003) */
|
|
65
|
+
export class BookmarksList extends BookmarksListBase {
|
|
66
|
+
constructor(event, store) {
|
|
67
|
+
if (!isValidBookmarkList(event))
|
|
68
|
+
throw new Error("Invalid bookmark list");
|
|
69
|
+
super(event, store);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** A class for bookmarks sets (kind 30003) */
|
|
73
|
+
export class BookmarksSet extends BookmarksListBase {
|
|
74
|
+
constructor(event, store) {
|
|
75
|
+
if (!isValidBookmarkSet(event))
|
|
76
|
+
throw new Error("Invalid bookmark set");
|
|
77
|
+
super(event, store);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EventModels, IEventStoreStreams, IEventSubscriptions } from "applesauce-core/event-store";
|
|
2
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
3
|
+
import { Observable } from "rxjs";
|
|
4
|
+
import { ChainableObservable } from "../observable/chainable.js";
|
|
5
|
+
/** The type of event store that is passed to cast references */
|
|
6
|
+
export type CastRefEventStore = IEventSubscriptions & EventModels & IEventStoreStreams;
|
|
7
|
+
/** A symbol used to store all the cast instances for a given event */
|
|
8
|
+
export declare const CAST_REF_SYMBOL: unique symbol;
|
|
9
|
+
/** A symbol used to store all the casts for an event */
|
|
10
|
+
export declare const CASTS_SYMBOL: unique symbol;
|
|
11
|
+
/** A class that can be used to cast a Nostr event */
|
|
12
|
+
export type CastConstructor<C extends EventCast<NostrEvent>> = new (event: NostrEvent, store: CastRefEventStore) => C;
|
|
13
|
+
/** Cast a Nostr event to a specific class */
|
|
14
|
+
export declare function castEvent<C extends EventCast<NostrEvent>>(event: NostrEvent, cls: CastConstructor<C>, store?: CastRefEventStore): C;
|
|
15
|
+
/** The base class for all casts */
|
|
16
|
+
export declare class EventCast<T extends NostrEvent = NostrEvent> {
|
|
17
|
+
#private;
|
|
18
|
+
readonly event: T;
|
|
19
|
+
readonly store: CastRefEventStore;
|
|
20
|
+
get id(): string;
|
|
21
|
+
get uid(): string;
|
|
22
|
+
get createdAt(): Date;
|
|
23
|
+
/** Get the {@link User} that authored this event */
|
|
24
|
+
get author(): import("./user.js").User;
|
|
25
|
+
/** Return the set of relays this event was seen on */
|
|
26
|
+
get seen(): Set<string> | undefined;
|
|
27
|
+
constructor(event: T, store: CastRefEventStore);
|
|
28
|
+
/** Internal method for creating a reference */
|
|
29
|
+
protected $$ref<Return extends unknown>(key: string, builder: (store: CastRefEventStore) => Observable<Return>): ChainableObservable<Return>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { getSeenRelays } from "applesauce-core/helpers";
|
|
2
|
+
import { getEventUID, getParentEventStore } from "applesauce-core/helpers/event";
|
|
3
|
+
import { chainable } from "../observable/chainable.js";
|
|
4
|
+
import { castUser } from "./user.js";
|
|
5
|
+
/** A symbol used to store all the cast instances for a given event */
|
|
6
|
+
export const CAST_REF_SYMBOL = Symbol.for("cast-ref");
|
|
7
|
+
/** A symbol used to store all the casts for an event */
|
|
8
|
+
export const CASTS_SYMBOL = Symbol.for("casts");
|
|
9
|
+
/** Cast a Nostr event to a specific class */
|
|
10
|
+
export function castEvent(event, cls, store) {
|
|
11
|
+
const casts = Reflect.get(event, CASTS_SYMBOL);
|
|
12
|
+
// If the event has already been cast to this class, return the existing cast
|
|
13
|
+
const existing = casts?.get(cls);
|
|
14
|
+
if (existing)
|
|
15
|
+
return existing;
|
|
16
|
+
if (!store) {
|
|
17
|
+
store = getParentEventStore(event);
|
|
18
|
+
if (!store)
|
|
19
|
+
throw new Error("Event is not attached to an event store, an event store must be provided");
|
|
20
|
+
}
|
|
21
|
+
// Create a new instance of the class
|
|
22
|
+
const cast = new cls(event, store);
|
|
23
|
+
if (!casts)
|
|
24
|
+
Reflect.set(event, CASTS_SYMBOL, new Map([[cls, cast]]));
|
|
25
|
+
else
|
|
26
|
+
casts.set(cls, cast);
|
|
27
|
+
return cast;
|
|
28
|
+
}
|
|
29
|
+
/** The base class for all casts */
|
|
30
|
+
export class EventCast {
|
|
31
|
+
event;
|
|
32
|
+
store;
|
|
33
|
+
get id() {
|
|
34
|
+
return this.event.id;
|
|
35
|
+
}
|
|
36
|
+
get uid() {
|
|
37
|
+
return getEventUID(this.event);
|
|
38
|
+
}
|
|
39
|
+
get createdAt() {
|
|
40
|
+
return new Date(this.event.created_at * 1000);
|
|
41
|
+
}
|
|
42
|
+
/** Get the {@link User} that authored this event */
|
|
43
|
+
get author() {
|
|
44
|
+
return castUser(this.event, this.store);
|
|
45
|
+
}
|
|
46
|
+
/** Return the set of relays this event was seen on */
|
|
47
|
+
get seen() {
|
|
48
|
+
return getSeenRelays(this.event);
|
|
49
|
+
}
|
|
50
|
+
// Enfore kind check in constructor. this will force child classes to verify the event before calling super()
|
|
51
|
+
constructor(event, store) {
|
|
52
|
+
this.event = event;
|
|
53
|
+
this.store = store;
|
|
54
|
+
}
|
|
55
|
+
/** A cache of observable references */
|
|
56
|
+
#refs = {};
|
|
57
|
+
/** Internal method for creating a reference */
|
|
58
|
+
$$ref(key, builder) {
|
|
59
|
+
// Return cached observable
|
|
60
|
+
if (this.#refs[key])
|
|
61
|
+
return this.#refs[key];
|
|
62
|
+
// Build a new observable and cache it
|
|
63
|
+
const observable = chainable(builder(this.store));
|
|
64
|
+
this.#refs[key] = observable;
|
|
65
|
+
return observable;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { CommentEvent } from "../helpers/comment.js";
|
|
3
|
+
import { CastRefEventStore, EventCast } from "./cast.js";
|
|
4
|
+
import { Zap } from "./zap.js";
|
|
5
|
+
/** Cast a kind 1111 event to a Comment */
|
|
6
|
+
export declare class Comment extends EventCast<CommentEvent> {
|
|
7
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
8
|
+
get rootPointer(): import("../helpers/comment.js").CommentPointer;
|
|
9
|
+
get replyPointer(): import("../helpers/comment.js").CommentPointer | null;
|
|
10
|
+
/** Get the event at the root of this thread */
|
|
11
|
+
get root$(): import("../observable/chainable.js").ChainableObservable<import("nostr-tools").Event | undefined>;
|
|
12
|
+
/** Get the event that this comment is replying to */
|
|
13
|
+
get parent$(): import("../observable/chainable.js").ChainableObservable<import("nostr-tools").Event | undefined>;
|
|
14
|
+
get zaps$(): import("../observable/chainable.js").ChainableObservable<Zap[]>;
|
|
15
|
+
get replies$(): import("../observable/chainable.js").ChainableObservable<Comment[]>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { of } from "rxjs";
|
|
2
|
+
import { getCommentReplyPointer, getCommentRootPointer, isValidComment } from "../helpers/comment.js";
|
|
3
|
+
import { CommentsModel } from "../models/comments.js";
|
|
4
|
+
import { EventZapsModel } from "../models/zaps.js";
|
|
5
|
+
import { castTimelineStream } from "../observable/cast-stream.js";
|
|
6
|
+
import { EventCast } from "./cast.js";
|
|
7
|
+
import { Zap } from "./zap.js";
|
|
8
|
+
/** Cast a kind 1111 event to a Comment */
|
|
9
|
+
export class Comment extends EventCast {
|
|
10
|
+
constructor(event, store) {
|
|
11
|
+
if (!isValidComment(event))
|
|
12
|
+
throw new Error("Invalid comment");
|
|
13
|
+
super(event, store);
|
|
14
|
+
}
|
|
15
|
+
get rootPointer() {
|
|
16
|
+
return getCommentRootPointer(this.event);
|
|
17
|
+
}
|
|
18
|
+
get replyPointer() {
|
|
19
|
+
return getCommentReplyPointer(this.event);
|
|
20
|
+
}
|
|
21
|
+
/** Get the event at the root of this thread */
|
|
22
|
+
get root$() {
|
|
23
|
+
return this.$$ref("root$", (store) => {
|
|
24
|
+
const pointer = this.rootPointer;
|
|
25
|
+
if (pointer.type === "event" || pointer.type === "address")
|
|
26
|
+
return store.event(pointer);
|
|
27
|
+
else
|
|
28
|
+
return of(undefined);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Get the event that this comment is replying to */
|
|
32
|
+
get parent$() {
|
|
33
|
+
return this.$$ref("parent$", (store) => {
|
|
34
|
+
const pointer = this.replyPointer;
|
|
35
|
+
if (!pointer)
|
|
36
|
+
return of(undefined);
|
|
37
|
+
else if (pointer.type === "event" || pointer.type === "address")
|
|
38
|
+
return store.event(pointer);
|
|
39
|
+
else
|
|
40
|
+
return of(undefined);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
get zaps$() {
|
|
44
|
+
return this.$$ref("zaps$", (store) => store.model(EventZapsModel, this.event).pipe(castTimelineStream(Zap, store)));
|
|
45
|
+
}
|
|
46
|
+
get replies$() {
|
|
47
|
+
return this.$$ref("replies$", (store) => store.model(CommentsModel, this.event).pipe(castTimelineStream(Comment, store)));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./article.js";
|
|
2
|
+
export * from "./bookmarks.js";
|
|
3
|
+
export * from "./cast.js";
|
|
4
|
+
export * from "./comment.js";
|
|
5
|
+
export * from "./mutes.js";
|
|
6
|
+
export * from "./note.js";
|
|
7
|
+
export * from "./profile.js";
|
|
8
|
+
export * from "./relay-lists.js";
|
|
9
|
+
export * from "./share.js";
|
|
10
|
+
export * from "./stream.js";
|
|
11
|
+
export * from "./user.js";
|
|
12
|
+
export * from "./zap.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./article.js";
|
|
2
|
+
export * from "./bookmarks.js";
|
|
3
|
+
export * from "./cast.js";
|
|
4
|
+
export * from "./comment.js";
|
|
5
|
+
export * from "./mutes.js";
|
|
6
|
+
export * from "./note.js";
|
|
7
|
+
export * from "./profile.js";
|
|
8
|
+
export * from "./relay-lists.js";
|
|
9
|
+
export * from "./share.js";
|
|
10
|
+
export * from "./stream.js";
|
|
11
|
+
export * from "./user.js";
|
|
12
|
+
export * from "./zap.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers";
|
|
2
|
+
import { HiddenContentSigner } from "applesauce-core/helpers/hidden-content";
|
|
3
|
+
import { MuteListEvent, type MutedThings } from "../helpers/mute.js";
|
|
4
|
+
import { CastRefEventStore, EventCast } from "./cast.js";
|
|
5
|
+
/** Class for mute lists (kind 10000) */
|
|
6
|
+
export declare class Mutes extends EventCast<MuteListEvent> implements MutedThings {
|
|
7
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
8
|
+
get mutes(): MutedThings;
|
|
9
|
+
get hashtags(): Set<string>;
|
|
10
|
+
get words(): Set<string>;
|
|
11
|
+
get pubkeys(): Set<string>;
|
|
12
|
+
get threads(): Set<string>;
|
|
13
|
+
/** Get the unlocked hidden mutes */
|
|
14
|
+
get hidden(): MutedThings | undefined;
|
|
15
|
+
/** An observable that updates when hidden mutes are unlocked */
|
|
16
|
+
get hidden$(): import("../observable/chainable.js").ChainableObservable<MutedThings>;
|
|
17
|
+
/** Whether the mute list has hidden mutes */
|
|
18
|
+
get hasHidden(): boolean;
|
|
19
|
+
/** Whether the mute list is unlocked */
|
|
20
|
+
get unlocked(): boolean;
|
|
21
|
+
/** Unlocks the hidden mutes on the mute list */
|
|
22
|
+
unlock(signer: HiddenContentSigner): Promise<MutedThings>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { defined, watchEventUpdates } from "applesauce-core";
|
|
2
|
+
import { hasHiddenTags } from "applesauce-core/helpers";
|
|
3
|
+
import { map, of } from "rxjs";
|
|
4
|
+
import { getHiddenMutedThings, getPublicMutedThings, isHiddenMutesUnlocked, isValidMuteList, unlockHiddenMutes, } from "../helpers/mute.js";
|
|
5
|
+
import { EventCast } from "./cast.js";
|
|
6
|
+
/** Class for mute lists (kind 10000) */
|
|
7
|
+
export class Mutes extends EventCast {
|
|
8
|
+
constructor(event, store) {
|
|
9
|
+
if (!isValidMuteList(event))
|
|
10
|
+
throw new Error("Invalid mute list");
|
|
11
|
+
super(event, store);
|
|
12
|
+
}
|
|
13
|
+
get mutes() {
|
|
14
|
+
return getPublicMutedThings(this.event);
|
|
15
|
+
}
|
|
16
|
+
get hashtags() {
|
|
17
|
+
return this.mutes.hashtags;
|
|
18
|
+
}
|
|
19
|
+
get words() {
|
|
20
|
+
return this.mutes.words;
|
|
21
|
+
}
|
|
22
|
+
get pubkeys() {
|
|
23
|
+
return this.mutes.pubkeys;
|
|
24
|
+
}
|
|
25
|
+
get threads() {
|
|
26
|
+
return this.mutes.threads;
|
|
27
|
+
}
|
|
28
|
+
/** Get the unlocked hidden mutes */
|
|
29
|
+
get hidden() {
|
|
30
|
+
return getHiddenMutedThings(this.event);
|
|
31
|
+
}
|
|
32
|
+
/** An observable that updates when hidden mutes are unlocked */
|
|
33
|
+
get hidden$() {
|
|
34
|
+
return this.$$ref("hidden$", (store) => of(this.event).pipe(
|
|
35
|
+
// Watch for event updates
|
|
36
|
+
watchEventUpdates(store),
|
|
37
|
+
// Get hidden mutes
|
|
38
|
+
map((event) => event && getHiddenMutedThings(event)),
|
|
39
|
+
// Only emit when the hidden mutes are unlocked
|
|
40
|
+
defined()));
|
|
41
|
+
}
|
|
42
|
+
/** Whether the mute list has hidden mutes */
|
|
43
|
+
get hasHidden() {
|
|
44
|
+
return hasHiddenTags(this.event);
|
|
45
|
+
}
|
|
46
|
+
/** Whether the mute list is unlocked */
|
|
47
|
+
get unlocked() {
|
|
48
|
+
return isHiddenMutesUnlocked(this.event);
|
|
49
|
+
}
|
|
50
|
+
/** Unlocks the hidden mutes on the mute list */
|
|
51
|
+
unlock(signer) {
|
|
52
|
+
return unlockHiddenMutes(this.event, signer);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventPointer, KnownEvent, NostrEvent } from "applesauce-core/helpers";
|
|
2
|
+
import { CastRefEventStore, EventCast } from "./cast.js";
|
|
3
|
+
import { Comment } from "./comment.js";
|
|
4
|
+
import { Share } from "./share.js";
|
|
5
|
+
import { Zap } from "./zap.js";
|
|
6
|
+
export declare class Note extends EventCast<KnownEvent<1>> {
|
|
7
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
8
|
+
get references(): import("../helpers/threading.js").ThreadReferences;
|
|
9
|
+
get isReply(): boolean;
|
|
10
|
+
get isRoot(): boolean;
|
|
11
|
+
/** An array of events that this note is quoting */
|
|
12
|
+
get quotePointers(): EventPointer[];
|
|
13
|
+
get replies$(): import("../observable/chainable.js").ChainableObservable<Note[]>;
|
|
14
|
+
get comments$(): import("../observable/chainable.js").ChainableObservable<Comment[]>;
|
|
15
|
+
get zaps$(): import("../observable/chainable.js").ChainableObservable<Zap[]>;
|
|
16
|
+
get shares$(): import("../observable/chainable.js").ChainableObservable<Share[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getEventPointerFromQTag, isQTag, kinds, processTags, } from "applesauce-core/helpers";
|
|
2
|
+
import { getNip10References } from "../helpers/threading.js";
|
|
3
|
+
import { CommentsModel } from "../models/comments.js";
|
|
4
|
+
import { SharesModel } from "../models/shares.js";
|
|
5
|
+
import { RepliesModel } from "../models/thread.js";
|
|
6
|
+
import { EventZapsModel } from "../models/zaps.js";
|
|
7
|
+
import { castTimelineStream } from "../observable/cast-stream.js";
|
|
8
|
+
import { EventCast } from "./cast.js";
|
|
9
|
+
import { Comment } from "./comment.js";
|
|
10
|
+
import { Share } from "./share.js";
|
|
11
|
+
import { Zap } from "./zap.js";
|
|
12
|
+
function isValidNote(event) {
|
|
13
|
+
return event.kind === kinds.ShortTextNote;
|
|
14
|
+
}
|
|
15
|
+
export class Note extends EventCast {
|
|
16
|
+
constructor(event, store) {
|
|
17
|
+
if (!isValidNote(event))
|
|
18
|
+
throw new Error("Invalid note");
|
|
19
|
+
super(event, store);
|
|
20
|
+
}
|
|
21
|
+
get references() {
|
|
22
|
+
return getNip10References(this.event);
|
|
23
|
+
}
|
|
24
|
+
get isReply() {
|
|
25
|
+
return !!this.references.reply?.e || !!this.references.reply?.a;
|
|
26
|
+
}
|
|
27
|
+
get isRoot() {
|
|
28
|
+
return !this.references.reply && !this.references.root;
|
|
29
|
+
}
|
|
30
|
+
/** An array of events that this note is quoting */
|
|
31
|
+
get quotePointers() {
|
|
32
|
+
return processTags(this.event.tags, (t) => (isQTag(t) ? t : undefined), (t) => getEventPointerFromQTag(t) ?? undefined);
|
|
33
|
+
}
|
|
34
|
+
get replies$() {
|
|
35
|
+
return this.$$ref("replies$", (store) => store.model(RepliesModel, this.event, [kinds.ShortTextNote]).pipe(castTimelineStream(Note, store)));
|
|
36
|
+
}
|
|
37
|
+
get comments$() {
|
|
38
|
+
return this.$$ref("comments$", (store) => store.model(CommentsModel, this.event).pipe(castTimelineStream(Comment, store)));
|
|
39
|
+
}
|
|
40
|
+
get zaps$() {
|
|
41
|
+
return this.$$ref("zaps$", (store) => store.model(EventZapsModel, this.event).pipe(castTimelineStream(Zap, store)));
|
|
42
|
+
}
|
|
43
|
+
get shares$() {
|
|
44
|
+
return this.$$ref("shares$", (store) => store.model(SharesModel, this.event).pipe(castTimelineStream(Share, store)));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NostrEvent, ProfileEvent } from "applesauce-core/helpers";
|
|
2
|
+
import { CastRefEventStore, EventCast } from "./cast.js";
|
|
3
|
+
/** Cast a kind 0 event to a Profile */
|
|
4
|
+
export declare class Profile extends EventCast<ProfileEvent> {
|
|
5
|
+
constructor(event: NostrEvent, store: CastRefEventStore);
|
|
6
|
+
get metadata(): import("applesauce-core/helpers").ProfileContent;
|
|
7
|
+
get name(): string | undefined;
|
|
8
|
+
get displayName(): string | undefined;
|
|
9
|
+
get about(): string | undefined;
|
|
10
|
+
get picture(): string | undefined;
|
|
11
|
+
get dnsIdentity(): string | undefined;
|
|
12
|
+
get website(): string | undefined;
|
|
13
|
+
get lud16(): string | undefined;
|
|
14
|
+
get lud06(): string | undefined;
|
|
15
|
+
get lightningAddress(): string | undefined;
|
|
16
|
+
}
|