applesauce-core 0.0.0-next-20251117171749 → 0.0.0-next-20251205152544
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 +6 -2
- package/dist/event-factory/event-factory.d.ts +57 -0
- package/dist/event-factory/event-factory.js +94 -0
- package/dist/event-factory/index.d.ts +3 -0
- package/dist/event-factory/index.js +3 -0
- package/dist/event-factory/methods.d.ts +17 -0
- package/dist/event-factory/methods.js +40 -0
- package/dist/event-factory/types.d.ts +76 -0
- package/dist/event-factory/types.js +1 -0
- package/dist/event-store/async-event-store.d.ts +15 -58
- package/dist/event-store/async-event-store.js +17 -22
- package/dist/event-store/event-memory.d.ts +7 -7
- package/dist/event-store/event-memory.js +5 -6
- package/dist/event-store/event-models.d.ts +76 -0
- package/dist/event-store/event-models.js +118 -0
- package/dist/event-store/event-store.d.ts +16 -61
- package/dist/event-store/event-store.js +19 -24
- package/dist/event-store/index.d.ts +1 -0
- package/dist/event-store/index.js +1 -0
- package/dist/event-store/interface.d.ts +19 -58
- package/dist/helpers/contacts.d.ts +2 -2
- package/dist/helpers/contacts.js +3 -3
- package/dist/helpers/delete.d.ts +1 -1
- package/dist/helpers/encrypted-content.js +1 -2
- package/dist/helpers/encryption.d.ts +1 -0
- package/dist/helpers/encryption.js +2 -0
- package/dist/helpers/event-cache.d.ts +1 -1
- package/dist/helpers/event.d.ts +19 -3
- package/dist/helpers/event.js +15 -4
- package/dist/helpers/expiration.d.ts +1 -1
- package/dist/helpers/factory.d.ts +32 -0
- package/dist/helpers/factory.js +117 -0
- package/dist/helpers/filter.d.ts +17 -17
- package/dist/helpers/filter.js +23 -6
- package/dist/helpers/hidden-content.js +1 -1
- package/dist/helpers/hidden-tags.js +3 -2
- package/dist/helpers/index.d.ts +4 -37
- package/dist/helpers/index.js +4 -37
- package/dist/helpers/keys.d.ts +8 -0
- package/dist/helpers/keys.js +27 -0
- package/dist/helpers/lists.d.ts +2 -2
- package/dist/helpers/lists.js +1 -2
- package/dist/helpers/mailboxes.d.ts +1 -1
- package/dist/helpers/pipeline.d.ts +16 -0
- package/dist/helpers/pipeline.js +43 -0
- package/dist/helpers/pointers.d.ts +12 -6
- package/dist/helpers/pointers.js +53 -26
- package/dist/helpers/profile.d.ts +1 -1
- package/dist/helpers/profile.js +2 -2
- package/dist/helpers/regexp.d.ts +19 -0
- package/dist/helpers/regexp.js +48 -0
- package/dist/helpers/relay-selection.d.ts +3 -1
- package/dist/helpers/relay-selection.js +33 -34
- package/dist/helpers/relays.d.ts +1 -1
- package/dist/helpers/relays.js +11 -5
- package/dist/helpers/tags.d.ts +8 -2
- package/dist/helpers/tags.js +44 -0
- package/dist/helpers/url.js +8 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/models/{common.d.ts → base.d.ts} +5 -13
- package/dist/models/{common.js → base.js} +29 -45
- package/dist/models/contacts.d.ts +1 -1
- package/dist/models/contacts.js +2 -2
- package/dist/models/encrypted-content.d.ts +1 -1
- package/dist/models/index.d.ts +2 -15
- package/dist/models/index.js +2 -15
- package/dist/models/mailboxes.d.ts +1 -1
- package/dist/models/mailboxes.js +1 -1
- package/dist/models/outbox.d.ts +1 -1
- package/dist/models/profile.d.ts +1 -1
- package/dist/models/profile.js +2 -5
- package/dist/models/relays.d.ts +2 -2
- package/dist/models/relays.js +5 -13
- package/dist/observable/claim-events.d.ts +1 -1
- package/dist/observable/claim-latest.d.ts +1 -1
- package/dist/observable/map-events-to-store.d.ts +1 -1
- package/dist/observable/map-events-to-timeline.d.ts +1 -1
- package/dist/observable/map-events-to-timeline.js +1 -1
- package/dist/observable/relay-selection.d.ts +1 -1
- package/dist/observable/watch-event-updates.d.ts +1 -1
- package/dist/operations/client.d.ts +4 -0
- package/dist/operations/client.js +23 -0
- package/dist/operations/content.d.ts +21 -0
- package/dist/operations/content.js +112 -0
- package/dist/operations/delete.d.ts +4 -0
- package/dist/operations/delete.js +17 -0
- package/dist/operations/encrypted-content.d.ts +4 -0
- package/dist/operations/encrypted-content.js +13 -0
- package/dist/operations/event.d.ts +39 -0
- package/dist/operations/event.js +107 -0
- package/dist/operations/hidden-content.d.ts +4 -0
- package/dist/operations/hidden-content.js +10 -0
- package/dist/operations/index.d.ts +7 -0
- package/dist/operations/index.js +7 -0
- package/dist/operations/mailboxes.d.ts +13 -0
- package/dist/operations/mailboxes.js +80 -0
- package/dist/operations/profile.d.ts +6 -0
- package/dist/operations/profile.js +13 -0
- package/dist/operations/tag/common.d.ts +22 -0
- package/dist/operations/tag/common.js +93 -0
- package/dist/operations/tag/index.d.ts +2 -0
- package/dist/operations/tag/index.js +2 -0
- package/dist/operations/tag/relay.d.ts +5 -0
- package/dist/operations/tag/relay.js +10 -0
- package/dist/operations/tags.d.ts +20 -0
- package/dist/operations/tags.js +93 -0
- package/package.json +18 -6
- package/dist/event-store/model-mixin.d.ts +0 -59
- package/dist/event-store/model-mixin.js +0 -147
- package/dist/helpers/app-data.d.ts +0 -39
- package/dist/helpers/app-data.js +0 -68
- package/dist/helpers/app-handlers.d.ts +0 -23
- package/dist/helpers/app-handlers.js +0 -68
- package/dist/helpers/article.d.ts +0 -15
- package/dist/helpers/article.js +0 -25
- package/dist/helpers/blossom.d.ts +0 -11
- package/dist/helpers/blossom.js +0 -40
- package/dist/helpers/bolt11.d.ts +0 -10
- package/dist/helpers/bolt11.js +0 -17
- package/dist/helpers/bookmarks.d.ts +0 -30
- package/dist/helpers/bookmarks.js +0 -96
- package/dist/helpers/calendar-event.d.ts +0 -36
- package/dist/helpers/calendar-event.js +0 -110
- package/dist/helpers/calendar-rsvp.d.ts +0 -15
- package/dist/helpers/calendar-rsvp.js +0 -38
- package/dist/helpers/calendar.d.ts +0 -6
- package/dist/helpers/calendar.js +0 -11
- package/dist/helpers/channels.d.ts +0 -10
- package/dist/helpers/channels.js +0 -27
- package/dist/helpers/comment.d.ts +0 -44
- package/dist/helpers/comment.js +0 -114
- package/dist/helpers/content.d.ts +0 -3
- package/dist/helpers/content.js +0 -8
- package/dist/helpers/emoji.d.ts +0 -21
- package/dist/helpers/emoji.js +0 -34
- package/dist/helpers/encrypted-content-cache.d.ts +0 -22
- package/dist/helpers/encrypted-content-cache.js +0 -139
- package/dist/helpers/event-tags.d.ts +0 -20
- package/dist/helpers/event-tags.js +0 -34
- package/dist/helpers/file-metadata.d.ts +0 -50
- package/dist/helpers/file-metadata.js +0 -91
- package/dist/helpers/gift-wraps.d.ts +0 -67
- package/dist/helpers/gift-wraps.js +0 -205
- package/dist/helpers/groups.d.ts +0 -26
- package/dist/helpers/groups.js +0 -49
- package/dist/helpers/hashtag.d.ts +0 -2
- package/dist/helpers/hashtag.js +0 -7
- package/dist/helpers/highlight.d.ts +0 -45
- package/dist/helpers/highlight.js +0 -76
- package/dist/helpers/legacy-messages.d.ts +0 -32
- package/dist/helpers/legacy-messages.js +0 -50
- package/dist/helpers/lnurl.d.ts +0 -8
- package/dist/helpers/lnurl.js +0 -44
- package/dist/helpers/messages.d.ts +0 -31
- package/dist/helpers/messages.js +0 -57
- package/dist/helpers/mutes.d.ts +0 -33
- package/dist/helpers/mutes.js +0 -110
- package/dist/helpers/picture-post.d.ts +0 -5
- package/dist/helpers/picture-post.js +0 -6
- package/dist/helpers/poll.d.ts +0 -46
- package/dist/helpers/poll.js +0 -78
- package/dist/helpers/reactions.d.ts +0 -8
- package/dist/helpers/reactions.js +0 -56
- package/dist/helpers/reports.d.ts +0 -28
- package/dist/helpers/reports.js +0 -38
- package/dist/helpers/share.d.ts +0 -19
- package/dist/helpers/share.js +0 -44
- package/dist/helpers/stream-chat.d.ts +0 -4
- package/dist/helpers/stream-chat.js +0 -9
- package/dist/helpers/stream.d.ts +0 -31
- package/dist/helpers/stream.js +0 -81
- package/dist/helpers/threading.d.ts +0 -55
- package/dist/helpers/threading.js +0 -94
- package/dist/helpers/user-status.d.ts +0 -18
- package/dist/helpers/user-status.js +0 -22
- package/dist/helpers/wrapped-messages.d.ts +0 -14
- package/dist/helpers/wrapped-messages.js +0 -22
- package/dist/helpers/zap.d.ts +0 -46
- package/dist/helpers/zap.js +0 -125
- package/dist/models/blossom.d.ts +0 -4
- package/dist/models/blossom.js +0 -10
- package/dist/models/bookmarks.d.ts +0 -8
- package/dist/models/bookmarks.js +0 -24
- package/dist/models/calendar.d.ts +0 -6
- package/dist/models/calendar.js +0 -15
- package/dist/models/channels.d.ts +0 -11
- package/dist/models/channels.js +0 -61
- package/dist/models/comments.d.ts +0 -4
- package/dist/models/comments.js +0 -11
- package/dist/models/gift-wrap.d.ts +0 -7
- package/dist/models/gift-wrap.js +0 -20
- package/dist/models/legacy-messages.d.ts +0 -14
- package/dist/models/legacy-messages.js +0 -64
- package/dist/models/mutes.d.ts +0 -9
- package/dist/models/mutes.js +0 -26
- package/dist/models/pins.d.ts +0 -4
- package/dist/models/pins.js +0 -10
- package/dist/models/reactions.d.ts +0 -4
- package/dist/models/reactions.js +0 -16
- package/dist/models/thread.d.ts +0 -26
- package/dist/models/thread.js +0 -88
- package/dist/models/user-status.d.ts +0 -11
- package/dist/models/user-status.js +0 -33
- package/dist/models/wrapped-messages.d.ts +0 -31
- package/dist/models/wrapped-messages.js +0 -76
- package/dist/models/zaps.d.ts +0 -10
- package/dist/models/zaps.js +0 -26
package/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# applesauce-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Applesauce is a collection of utilities for building reactive nostr applications. The core package provides protocol-level functionality including an in-memory event database, generic event utilities, and basic reactive models.
|
|
4
4
|
|
|
5
5
|
## Key Components
|
|
6
6
|
|
|
7
7
|
- **Helpers**: Core utility methods for parsing and extracting data from nostr events
|
|
8
8
|
- **EventStore**: In-memory database for storing and subscribing to nostr events
|
|
9
|
-
- **
|
|
9
|
+
- **Helpers**: Core protocol-level utility methods for working with events, tags, filters, and pointers
|
|
10
|
+
- **Models**: Generic models for common nostr data patterns (profiles, reactions, zaps, etc.)
|
|
11
|
+
- **Observable**: RxJS utilities for reactive programming
|
|
12
|
+
|
|
13
|
+
> **Note**: For NIP-specific helpers and models (NIP-10 threading, NIP-22 comments, NIP-53 streams, etc.), see the [`applesauce-common`](../common/README.md) package.
|
|
10
14
|
|
|
11
15
|
## Documentation
|
|
12
16
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { EventTemplate, NostrEvent, UnsignedEvent } from "../helpers/event.js";
|
|
2
|
+
import { ModifyTagsOptions } from "../operations/tags.js";
|
|
3
|
+
import { EventFactoryTemplate } from "./methods.js";
|
|
4
|
+
import { EventBlueprint, EventFactoryContext, EventOperation, IEventFactory } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Base class that provides event creation functionality.
|
|
7
|
+
* This class can be extended by other packages to add additional helpful event creation methods.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // In another package (e.g., applesauce-common)
|
|
12
|
+
* import { EventFactory } from "applesauce-core/event-factory";
|
|
13
|
+
* import { NoteBlueprint, ReactionBlueprint } from "applesauce-common/blueprints";
|
|
14
|
+
*
|
|
15
|
+
* // Add methods to the prototype
|
|
16
|
+
* EventFactory.prototype.note = function(content, options) {
|
|
17
|
+
* return this.create(NoteBlueprint, content, options);
|
|
18
|
+
* };
|
|
19
|
+
*
|
|
20
|
+
* EventFactory.prototype.reaction = function(event, emoji) {
|
|
21
|
+
* return this.create(ReactionBlueprint, event, emoji);
|
|
22
|
+
* };
|
|
23
|
+
*
|
|
24
|
+
* // Extend the type via module augmentation
|
|
25
|
+
* declare module "applesauce-core/event-factory" {
|
|
26
|
+
* interface EventFactory {
|
|
27
|
+
* note(content: string, options?: NoteBlueprintOptions): Promise<EventTemplate>;
|
|
28
|
+
* reaction(event: NostrEvent, emoji?: string): Promise<EventTemplate>;
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class EventFactory implements IEventFactory {
|
|
34
|
+
context: EventFactoryContext;
|
|
35
|
+
constructor(context?: EventFactoryContext);
|
|
36
|
+
/** Build an event template with operations */
|
|
37
|
+
build(template: EventFactoryTemplate, ...operations: (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
38
|
+
/** Create an event from a blueprint */
|
|
39
|
+
create<T extends EventTemplate | UnsignedEvent | NostrEvent>(blueprint: EventBlueprint<T>): Promise<T>;
|
|
40
|
+
create<T extends EventTemplate | UnsignedEvent | NostrEvent, Args extends Array<any>>(blueprint: (...args: Args) => EventBlueprint<T>, ...args: Args): Promise<T>;
|
|
41
|
+
/** Modify an existing event with operations and updated the created_at */
|
|
42
|
+
modify(draft: EventTemplate | UnsignedEvent | NostrEvent, ...operations: (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
43
|
+
/** Modify a lists public and hidden tags and updated the created_at */
|
|
44
|
+
modifyTags(event: EventTemplate | UnsignedEvent | NostrEvent, tagOperations?: ModifyTagsOptions, eventOperations?: EventOperation | (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
45
|
+
/** Attaches the signers pubkey to an event template */
|
|
46
|
+
stamp(draft: EventTemplate | UnsignedEvent): Promise<UnsignedEvent>;
|
|
47
|
+
/** Signs a event template with the signer */
|
|
48
|
+
sign(draft: EventTemplate | UnsignedEvent): Promise<NostrEvent>;
|
|
49
|
+
/** Sets the signer in the context */
|
|
50
|
+
setSigner(signer: EventFactoryContext["signer"]): void;
|
|
51
|
+
/** clears the signer in the context */
|
|
52
|
+
clearSigner(): void;
|
|
53
|
+
/** sets the client in the context */
|
|
54
|
+
setClient(client: EventFactoryContext["client"]): void;
|
|
55
|
+
/** clears the client in the context */
|
|
56
|
+
clearClient(): void;
|
|
57
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { sign, stamp } from "../operations/event.js";
|
|
2
|
+
import { modifyTags } from "../operations/tags.js";
|
|
3
|
+
import { buildEvent, modifyEvent } from "./methods.js";
|
|
4
|
+
/**
|
|
5
|
+
* Base class that provides event creation functionality.
|
|
6
|
+
* This class can be extended by other packages to add additional helpful event creation methods.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // In another package (e.g., applesauce-common)
|
|
11
|
+
* import { EventFactory } from "applesauce-core/event-factory";
|
|
12
|
+
* import { NoteBlueprint, ReactionBlueprint } from "applesauce-common/blueprints";
|
|
13
|
+
*
|
|
14
|
+
* // Add methods to the prototype
|
|
15
|
+
* EventFactory.prototype.note = function(content, options) {
|
|
16
|
+
* return this.create(NoteBlueprint, content, options);
|
|
17
|
+
* };
|
|
18
|
+
*
|
|
19
|
+
* EventFactory.prototype.reaction = function(event, emoji) {
|
|
20
|
+
* return this.create(ReactionBlueprint, event, emoji);
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* // Extend the type via module augmentation
|
|
24
|
+
* declare module "applesauce-core/event-factory" {
|
|
25
|
+
* interface EventFactory {
|
|
26
|
+
* note(content: string, options?: NoteBlueprintOptions): Promise<EventTemplate>;
|
|
27
|
+
* reaction(event: NostrEvent, emoji?: string): Promise<EventTemplate>;
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class EventFactory {
|
|
33
|
+
context;
|
|
34
|
+
constructor(context = {}) {
|
|
35
|
+
this.context = context;
|
|
36
|
+
}
|
|
37
|
+
/** Build an event template with operations */
|
|
38
|
+
async build(template, ...operations) {
|
|
39
|
+
return await buildEvent(template, this.context, ...operations);
|
|
40
|
+
}
|
|
41
|
+
async create(blueprint, ...args) {
|
|
42
|
+
// Context, blueprint(context)
|
|
43
|
+
if (arguments.length === 1) {
|
|
44
|
+
return (await blueprint(this.context));
|
|
45
|
+
}
|
|
46
|
+
// Context, blueprintConstructor(...args)(context), ...args
|
|
47
|
+
else {
|
|
48
|
+
const constructor = blueprint;
|
|
49
|
+
return await constructor(...args)(this.context);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Modify an existing event with operations and updated the created_at */
|
|
53
|
+
async modify(draft, ...operations) {
|
|
54
|
+
return await modifyEvent(draft, this.context, ...operations);
|
|
55
|
+
}
|
|
56
|
+
/** Modify a lists public and hidden tags and updated the created_at */
|
|
57
|
+
async modifyTags(event, tagOperations, eventOperations) {
|
|
58
|
+
let eventOperationsArr = [];
|
|
59
|
+
// normalize event operation arg
|
|
60
|
+
if (eventOperations === undefined)
|
|
61
|
+
eventOperationsArr = [];
|
|
62
|
+
else if (typeof eventOperations === "function")
|
|
63
|
+
eventOperationsArr = [eventOperations];
|
|
64
|
+
else if (Array.isArray(eventOperations))
|
|
65
|
+
eventOperationsArr = eventOperations.filter((e) => !!e);
|
|
66
|
+
// modify event
|
|
67
|
+
return await this.modify(event, modifyTags(tagOperations), ...eventOperationsArr);
|
|
68
|
+
}
|
|
69
|
+
/** Attaches the signers pubkey to an event template */
|
|
70
|
+
async stamp(draft) {
|
|
71
|
+
return await stamp()(draft, this.context);
|
|
72
|
+
}
|
|
73
|
+
/** Signs a event template with the signer */
|
|
74
|
+
async sign(draft) {
|
|
75
|
+
return await sign()(draft, this.context);
|
|
76
|
+
}
|
|
77
|
+
// Helpers
|
|
78
|
+
/** Sets the signer in the context */
|
|
79
|
+
setSigner(signer) {
|
|
80
|
+
this.context.signer = signer;
|
|
81
|
+
}
|
|
82
|
+
/** clears the signer in the context */
|
|
83
|
+
clearSigner() {
|
|
84
|
+
this.context.signer = undefined;
|
|
85
|
+
}
|
|
86
|
+
/** sets the client in the context */
|
|
87
|
+
setClient(client) {
|
|
88
|
+
this.context.client = client;
|
|
89
|
+
}
|
|
90
|
+
/** clears the client in the context */
|
|
91
|
+
clearClient() {
|
|
92
|
+
this.context.client = undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventTemplate, NostrEvent, UnsignedEvent } from "../helpers/event.js";
|
|
2
|
+
import { EventBlueprint, EventFactoryContext, EventOperation } from "./types.js";
|
|
3
|
+
export type EventFactoryTemplate = {
|
|
4
|
+
kind: number;
|
|
5
|
+
content?: string;
|
|
6
|
+
tags?: string[][];
|
|
7
|
+
created_at?: number;
|
|
8
|
+
};
|
|
9
|
+
/** Creates an event using a template, context, and a set of operations */
|
|
10
|
+
export declare function buildEvent(template: EventFactoryTemplate, context: EventFactoryContext, ...operations: (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
11
|
+
/** Creates a blueprint function with operations */
|
|
12
|
+
export declare function blueprint(kind: number, ...operations: (EventOperation | undefined)[]): EventBlueprint;
|
|
13
|
+
/** Creates an event from a context and a blueprint */
|
|
14
|
+
export declare function createEvent<T extends EventTemplate | UnsignedEvent | NostrEvent>(context: EventFactoryContext, blueprint: EventBlueprint<T>): Promise<T>;
|
|
15
|
+
export declare function createEvent<T extends EventTemplate | UnsignedEvent | NostrEvent, Args extends Array<any>>(context: EventFactoryContext, blueprintConstructor: (...args: Args) => EventBlueprint<T>, ...args: Args): Promise<T>;
|
|
16
|
+
/** Modifies an event using a context and a set of operations */
|
|
17
|
+
export declare function modifyEvent(event: EventTemplate | UnsignedEvent | NostrEvent, context: EventFactoryContext, ...operations: (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { EncryptedContentSymbol } from "../helpers/encrypted-content.js";
|
|
2
|
+
import { eventPipe } from "../helpers/pipeline.js";
|
|
3
|
+
import { unixNow } from "../helpers/time.js";
|
|
4
|
+
import { setClient } from "../operations/client.js";
|
|
5
|
+
import { includeReplaceableIdentifier, stripSignature, stripStamp, stripSymbols, updateCreatedAt, } from "../operations/event.js";
|
|
6
|
+
/** Wraps a set of operations with common event operations */
|
|
7
|
+
function wrapCommon(...operations) {
|
|
8
|
+
return eventPipe(
|
|
9
|
+
// Remove all symbols from the event except for the encrypted content symbol
|
|
10
|
+
stripSymbols([EncryptedContentSymbol]),
|
|
11
|
+
// Ensure all addressable events have "d" tags
|
|
12
|
+
includeReplaceableIdentifier(),
|
|
13
|
+
// Apply operations
|
|
14
|
+
...operations,
|
|
15
|
+
// Include client tag if its set in the context
|
|
16
|
+
(draft, ctx) => (ctx.client ? setClient(ctx.client.name, ctx.client.address)(draft, ctx) : draft));
|
|
17
|
+
}
|
|
18
|
+
/** Creates an event using a template, context, and a set of operations */
|
|
19
|
+
export async function buildEvent(template, context, ...operations) {
|
|
20
|
+
return await wrapCommon(stripSignature(), stripStamp(), ...operations)({ created_at: unixNow(), tags: [], content: "", ...template }, context);
|
|
21
|
+
}
|
|
22
|
+
/** Creates a blueprint function with operations */
|
|
23
|
+
export function blueprint(kind, ...operations) {
|
|
24
|
+
return async (context) => await buildEvent({ kind }, context, ...operations);
|
|
25
|
+
}
|
|
26
|
+
export async function createEvent(context, blueprint, ...args) {
|
|
27
|
+
// Context, blueprint(context)
|
|
28
|
+
if (arguments.length === 2) {
|
|
29
|
+
return (await blueprint(context));
|
|
30
|
+
}
|
|
31
|
+
// Context, blueprintConstructor(...args)(context), ...args
|
|
32
|
+
else {
|
|
33
|
+
const constructor = blueprint;
|
|
34
|
+
return await constructor(...args)(context);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Modifies an event using a context and a set of operations */
|
|
38
|
+
export async function modifyEvent(event, context, ...operations) {
|
|
39
|
+
return await wrapCommon(stripSignature(), stripStamp(), updateCreatedAt(), ...operations)(event, context);
|
|
40
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EventTemplate, NostrEvent, UnsignedEvent } from "../helpers/event.js";
|
|
2
|
+
import { AddressPointer } from "../helpers/pointers.js";
|
|
3
|
+
import { ModifyTagsOptions } from "../operations/tags.js";
|
|
4
|
+
import { EventFactoryTemplate } from "./methods.js";
|
|
5
|
+
/** Nostr event signer */
|
|
6
|
+
export interface EventSigner {
|
|
7
|
+
getPublicKey: () => Promise<string> | string;
|
|
8
|
+
signEvent: (draft: EventTemplate | UnsignedEvent) => Promise<NostrEvent> | NostrEvent;
|
|
9
|
+
nip04?: {
|
|
10
|
+
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
11
|
+
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
12
|
+
};
|
|
13
|
+
nip44?: {
|
|
14
|
+
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
15
|
+
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** A context with optional methods for getting relay hints */
|
|
19
|
+
export interface RelayHintContext {
|
|
20
|
+
getEventRelayHint?: (event: string) => string | undefined | Promise<string> | Promise<undefined>;
|
|
21
|
+
getPubkeyRelayHint?: (pubkey: string) => string | undefined | Promise<string> | Promise<undefined>;
|
|
22
|
+
}
|
|
23
|
+
/** A context with an optional signer */
|
|
24
|
+
export interface EventSignerContext {
|
|
25
|
+
signer?: EventSigner;
|
|
26
|
+
}
|
|
27
|
+
export interface EventFactoryClient {
|
|
28
|
+
name: string;
|
|
29
|
+
address?: Omit<AddressPointer, "kind" | "relays">;
|
|
30
|
+
}
|
|
31
|
+
/** A context with an optional NIP-89 app pointer */
|
|
32
|
+
export interface ClientPointerContext {
|
|
33
|
+
client?: EventFactoryClient;
|
|
34
|
+
}
|
|
35
|
+
/** NIP-30 emoji type. this should be moved out of the core package to common */
|
|
36
|
+
export type Emoji = {
|
|
37
|
+
/** The emoji shortcode (without the ::) */
|
|
38
|
+
shortcode: string;
|
|
39
|
+
/** The URL to the emoji image */
|
|
40
|
+
url: string;
|
|
41
|
+
};
|
|
42
|
+
export interface EmojiContext {
|
|
43
|
+
/** An array of custom emojis that will be used for text notes */
|
|
44
|
+
emojis?: Emoji[];
|
|
45
|
+
}
|
|
46
|
+
/** All options that can be passed when building an event */
|
|
47
|
+
export interface EventFactoryContext extends ClientPointerContext, EventSignerContext, RelayHintContext, EmojiContext {
|
|
48
|
+
}
|
|
49
|
+
/** A single operation that modifies an events public or hidden tags array */
|
|
50
|
+
export type Operation<I extends unknown = unknown, R extends unknown = unknown> = (value: I, context: EventFactoryContext) => R | Promise<R>;
|
|
51
|
+
/** A single operation that modifies an events public or hidden tags array */
|
|
52
|
+
export type TagOperation = Operation<string[][], string[][]>;
|
|
53
|
+
/** A single operation that modifies an event */
|
|
54
|
+
export type EventOperation<I extends EventTemplate | UnsignedEvent | NostrEvent = EventTemplate, R extends EventTemplate | UnsignedEvent | NostrEvent = EventTemplate> = Operation<I, R>;
|
|
55
|
+
/** A method that creates a new event based on a set of operations */
|
|
56
|
+
export type EventBlueprint<T extends EventTemplate | UnsignedEvent | NostrEvent = EventTemplate> = (context: EventFactoryContext) => Promise<T>;
|
|
57
|
+
/**
|
|
58
|
+
* Core helpful event creation interface.
|
|
59
|
+
* Contains only methods that use blueprints from the core package.
|
|
60
|
+
* Other packages (like applesauce-common) can extend this interface via module augmentation.
|
|
61
|
+
*/
|
|
62
|
+
export interface IEventFactory {
|
|
63
|
+
/** Build an event template with operations */
|
|
64
|
+
build(template: EventFactoryTemplate, ...operations: (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
65
|
+
/** Create an event from a blueprint */
|
|
66
|
+
create<T extends EventTemplate | UnsignedEvent | NostrEvent>(blueprint: EventBlueprint<T>): Promise<T>;
|
|
67
|
+
create<T extends EventTemplate | UnsignedEvent | NostrEvent, Args extends Array<any>>(blueprint: (...args: Args) => EventBlueprint<T>, ...args: Args): Promise<T>;
|
|
68
|
+
/** Modify an existing event with operations and updated the created_at */
|
|
69
|
+
modify(draft: EventTemplate | UnsignedEvent | NostrEvent, ...operations: (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
70
|
+
/** Modify a lists public and hidden tags and updated the created_at */
|
|
71
|
+
modifyTags(event: EventTemplate | UnsignedEvent | NostrEvent, tagOperations?: ModifyTagsOptions, eventOperations?: EventOperation | (EventOperation | undefined)[]): Promise<EventTemplate>;
|
|
72
|
+
/** Attaches the signers pubkey to an event template */
|
|
73
|
+
stamp(draft: EventTemplate | UnsignedEvent): Promise<UnsignedEvent>;
|
|
74
|
+
/** Signs a event template with the signer */
|
|
75
|
+
sign(draft: EventTemplate | UnsignedEvent): Promise<NostrEvent>;
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,44 +1,12 @@
|
|
|
1
|
-
import { Filter, NostrEvent } from "nostr-tools";
|
|
2
|
-
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
|
|
3
1
|
import { Observable, Subject } from "rxjs";
|
|
4
|
-
import {
|
|
2
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
3
|
+
import { Filter } from "../helpers/filter.js";
|
|
4
|
+
import { AddressPointer, AddressPointerWithoutD, EventPointer } from "../helpers/pointers.js";
|
|
5
5
|
import { EventMemory } from "./event-memory.js";
|
|
6
|
+
import { EventModels } from "./event-models.js";
|
|
6
7
|
import { IAsyncEventDatabase, IAsyncEventStore } from "./interface.js";
|
|
7
|
-
declare const AsyncEventStore_base: {
|
|
8
|
-
new (...args: any[]): {
|
|
9
|
-
[x: string]: any;
|
|
10
|
-
models: Map<import("./interface.js").ModelConstructor<any, any[], import("./interface.js").IEventStore | IAsyncEventStore>, Map<string, Observable<any>>>;
|
|
11
|
-
modelKeepWarm: number;
|
|
12
|
-
model<T extends unknown, Args extends Array<any>>(constructor: import("./interface.js").ModelConstructor<T, Args, import("./interface.js").IEventStore | IAsyncEventStore>, ...args: Args): Observable<T>;
|
|
13
|
-
filters(filters: Filter | Filter[], onlyNew?: boolean): Observable<NostrEvent>;
|
|
14
|
-
event(pointer: string | EventPointer): Observable<NostrEvent | undefined>;
|
|
15
|
-
replaceable(pointer: AddressPointer | AddressPointerWithoutD): Observable<NostrEvent | undefined>;
|
|
16
|
-
replaceable(kind: number, pubkey: string, identifier?: string): Observable<NostrEvent | undefined>;
|
|
17
|
-
addressable(pointer: AddressPointer): Observable<NostrEvent | undefined>;
|
|
18
|
-
timeline(filters: Filter | Filter[], includeOldVersion?: boolean): Observable<NostrEvent[]>;
|
|
19
|
-
profile(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("../helpers/profile.js").ProfileContent | undefined>;
|
|
20
|
-
contacts(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("nostr-tools/nip19").ProfilePointer[]>;
|
|
21
|
-
mutes(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("../helpers/mutes.js").Mutes | undefined>;
|
|
22
|
-
mailboxes(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<{
|
|
23
|
-
inboxes: string[];
|
|
24
|
-
outboxes: string[];
|
|
25
|
-
} | undefined>;
|
|
26
|
-
blossomServers(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<URL[]>;
|
|
27
|
-
reactions(event: NostrEvent): Observable<import("nostr-tools").Event[]>;
|
|
28
|
-
thread(root: string | EventPointer | AddressPointer): Observable<import("../models/thread.js").Thread>;
|
|
29
|
-
comments(event: NostrEvent): Observable<import("nostr-tools").Event[]>;
|
|
30
|
-
events(ids: string[]): Observable<Record<string, NostrEvent | undefined>>;
|
|
31
|
-
replaceableSet(pointers: {
|
|
32
|
-
kind: number;
|
|
33
|
-
pubkey: string;
|
|
34
|
-
identifier?: string;
|
|
35
|
-
}[]): Observable<Record<string, NostrEvent | undefined>>;
|
|
36
|
-
};
|
|
37
|
-
} & {
|
|
38
|
-
new (): {};
|
|
39
|
-
};
|
|
40
8
|
/** An async wrapper around an async event database that handles replaceable events, deletes, and models */
|
|
41
|
-
export declare class AsyncEventStore extends
|
|
9
|
+
export declare class AsyncEventStore extends EventModels implements IAsyncEventStore {
|
|
42
10
|
database: IAsyncEventDatabase;
|
|
43
11
|
/** Optional memory database for ensuring single event instances */
|
|
44
12
|
memory: EventMemory;
|
|
@@ -46,32 +14,22 @@ export declare class AsyncEventStore extends AsyncEventStore_base implements IAs
|
|
|
46
14
|
keepOldVersions: boolean;
|
|
47
15
|
/** Enable this to keep expired events */
|
|
48
16
|
keepExpired: boolean;
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
17
|
+
/** The method used to verify events */
|
|
18
|
+
private _verifyEventMethod?;
|
|
19
|
+
/** Get the method used to verify events */
|
|
20
|
+
get verifyEvent(): undefined | ((event: NostrEvent) => boolean);
|
|
21
|
+
/** Sets the method used to verify events */
|
|
22
|
+
set verifyEvent(method: undefined | ((event: NostrEvent) => boolean));
|
|
54
23
|
/** A stream of new events added to the store */
|
|
55
|
-
insert$: Subject<import("nostr-tools").Event>;
|
|
24
|
+
insert$: Subject<import("nostr-tools/core").Event>;
|
|
56
25
|
/** A stream of events that have been updated */
|
|
57
|
-
update$: Subject<import("nostr-tools").Event>;
|
|
26
|
+
update$: Subject<import("nostr-tools/core").Event>;
|
|
58
27
|
/** A stream of events that have been removed */
|
|
59
|
-
remove$: Subject<import("nostr-tools").Event>;
|
|
28
|
+
remove$: Subject<import("nostr-tools/core").Event>;
|
|
60
29
|
/**
|
|
61
30
|
* A method that will be called when an event isn't found in the store
|
|
62
|
-
* @experimental
|
|
63
|
-
*/
|
|
64
|
-
eventLoader?: (pointer: EventPointer) => Observable<NostrEvent> | Promise<NostrEvent | undefined>;
|
|
65
|
-
/**
|
|
66
|
-
* A method that will be called when a replaceable event isn't found in the store
|
|
67
|
-
* @experimental
|
|
68
|
-
*/
|
|
69
|
-
replaceableLoader?: (pointer: AddressPointerWithoutD) => Observable<NostrEvent> | Promise<NostrEvent | undefined>;
|
|
70
|
-
/**
|
|
71
|
-
* A method that will be called when an addressable event isn't found in the store
|
|
72
|
-
* @experimental
|
|
73
31
|
*/
|
|
74
|
-
|
|
32
|
+
eventLoader?: (pointer: EventPointer | AddressPointer | AddressPointerWithoutD) => Observable<NostrEvent> | Promise<NostrEvent | undefined>;
|
|
75
33
|
constructor(database: IAsyncEventDatabase);
|
|
76
34
|
/** A method to add all events to memory to ensure there is only ever a single instance of an event */
|
|
77
35
|
private mapToMemory;
|
|
@@ -133,4 +91,3 @@ export declare class AsyncEventStore extends AsyncEventStore_base implements IAs
|
|
|
133
91
|
/** Creates an observable that emits when event is updated */
|
|
134
92
|
updated(event: string | NostrEvent): Observable<NostrEvent>;
|
|
135
93
|
}
|
|
136
|
-
export {};
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { kinds } from "nostr-tools";
|
|
2
|
-
import { isAddressableKind } from "nostr-tools/kinds";
|
|
3
1
|
import { EMPTY, filter, mergeMap, Subject, take } from "rxjs";
|
|
4
2
|
import { getDeleteCoordinates, getDeleteIds } from "../helpers/delete.js";
|
|
5
|
-
import { createReplaceableAddress, EventStoreSymbol, FromCacheSymbol, isReplaceable } from "../helpers/event.js";
|
|
3
|
+
import { createReplaceableAddress, EventStoreSymbol, FromCacheSymbol, isAddressableKind, isReplaceable, kinds, } from "../helpers/event.js";
|
|
6
4
|
import { getExpirationTimestamp } from "../helpers/expiration.js";
|
|
7
5
|
import { parseCoordinate } from "../helpers/pointers.js";
|
|
8
6
|
import { addSeenRelay, getSeenRelays } from "../helpers/relays.js";
|
|
9
7
|
import { unixNow } from "../helpers/time.js";
|
|
10
8
|
import { EventMemory } from "./event-memory.js";
|
|
11
|
-
import {
|
|
9
|
+
import { EventModels } from "./event-models.js";
|
|
10
|
+
import { verifyEvent as coreVerifyEvent } from "nostr-tools/pure";
|
|
12
11
|
/** An async wrapper around an async event database that handles replaceable events, deletes, and models */
|
|
13
|
-
export class AsyncEventStore extends
|
|
14
|
-
}) {
|
|
12
|
+
export class AsyncEventStore extends EventModels {
|
|
15
13
|
database;
|
|
16
14
|
/** Optional memory database for ensuring single event instances */
|
|
17
15
|
memory;
|
|
@@ -19,11 +17,19 @@ export class AsyncEventStore extends EventStoreModelMixin(class {
|
|
|
19
17
|
keepOldVersions = false;
|
|
20
18
|
/** Enable this to keep expired events */
|
|
21
19
|
keepExpired = false;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
/** The method used to verify events */
|
|
21
|
+
_verifyEventMethod = coreVerifyEvent;
|
|
22
|
+
/** Get the method used to verify events */
|
|
23
|
+
get verifyEvent() {
|
|
24
|
+
return this._verifyEventMethod;
|
|
25
|
+
}
|
|
26
|
+
/** Sets the method used to verify events */
|
|
27
|
+
set verifyEvent(method) {
|
|
28
|
+
this._verifyEventMethod = method;
|
|
29
|
+
if (method === undefined) {
|
|
30
|
+
console.warn("[applesauce-core] AsyncEventStore.verifyEvent is undefined; signature checks are disabled.");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
27
33
|
/** A stream of new events added to the store */
|
|
28
34
|
insert$ = new Subject();
|
|
29
35
|
/** A stream of events that have been updated */
|
|
@@ -32,19 +38,8 @@ export class AsyncEventStore extends EventStoreModelMixin(class {
|
|
|
32
38
|
remove$ = new Subject();
|
|
33
39
|
/**
|
|
34
40
|
* A method that will be called when an event isn't found in the store
|
|
35
|
-
* @experimental
|
|
36
41
|
*/
|
|
37
42
|
eventLoader;
|
|
38
|
-
/**
|
|
39
|
-
* A method that will be called when a replaceable event isn't found in the store
|
|
40
|
-
* @experimental
|
|
41
|
-
*/
|
|
42
|
-
replaceableLoader;
|
|
43
|
-
/**
|
|
44
|
-
* A method that will be called when an addressable event isn't found in the store
|
|
45
|
-
* @experimental
|
|
46
|
-
*/
|
|
47
|
-
addressableLoader;
|
|
48
43
|
constructor(database) {
|
|
49
44
|
super();
|
|
50
45
|
this.database = database;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { NostrEvent } from "
|
|
2
|
-
import {
|
|
1
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
2
|
+
import { Filter } from "../helpers/filter.js";
|
|
3
3
|
import { LRU } from "../helpers/lru.js";
|
|
4
4
|
import { IEventMemory } from "./interface.js";
|
|
5
5
|
/** An in-memory database of events */
|
|
@@ -29,15 +29,15 @@ export declare class EventMemory implements IEventMemory {
|
|
|
29
29
|
/** Gets the history of a replaceable event */
|
|
30
30
|
getReplaceableHistory(kind: number, pubkey: string, identifier?: string): NostrEvent[] | undefined;
|
|
31
31
|
/** Gets all events that match the filters */
|
|
32
|
-
getByFilters(filters:
|
|
32
|
+
getByFilters(filters: Filter | Filter[]): NostrEvent[];
|
|
33
33
|
/** Gets a timeline of events that match the filters */
|
|
34
|
-
getTimeline(filters:
|
|
34
|
+
getTimeline(filters: Filter | Filter[]): NostrEvent[];
|
|
35
35
|
/** Inserts an event into the database and notifies all subscriptions */
|
|
36
36
|
add(event: NostrEvent): NostrEvent;
|
|
37
37
|
/** Removes an event from the database and notifies all subscriptions */
|
|
38
38
|
remove(eventOrId: string | NostrEvent): boolean;
|
|
39
39
|
/** Remove multiple events that match the given filters */
|
|
40
|
-
removeByFilters(filters:
|
|
40
|
+
removeByFilters(filters: Filter | Filter[]): number;
|
|
41
41
|
/** Notify the database that an event has updated */
|
|
42
42
|
update(_event: NostrEvent): void;
|
|
43
43
|
/** A weak map of events to claim reference counts */
|
|
@@ -77,9 +77,9 @@ export declare class EventMemory implements IEventMemory {
|
|
|
77
77
|
/** Iterates over all events by id */
|
|
78
78
|
iterateIds(ids: Iterable<string>): Generator<NostrEvent>;
|
|
79
79
|
/** Returns all events that match the filter */
|
|
80
|
-
protected getEventsForFilter(filter:
|
|
80
|
+
protected getEventsForFilter(filter: Filter): Set<NostrEvent>;
|
|
81
81
|
/** Returns all events that match the filters */
|
|
82
|
-
protected getEventsForFilters(filters:
|
|
82
|
+
protected getEventsForFilters(filters: Filter[]): Set<NostrEvent>;
|
|
83
83
|
/** Resets the event set */
|
|
84
84
|
reset(): void;
|
|
85
85
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { binarySearch, insertEventIntoDescendingList } from "
|
|
2
|
-
import { getIndexableTags, INDEXABLE_TAGS } from "../helpers/
|
|
3
|
-
import { createReplaceableAddress, isReplaceable } from "../helpers/event.js";
|
|
1
|
+
import { binarySearch, createReplaceableAddress, insertEventIntoDescendingList, isReplaceable, } from "../helpers/event.js";
|
|
2
|
+
import { getIndexableTags, INDEXABLE_TAGS } from "../helpers/filter.js";
|
|
4
3
|
import { LRU } from "../helpers/lru.js";
|
|
5
4
|
import { logger } from "../logger.js";
|
|
6
5
|
/** An in-memory database of events */
|
|
@@ -377,7 +376,7 @@ export class EventMemory {
|
|
|
377
376
|
time = Array.from(this.iterateTime(filter.since, filter.until));
|
|
378
377
|
and(time);
|
|
379
378
|
}
|
|
380
|
-
// Process AND tag filters (& prefix) first - NIP-
|
|
379
|
+
// Process AND tag filters (& prefix) first - NIP-91
|
|
381
380
|
// AND takes precedence and requires ALL values to be present
|
|
382
381
|
for (const t of INDEXABLE_TAGS) {
|
|
383
382
|
const key = `&${t}`;
|
|
@@ -391,7 +390,7 @@ export class EventMemory {
|
|
|
391
390
|
}
|
|
392
391
|
}
|
|
393
392
|
// Process OR tag filters (# prefix)
|
|
394
|
-
// Skip values that are in AND tags (NIP-
|
|
393
|
+
// Skip values that are in AND tags (NIP-91 rule)
|
|
395
394
|
for (const t of INDEXABLE_TAGS) {
|
|
396
395
|
const key = `#${t}`;
|
|
397
396
|
const values = filter[key];
|
|
@@ -399,7 +398,7 @@ export class EventMemory {
|
|
|
399
398
|
// Check if there's a corresponding AND filter for this tag
|
|
400
399
|
const andKey = `&${t}`;
|
|
401
400
|
const andValues = filter[andKey];
|
|
402
|
-
//
|
|
401
|
+
// Filterout values that are in AND tags (NIP-91 rule)
|
|
403
402
|
const filteredValues = andValues ? values.filter((v) => !andValues.includes(v)) : values;
|
|
404
403
|
// Only apply OR filter if there are values left after filtering
|
|
405
404
|
if (filteredValues.length > 0)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
3
|
+
import { Filter } from "../helpers/filter.js";
|
|
4
|
+
import { AddressPointer, AddressPointerWithoutD, EventPointer, ProfilePointer } from "../helpers/pointers.js";
|
|
5
|
+
import { ProfileContent } from "../helpers/profile.js";
|
|
6
|
+
import { IAsyncEventStore, IEventStore, ModelConstructor } from "./interface.js";
|
|
7
|
+
/**
|
|
8
|
+
* Core helpful subscriptions interface.
|
|
9
|
+
* Contains only methods that use models from the core package.
|
|
10
|
+
* Other packages (like applesauce-common) can extend this interface via module augmentation.
|
|
11
|
+
*/
|
|
12
|
+
export interface IEventStoreModels {
|
|
13
|
+
/** Subscribe to a users profile */
|
|
14
|
+
profile(user: string | ProfilePointer): Observable<ProfileContent | undefined>;
|
|
15
|
+
/** Subscribe to a users contacts */
|
|
16
|
+
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]>;
|
|
17
|
+
/** Subscribe to a users mailboxes */
|
|
18
|
+
mailboxes(user: string | ProfilePointer): Observable<{
|
|
19
|
+
inboxes: string[];
|
|
20
|
+
outboxes: string[];
|
|
21
|
+
} | undefined>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Base class that provides model functionality for both sync and async event stores.
|
|
25
|
+
* This class can be extended by other packages to add additional helpful subscription methods.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // In another package (e.g., applesauce-common)
|
|
30
|
+
* import { EventModels } from "applesauce-core/event-store";
|
|
31
|
+
*
|
|
32
|
+
* // Add methods to the prototype
|
|
33
|
+
* EventModels.prototype.mutes = function(user) {
|
|
34
|
+
* return this.model(MuteModel, user);
|
|
35
|
+
* };
|
|
36
|
+
*
|
|
37
|
+
* // Extend the type via module augmentation
|
|
38
|
+
* declare module "applesauce-core/event-store" {
|
|
39
|
+
* interface EventModels {
|
|
40
|
+
* mutes(user: string | ProfilePointer): Observable<Mutes | undefined>;
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class EventModels<TStore extends IEventStore | IAsyncEventStore = IEventStore | IAsyncEventStore> implements IEventStoreModels {
|
|
46
|
+
/** A directory of all active models */
|
|
47
|
+
models: Map<ModelConstructor<any, any[], TStore>, Map<string, Observable<any>>>;
|
|
48
|
+
/** How long a model should be kept "warm" while nothing is subscribed to it */
|
|
49
|
+
modelKeepWarm: number;
|
|
50
|
+
/** Get or create a model on the event store */
|
|
51
|
+
model<T extends unknown, Args extends Array<any>>(constructor: ModelConstructor<T, Args, TStore>, ...args: Args): Observable<T>;
|
|
52
|
+
/**
|
|
53
|
+
* Creates an observable that streams all events that match the filter
|
|
54
|
+
* @param filters
|
|
55
|
+
* @param [onlyNew=false] Only subscribe to new events
|
|
56
|
+
*/
|
|
57
|
+
filters(filters: Filter | Filter[], onlyNew?: boolean): Observable<NostrEvent>;
|
|
58
|
+
/** Creates a {@link EventModel} */
|
|
59
|
+
event(pointer: string | EventPointer): Observable<NostrEvent | undefined>;
|
|
60
|
+
/** Subscribe to a replaceable event by pointer */
|
|
61
|
+
replaceable(pointer: AddressPointer | AddressPointerWithoutD): Observable<NostrEvent | undefined>;
|
|
62
|
+
replaceable(kind: number, pubkey: string, identifier?: string): Observable<NostrEvent | undefined>;
|
|
63
|
+
/** Subscribe to an addressable event by pointer */
|
|
64
|
+
addressable(pointer: AddressPointer): Observable<NostrEvent | undefined>;
|
|
65
|
+
/** Creates a {@link TimelineModel} */
|
|
66
|
+
timeline(filters: Filter | Filter[], includeOldVersion?: boolean): Observable<NostrEvent[]>;
|
|
67
|
+
/** Subscribe to a users profile */
|
|
68
|
+
profile(user: string | ProfilePointer): Observable<ProfileContent | undefined>;
|
|
69
|
+
/** Subscribe to a users contacts */
|
|
70
|
+
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]>;
|
|
71
|
+
/** Subscribe to a users mailboxes */
|
|
72
|
+
mailboxes(user: string | ProfilePointer): Observable<{
|
|
73
|
+
inboxes: string[];
|
|
74
|
+
outboxes: string[];
|
|
75
|
+
} | undefined>;
|
|
76
|
+
}
|