applesauce-core 0.0.0-concord-20260710175615
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/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/casts/cast.d.ts +26 -0
- package/dist/casts/cast.js +29 -0
- package/dist/casts/event.d.ts +44 -0
- package/dist/casts/event.js +80 -0
- package/dist/casts/index.d.ts +4 -0
- package/dist/casts/index.js +4 -0
- package/dist/casts/pubkey.d.ts +32 -0
- package/dist/casts/pubkey.js +73 -0
- package/dist/casts/user.d.ts +31 -0
- package/dist/casts/user.js +49 -0
- package/dist/event-store/async-delete-manager.d.ts +26 -0
- package/dist/event-store/async-delete-manager.js +33 -0
- package/dist/event-store/async-event-store.d.ts +111 -0
- package/dist/event-store/async-event-store.js +380 -0
- package/dist/event-store/async-rumor-store.d.ts +17 -0
- package/dist/event-store/async-rumor-store.js +19 -0
- package/dist/event-store/delete-manager.d.ts +30 -0
- package/dist/event-store/delete-manager.js +103 -0
- package/dist/event-store/event-memory.d.ts +85 -0
- package/dist/event-store/event-memory.js +511 -0
- package/dist/event-store/event-models.d.ts +70 -0
- package/dist/event-store/event-models.js +146 -0
- package/dist/event-store/event-store.d.ts +111 -0
- package/dist/event-store/event-store.js +408 -0
- package/dist/event-store/expiration-manager.d.ts +44 -0
- package/dist/event-store/expiration-manager.js +113 -0
- package/dist/event-store/index.d.ts +10 -0
- package/dist/event-store/index.js +10 -0
- package/dist/event-store/interface.d.ts +217 -0
- package/dist/event-store/interface.js +1 -0
- package/dist/event-store/rumor-store.d.ts +17 -0
- package/dist/event-store/rumor-store.js +19 -0
- package/dist/factories/delete.d.ts +18 -0
- package/dist/factories/delete.js +23 -0
- package/dist/factories/event.d.ts +61 -0
- package/dist/factories/event.js +164 -0
- package/dist/factories/index.d.ts +5 -0
- package/dist/factories/index.js +5 -0
- package/dist/factories/mailboxes.d.ts +33 -0
- package/dist/factories/mailboxes.js +57 -0
- package/dist/factories/profile.d.ts +46 -0
- package/dist/factories/profile.js +80 -0
- package/dist/factories/types.d.ts +56 -0
- package/dist/factories/types.js +1 -0
- package/dist/helpers/cache.d.ts +4 -0
- package/dist/helpers/cache.js +17 -0
- package/dist/helpers/contacts.d.ts +24 -0
- package/dist/helpers/contacts.js +86 -0
- package/dist/helpers/delete.d.ts +10 -0
- package/dist/helpers/delete.js +31 -0
- package/dist/helpers/dns-identity.d.ts +7 -0
- package/dist/helpers/dns-identity.js +10 -0
- package/dist/helpers/encrypted-content.d.ts +65 -0
- package/dist/helpers/encrypted-content.js +77 -0
- package/dist/helpers/encryption.d.ts +6 -0
- package/dist/helpers/encryption.js +12 -0
- package/dist/helpers/event-cache.d.ts +17 -0
- package/dist/helpers/event-cache.js +34 -0
- package/dist/helpers/event.d.ts +102 -0
- package/dist/helpers/event.js +139 -0
- package/dist/helpers/expiration.d.ts +6 -0
- package/dist/helpers/expiration.js +15 -0
- package/dist/helpers/factory.d.ts +32 -0
- package/dist/helpers/factory.js +117 -0
- package/dist/helpers/filter.d.ts +27 -0
- package/dist/helpers/filter.js +122 -0
- package/dist/helpers/hidden-content.d.ts +52 -0
- package/dist/helpers/hidden-content.js +69 -0
- package/dist/helpers/hidden-tags.d.ts +57 -0
- package/dist/helpers/hidden-tags.js +114 -0
- package/dist/helpers/index.d.ts +26 -0
- package/dist/helpers/index.js +26 -0
- package/dist/helpers/json.d.ts +2 -0
- package/dist/helpers/json.js +9 -0
- package/dist/helpers/keys.d.ts +9 -0
- package/dist/helpers/keys.js +35 -0
- package/dist/helpers/lru.d.ts +32 -0
- package/dist/helpers/lru.js +148 -0
- package/dist/helpers/mailboxes.d.ts +11 -0
- package/dist/helpers/mailboxes.js +54 -0
- package/dist/helpers/model.d.ts +5 -0
- package/dist/helpers/model.js +17 -0
- package/dist/helpers/pipeline.d.ts +29 -0
- package/dist/helpers/pipeline.js +58 -0
- package/dist/helpers/pointers.d.ts +89 -0
- package/dist/helpers/pointers.js +382 -0
- package/dist/helpers/profile.d.ts +58 -0
- package/dist/helpers/profile.js +63 -0
- package/dist/helpers/regexp.d.ts +21 -0
- package/dist/helpers/regexp.js +54 -0
- package/dist/helpers/relay-selection.d.ts +26 -0
- package/dist/helpers/relay-selection.js +110 -0
- package/dist/helpers/relays.d.ts +16 -0
- package/dist/helpers/relays.js +62 -0
- package/dist/helpers/string.d.ts +10 -0
- package/dist/helpers/string.js +21 -0
- package/dist/helpers/tags.d.ts +37 -0
- package/dist/helpers/tags.js +94 -0
- package/dist/helpers/time.d.ts +2 -0
- package/dist/helpers/time.js +4 -0
- package/dist/helpers/url.d.ts +24 -0
- package/dist/helpers/url.js +95 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +3 -0
- package/dist/models/base.d.ts +12 -0
- package/dist/models/base.js +206 -0
- package/dist/models/contacts.d.ts +8 -0
- package/dist/models/contacts.js +26 -0
- package/dist/models/encrypted-content.d.ts +4 -0
- package/dist/models/encrypted-content.js +11 -0
- package/dist/models/index.d.ts +6 -0
- package/dist/models/index.js +6 -0
- package/dist/models/mailboxes.d.ts +7 -0
- package/dist/models/mailboxes.js +12 -0
- package/dist/models/outbox.d.ts +13 -0
- package/dist/models/outbox.js +18 -0
- package/dist/models/profile.d.ts +5 -0
- package/dist/models/profile.js +13 -0
- package/dist/observable/cast-stream.d.ts +8 -0
- package/dist/observable/cast-stream.js +29 -0
- package/dist/observable/catch-error-inline.d.ts +3 -0
- package/dist/observable/catch-error-inline.js +5 -0
- package/dist/observable/chainable.d.ts +36 -0
- package/dist/observable/chainable.js +72 -0
- package/dist/observable/claim-events.d.ts +5 -0
- package/dist/observable/claim-events.js +30 -0
- package/dist/observable/claim-latest.d.ts +5 -0
- package/dist/observable/claim-latest.js +24 -0
- package/dist/observable/combine-latest-by-index.d.ts +10 -0
- package/dist/observable/combine-latest-by-index.js +121 -0
- package/dist/observable/combine-latest-by-key.d.ts +10 -0
- package/dist/observable/combine-latest-by-key.js +136 -0
- package/dist/observable/combine-latest-by-value.d.ts +10 -0
- package/dist/observable/combine-latest-by-value.js +117 -0
- package/dist/observable/combine-latest-by.d.ts +16 -0
- package/dist/observable/combine-latest-by.js +12 -0
- package/dist/observable/defined.d.ts +3 -0
- package/dist/observable/defined.js +5 -0
- package/dist/observable/get-observable-value.d.ts +6 -0
- package/dist/observable/get-observable-value.js +12 -0
- package/dist/observable/index.d.ts +16 -0
- package/dist/observable/index.js +17 -0
- package/dist/observable/map-events-to-store.d.ts +10 -0
- package/dist/observable/map-events-to-store.js +36 -0
- package/dist/observable/map-events-to-timeline.d.ts +8 -0
- package/dist/observable/map-events-to-timeline.js +18 -0
- package/dist/observable/relay-selection.d.ts +11 -0
- package/dist/observable/relay-selection.js +51 -0
- package/dist/observable/simple-timeout.d.ts +5 -0
- package/dist/observable/simple-timeout.js +7 -0
- package/dist/observable/timeout-with-ignore.d.ts +24 -0
- package/dist/observable/timeout-with-ignore.js +33 -0
- package/dist/observable/watch-event-updates.d.ts +9 -0
- package/dist/observable/watch-event-updates.js +27 -0
- package/dist/observable/with-immediate-value.d.ts +3 -0
- package/dist/observable/with-immediate-value.js +19 -0
- package/dist/operations/client.d.ts +4 -0
- package/dist/operations/client.js +23 -0
- package/dist/operations/content.d.ts +24 -0
- package/dist/operations/content.js +116 -0
- package/dist/operations/delete.d.ts +4 -0
- package/dist/operations/delete.js +26 -0
- package/dist/operations/encrypted-content.d.ts +10 -0
- package/dist/operations/encrypted-content.js +19 -0
- package/dist/operations/event.d.ts +41 -0
- package/dist/operations/event.js +115 -0
- package/dist/operations/hidden-content.d.ts +9 -0
- package/dist/operations/hidden-content.js +15 -0
- package/dist/operations/index.d.ts +7 -0
- package/dist/operations/index.js +7 -0
- package/dist/operations/mailboxes.d.ts +17 -0
- package/dist/operations/mailboxes.js +156 -0
- package/dist/operations/profile.d.ts +6 -0
- package/dist/operations/profile.js +13 -0
- package/dist/operations/tag/common.d.ts +38 -0
- package/dist/operations/tag/common.js +121 -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 +26 -0
- package/dist/operations/tags.js +99 -0
- package/dist/promise/deferred.d.ts +6 -0
- package/dist/promise/deferred.js +15 -0
- package/dist/promise/index.d.ts +1 -0
- package/dist/promise/index.js +1 -0
- package/package.json +121 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 hzrd149
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# applesauce-core
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
## Key Components
|
|
6
|
+
|
|
7
|
+
- **Helpers**: Core utility methods for parsing and extracting data from nostr events
|
|
8
|
+
- **EventStore**: In-memory database for storing and subscribing to nostr events
|
|
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.
|
|
14
|
+
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
For detailed documentation and guides, visit:
|
|
18
|
+
|
|
19
|
+
- [Getting Started](https://applesauce.build/introduction/getting-started)
|
|
20
|
+
- [API Reference](https://applesauce.build/typedoc/)
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import { EventStore } from "applesauce-core";
|
|
26
|
+
import { ProfileModel, TimelineModel } from "applesauce-core/models";
|
|
27
|
+
import { Relay } from "nostr-tools/relay";
|
|
28
|
+
|
|
29
|
+
// Create a single EventStore instance for your app
|
|
30
|
+
const eventStore = new EventStore();
|
|
31
|
+
|
|
32
|
+
// Use any nostr library for relay connections (nostr-tools, ndk, nostrify, etc...)
|
|
33
|
+
const relay = await Relay.connect("wss://relay.example.com");
|
|
34
|
+
|
|
35
|
+
// Subscribe to events and add them to the store
|
|
36
|
+
const sub = relay.subscribe([{ authors: ["3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"] }], {
|
|
37
|
+
onevent(event) {
|
|
38
|
+
eventStore.add(event);
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Subscribe to profile changes using ProfileModel
|
|
43
|
+
const profile = eventStore.model(ProfileModel, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d");
|
|
44
|
+
|
|
45
|
+
profile.subscribe((parsed) => {
|
|
46
|
+
if (parsed) console.log(parsed);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Subscribe to a timeline of events
|
|
50
|
+
const timeline = eventStore.model(TimelineModel, { kinds: [1] });
|
|
51
|
+
|
|
52
|
+
timeline.subscribe((events) => {
|
|
53
|
+
console.log(events);
|
|
54
|
+
});
|
|
55
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EventModels, IEventStoreStreams, IEventSubscriptions } from "../event-store/index.js";
|
|
2
|
+
import { NostrEvent, StoreEvent } from "../helpers/event.js";
|
|
3
|
+
import { EventCast } from "./event.js";
|
|
4
|
+
/** The type of event store that is passed to cast references */
|
|
5
|
+
export type CastRefEventStore<E extends StoreEvent = NostrEvent> = IEventSubscriptions<E> & EventModels<E> & IEventStoreStreams<E>;
|
|
6
|
+
/** A symbol used to store all the cast instances for a given event */
|
|
7
|
+
export declare const CAST_REF_SYMBOL: unique symbol;
|
|
8
|
+
/** A symbol used to store all the casts for an event */
|
|
9
|
+
export declare const CASTS_SYMBOL: unique symbol;
|
|
10
|
+
/** A class that can be used to cast a Nostr event (or an unsigned {@link StoreEvent}/rumor) */
|
|
11
|
+
export type CastConstructor<C extends EventCast<StoreEvent>, E extends StoreEvent = NostrEvent> = new (event: NostrEvent, store: CastRefEventStore<E>) => C;
|
|
12
|
+
/**
|
|
13
|
+
* Gates {@link castEvent}'s accepted input type on whether a cast's own declared event type `T`
|
|
14
|
+
* requires a signature. If `T` carries a `sig: string` field (a `NostrEvent`-shaped cast), the
|
|
15
|
+
* input is pinned to `NostrEvent` — this rejects an unsigned rumor at compile time. Otherwise (a
|
|
16
|
+
* rumor-shaped/sig-less `T`) the input stays a loose {@link StoreEvent} — deliberately not
|
|
17
|
+
* narrowed to the cast's exact `T` (e.g. a literal `kind`), so a generic `Rumor` still satisfies
|
|
18
|
+
* a narrowed-kind rumor cast; the cast's own constructor validates the narrower shape at runtime.
|
|
19
|
+
*/
|
|
20
|
+
export type CastEventInput<T extends StoreEvent> = T extends {
|
|
21
|
+
sig: string;
|
|
22
|
+
} ? NostrEvent : StoreEvent;
|
|
23
|
+
/** @internal loose, runtime-guarded shared implementation — used by castEvent, castEventStream, and castTimelineStream */
|
|
24
|
+
export declare function performCast<C extends EventCast<StoreEvent>, E extends StoreEvent = NostrEvent>(event: StoreEvent, cls: CastConstructor<C, E>, store?: CastRefEventStore<E>): C;
|
|
25
|
+
/** Cast a Nostr event (or an unsigned StoreEvent/rumor) to a specific class */
|
|
26
|
+
export declare function castEvent<C extends EventCast<StoreEvent>, E extends StoreEvent = NostrEvent>(event: C extends EventCast<infer T> ? CastEventInput<T> : never, cls: CastConstructor<C, E>, store?: CastRefEventStore<E>): C;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getParentEventStore } from "../helpers/event.js";
|
|
2
|
+
/** A symbol used to store all the cast instances for a given event */
|
|
3
|
+
export const CAST_REF_SYMBOL = Symbol.for("cast-ref");
|
|
4
|
+
/** A symbol used to store all the casts for an event */
|
|
5
|
+
export const CASTS_SYMBOL = Symbol.for("casts");
|
|
6
|
+
/** @internal loose, runtime-guarded shared implementation — used by castEvent, castEventStream, and castTimelineStream */
|
|
7
|
+
export function performCast(event, cls, store) {
|
|
8
|
+
const casts = Reflect.get(event, CASTS_SYMBOL);
|
|
9
|
+
// If the event has already been cast to this class, return the existing cast
|
|
10
|
+
const existing = casts?.get(cls);
|
|
11
|
+
if (existing)
|
|
12
|
+
return existing;
|
|
13
|
+
if (!store) {
|
|
14
|
+
store = getParentEventStore(event);
|
|
15
|
+
if (!store)
|
|
16
|
+
throw new Error("Event is not attached to an event store, an event store must be provided");
|
|
17
|
+
}
|
|
18
|
+
// Create a new instance of the class (the constructor reads only StoreEvent fields).
|
|
19
|
+
const cast = new cls(event, store);
|
|
20
|
+
if (!casts)
|
|
21
|
+
Reflect.set(event, CASTS_SYMBOL, new Map([[cls, cast]]));
|
|
22
|
+
else
|
|
23
|
+
casts.set(cls, cast);
|
|
24
|
+
return cast;
|
|
25
|
+
}
|
|
26
|
+
/** Cast a Nostr event (or an unsigned StoreEvent/rumor) to a specific class */
|
|
27
|
+
export function castEvent(event, cls, store) {
|
|
28
|
+
return performCast(event, cls, store);
|
|
29
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { NostrEvent, StoreEvent } from "../helpers/event.js";
|
|
3
|
+
import { AddressPointer, EventPointer } from "../helpers/pointers.js";
|
|
4
|
+
import { ChainableObservable } from "../observable/chainable.js";
|
|
5
|
+
import { CastRefEventStore } from "./cast.js";
|
|
6
|
+
import { User } from "./user.js";
|
|
7
|
+
/**
|
|
8
|
+
* The base class for all casts. `T` is bounded by {@link StoreEvent} (not `NostrEvent`) so a
|
|
9
|
+
* cast can wrap an unsigned {@link Rumor} as well as a signed event — `EventCast` never reads
|
|
10
|
+
* `.sig`. The event-reading helpers below are still typed `NostrEvent`, so they are bridged
|
|
11
|
+
* with a localized `as NostrEvent`; each reads only fields present on a rumor.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EventCast<T extends StoreEvent = NostrEvent> {
|
|
14
|
+
#private;
|
|
15
|
+
readonly event: T;
|
|
16
|
+
readonly store: CastRefEventStore;
|
|
17
|
+
/**
|
|
18
|
+
* The event viewed as a signed `NostrEvent`, for the event-reading helpers that are still
|
|
19
|
+
* typed `NostrEvent` but only touch fields a rumor already has (id/kind/pubkey/created_at/
|
|
20
|
+
* tags). A documented internal bridge until those helpers are genericized over StoreEvent.
|
|
21
|
+
*/
|
|
22
|
+
private get signedView();
|
|
23
|
+
/** Alias for event.id */
|
|
24
|
+
get id(): string;
|
|
25
|
+
/** Alias for event.kind */
|
|
26
|
+
get kind(): number;
|
|
27
|
+
/** Returns the unique identifier for this event */
|
|
28
|
+
get uid(): string;
|
|
29
|
+
/** Returns the created_at timestamp as a Date object */
|
|
30
|
+
get createdAt(): Date;
|
|
31
|
+
/** Get the {@link User} that authored this event */
|
|
32
|
+
get author(): User;
|
|
33
|
+
/** Return the set of relays this event was seen on */
|
|
34
|
+
get seen(): Set<string> | undefined;
|
|
35
|
+
/** Returns the NIP-01 address string for this event if its replaceable or addressable, otherwise returns null */
|
|
36
|
+
get coordinate(): string | null;
|
|
37
|
+
/** Alias for {@link coordinate} */
|
|
38
|
+
get replaceableAddress(): string | null;
|
|
39
|
+
/** Returns a single {@link EventPointer} or {@link AddressPointer} for this event */
|
|
40
|
+
get pointer(): EventPointer | AddressPointer;
|
|
41
|
+
constructor(event: T, store: CastRefEventStore);
|
|
42
|
+
/** Internal method for creating a reference */
|
|
43
|
+
protected $$ref<Return extends unknown>(key: string, builder: (store: CastRefEventStore) => Observable<Return>): ChainableObservable<Return>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { getEventUID, isAddressableKind, isReplaceableKind } from "../helpers/event.js";
|
|
2
|
+
import { getAddressPointerForEvent, getEventPointerForEvent, getReplaceableAddressForEvent, } from "../helpers/pointers.js";
|
|
3
|
+
import { getSeenRelays } from "../helpers/relays.js";
|
|
4
|
+
import { chainable } from "../observable/chainable.js";
|
|
5
|
+
import { castUser } from "./user.js";
|
|
6
|
+
/**
|
|
7
|
+
* The base class for all casts. `T` is bounded by {@link StoreEvent} (not `NostrEvent`) so a
|
|
8
|
+
* cast can wrap an unsigned {@link Rumor} as well as a signed event — `EventCast` never reads
|
|
9
|
+
* `.sig`. The event-reading helpers below are still typed `NostrEvent`, so they are bridged
|
|
10
|
+
* with a localized `as NostrEvent`; each reads only fields present on a rumor.
|
|
11
|
+
*/
|
|
12
|
+
export class EventCast {
|
|
13
|
+
event;
|
|
14
|
+
store;
|
|
15
|
+
/**
|
|
16
|
+
* The event viewed as a signed `NostrEvent`, for the event-reading helpers that are still
|
|
17
|
+
* typed `NostrEvent` but only touch fields a rumor already has (id/kind/pubkey/created_at/
|
|
18
|
+
* tags). A documented internal bridge until those helpers are genericized over StoreEvent.
|
|
19
|
+
*/
|
|
20
|
+
get signedView() {
|
|
21
|
+
return this.event;
|
|
22
|
+
}
|
|
23
|
+
/** Alias for event.id */
|
|
24
|
+
get id() {
|
|
25
|
+
return this.event.id;
|
|
26
|
+
}
|
|
27
|
+
/** Alias for event.kind */
|
|
28
|
+
get kind() {
|
|
29
|
+
return this.event.kind;
|
|
30
|
+
}
|
|
31
|
+
/** Returns the unique identifier for this event */
|
|
32
|
+
get uid() {
|
|
33
|
+
return getEventUID(this.signedView);
|
|
34
|
+
}
|
|
35
|
+
/** Returns the created_at timestamp as a Date object */
|
|
36
|
+
get createdAt() {
|
|
37
|
+
return new Date(this.event.created_at * 1000);
|
|
38
|
+
}
|
|
39
|
+
/** Get the {@link User} that authored this event */
|
|
40
|
+
get author() {
|
|
41
|
+
// Route via the pubkey string overload: result-identical for signed events and correct for
|
|
42
|
+
// rumors (passing the event would hit `isEvent`, which requires `sig` and misroutes a rumor).
|
|
43
|
+
return castUser(this.event.pubkey, this.store);
|
|
44
|
+
}
|
|
45
|
+
/** Return the set of relays this event was seen on */
|
|
46
|
+
get seen() {
|
|
47
|
+
return getSeenRelays(this.signedView);
|
|
48
|
+
}
|
|
49
|
+
/** Returns the NIP-01 address string for this event if its replaceable or addressable, otherwise returns null */
|
|
50
|
+
get coordinate() {
|
|
51
|
+
return getReplaceableAddressForEvent(this.signedView);
|
|
52
|
+
}
|
|
53
|
+
/** Alias for {@link coordinate} */
|
|
54
|
+
get replaceableAddress() {
|
|
55
|
+
return this.coordinate;
|
|
56
|
+
}
|
|
57
|
+
/** Returns a single {@link EventPointer} or {@link AddressPointer} for this event */
|
|
58
|
+
get pointer() {
|
|
59
|
+
if (isReplaceableKind(this.kind) || isAddressableKind(this.kind))
|
|
60
|
+
return getAddressPointerForEvent(this.signedView) || getEventPointerForEvent(this.signedView);
|
|
61
|
+
return getEventPointerForEvent(this.signedView);
|
|
62
|
+
}
|
|
63
|
+
// Enfore kind check in constructor. this will force child classes to verify the event before calling super()
|
|
64
|
+
constructor(event, store) {
|
|
65
|
+
this.event = event;
|
|
66
|
+
this.store = store;
|
|
67
|
+
}
|
|
68
|
+
/** A cache of observable references */
|
|
69
|
+
#refs = {};
|
|
70
|
+
/** Internal method for creating a reference */
|
|
71
|
+
$$ref(key, builder) {
|
|
72
|
+
// Return cached observable
|
|
73
|
+
if (this.#refs[key])
|
|
74
|
+
return this.#refs[key];
|
|
75
|
+
// Build a new observable and cache it
|
|
76
|
+
const observable = chainable(builder(this.store));
|
|
77
|
+
this.#refs[key] = observable;
|
|
78
|
+
return observable;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
3
|
+
import type { ProfilePointer } from "../helpers/pointers.js";
|
|
4
|
+
import { ChainableObservable } from "../observable/chainable.js";
|
|
5
|
+
import { CastRefEventStore } from "./cast.js";
|
|
6
|
+
export type PubkeyCastConstructor<C extends PubkeyCast> = (new (pointer: ProfilePointer, store: CastRefEventStore) => C) & {
|
|
7
|
+
cache?: Map<string, WeakRef<C>>;
|
|
8
|
+
cacheRegistry?: FinalizationRegistry<string>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Cast a pubkey to a specific class instance.
|
|
12
|
+
* Works like {@link castUser} - returns a cached singleton per pubkey+relay-hints combination.
|
|
13
|
+
*
|
|
14
|
+
* @note Instances are held weakly so unused casts can be garbage collected instead of
|
|
15
|
+
* accumulating one instance per pubkey for the lifetime of the process.
|
|
16
|
+
*/
|
|
17
|
+
export declare function castPubkey<C extends PubkeyCast>(pubkey: string | NostrEvent | ProfilePointer, cls: PubkeyCastConstructor<C>, store: CastRefEventStore): C;
|
|
18
|
+
/** Base class for pubkey-based casts (analogous to {@link EventCast} for events) */
|
|
19
|
+
export declare class PubkeyCast {
|
|
20
|
+
#private;
|
|
21
|
+
readonly pointer: ProfilePointer;
|
|
22
|
+
readonly store: CastRefEventStore;
|
|
23
|
+
/** A global cache of pubkey -> weak instance reference, populated by {@link castPubkey} */
|
|
24
|
+
static cache: Map<string, WeakRef<PubkeyCast>>;
|
|
25
|
+
/** Cleans up dead {@link cache} entries when their instances are garbage collected */
|
|
26
|
+
static cacheRegistry?: FinalizationRegistry<string>;
|
|
27
|
+
constructor(pointer: ProfilePointer, store: CastRefEventStore);
|
|
28
|
+
/** The hex pubkey represented by this cast */
|
|
29
|
+
get pubkey(): string;
|
|
30
|
+
/** Internal method for creating a cached observable reference */
|
|
31
|
+
protected $$ref<Return extends unknown>(key: string, builder: (store: CastRefEventStore) => Observable<Return>): ChainableObservable<Return>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { isEvent } from "../helpers/event.js";
|
|
2
|
+
import { isHexKey } from "../helpers/string.js";
|
|
3
|
+
import { chainable } from "../observable/chainable.js";
|
|
4
|
+
const storeCacheIds = new WeakMap();
|
|
5
|
+
let nextStoreCacheId = 0;
|
|
6
|
+
function getStoreCacheId(store) {
|
|
7
|
+
let id = storeCacheIds.get(store);
|
|
8
|
+
if (id === undefined) {
|
|
9
|
+
id = ++nextStoreCacheId;
|
|
10
|
+
storeCacheIds.set(store, id);
|
|
11
|
+
}
|
|
12
|
+
return id;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Cast a pubkey to a specific class instance.
|
|
16
|
+
* Works like {@link castUser} - returns a cached singleton per pubkey+relay-hints combination.
|
|
17
|
+
*
|
|
18
|
+
* @note Instances are held weakly so unused casts can be garbage collected instead of
|
|
19
|
+
* accumulating one instance per pubkey for the lifetime of the process.
|
|
20
|
+
*/
|
|
21
|
+
export function castPubkey(pubkey, cls, store) {
|
|
22
|
+
if (isEvent(pubkey))
|
|
23
|
+
return castPubkey(pubkey.pubkey, cls, store);
|
|
24
|
+
const pointer = typeof pubkey === "string" ? { pubkey } : pubkey;
|
|
25
|
+
if (!isHexKey(pointer.pubkey))
|
|
26
|
+
throw new Error("Invalid pubkey");
|
|
27
|
+
const pointerKey = pointer.relays?.length ? `${pointer.pubkey}:${JSON.stringify(pointer.relays)}` : pointer.pubkey;
|
|
28
|
+
const cacheKey = `${getStoreCacheId(store)}:${pointerKey}`;
|
|
29
|
+
if (!cls.cache)
|
|
30
|
+
cls.cache = new Map();
|
|
31
|
+
// Clean up dead cache entries when their instances are garbage collected
|
|
32
|
+
if (!cls.cacheRegistry)
|
|
33
|
+
cls.cacheRegistry = new FinalizationRegistry((key) => {
|
|
34
|
+
// Only drop the entry if it still points at a collected instance; a re-created
|
|
35
|
+
// instance under the same key has a live ref and must be kept.
|
|
36
|
+
if (cls.cache.get(key)?.deref() === undefined)
|
|
37
|
+
cls.cache.delete(key);
|
|
38
|
+
});
|
|
39
|
+
const existing = cls.cache.get(cacheKey)?.deref();
|
|
40
|
+
if (existing)
|
|
41
|
+
return existing;
|
|
42
|
+
const instance = new cls(pointer, store);
|
|
43
|
+
cls.cache.set(cacheKey, new WeakRef(instance));
|
|
44
|
+
cls.cacheRegistry.register(instance, cacheKey);
|
|
45
|
+
return instance;
|
|
46
|
+
}
|
|
47
|
+
/** Base class for pubkey-based casts (analogous to {@link EventCast} for events) */
|
|
48
|
+
export class PubkeyCast {
|
|
49
|
+
pointer;
|
|
50
|
+
store;
|
|
51
|
+
/** A global cache of pubkey -> weak instance reference, populated by {@link castPubkey} */
|
|
52
|
+
static cache = new Map();
|
|
53
|
+
/** Cleans up dead {@link cache} entries when their instances are garbage collected */
|
|
54
|
+
static cacheRegistry;
|
|
55
|
+
constructor(pointer, store) {
|
|
56
|
+
this.pointer = pointer;
|
|
57
|
+
this.store = store;
|
|
58
|
+
}
|
|
59
|
+
/** The hex pubkey represented by this cast */
|
|
60
|
+
get pubkey() {
|
|
61
|
+
return this.pointer.pubkey;
|
|
62
|
+
}
|
|
63
|
+
/** A cache of observable references */
|
|
64
|
+
#refs = {};
|
|
65
|
+
/** Internal method for creating a cached observable reference */
|
|
66
|
+
$$ref(key, builder) {
|
|
67
|
+
if (this.#refs[key])
|
|
68
|
+
return this.#refs[key];
|
|
69
|
+
const observable = chainable(builder(this.store));
|
|
70
|
+
this.#refs[key] = observable;
|
|
71
|
+
return observable;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { NostrEvent } from "../helpers/event.js";
|
|
3
|
+
import { Filter } from "../helpers/filter.js";
|
|
4
|
+
import { ProfilePointer } from "../helpers/pointers.js";
|
|
5
|
+
import { ChainableObservable } from "../observable/chainable.js";
|
|
6
|
+
import type { CastConstructor, CastRefEventStore } from "./cast.js";
|
|
7
|
+
import { PubkeyCast } from "./pubkey.js";
|
|
8
|
+
import { EventCast } from "./event.js";
|
|
9
|
+
/** Cast a Nostr event or pointer into a {@link User} */
|
|
10
|
+
export declare function castUser(event: NostrEvent, store: CastRefEventStore): User;
|
|
11
|
+
export declare function castUser(user: string | ProfilePointer, store: CastRefEventStore): User;
|
|
12
|
+
/** A class representing a Nostr user */
|
|
13
|
+
export declare class User extends PubkeyCast {
|
|
14
|
+
/** A global cache of pubkey -> weak {@link User} reference */
|
|
15
|
+
static cache: Map<string, WeakRef<User>>;
|
|
16
|
+
/** Returns the NIP-19 npub for this user */
|
|
17
|
+
get npub(): `npub1${string}`;
|
|
18
|
+
/** Returns the NIP-19 nprofile for this user */
|
|
19
|
+
get nprofile(): `nprofile1${string}`;
|
|
20
|
+
/** Subscribe to a replaceable event for this user */
|
|
21
|
+
replaceable(kind: number, identifier?: string, relays?: string[]): ChainableObservable<NostrEvent | undefined>;
|
|
22
|
+
/** Subscribe to an addressable event for this user */
|
|
23
|
+
addressable(kind: number, identifier: string, relays?: string[]): ChainableObservable<NostrEvent | undefined>;
|
|
24
|
+
/**
|
|
25
|
+
* Creates an observable of a timeline of events created by this user
|
|
26
|
+
* @param input - The filter(s) for the timeline or kind(s)
|
|
27
|
+
* @returns A timeline observable of events by the user rom the event store
|
|
28
|
+
*/
|
|
29
|
+
timeline$(input: Omit<Filter, "authors"> | Omit<Filter, "authors">[] | number | number[]): Observable<NostrEvent[]>;
|
|
30
|
+
timeline$<T extends EventCast>(input: Omit<Filter, "authors"> | Omit<Filter, "authors">[] | number | number[], cast?: CastConstructor<T>): Observable<T[]>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import hash_sum from "hash-sum";
|
|
2
|
+
import { nprofileEncode, npubEncode } from "../helpers/pointers.js";
|
|
3
|
+
import { chainable } from "../observable/chainable.js";
|
|
4
|
+
import { castPubkey, PubkeyCast } from "./pubkey.js";
|
|
5
|
+
import { castTimelineStream } from "../observable/cast-stream.js";
|
|
6
|
+
export function castUser(user, store) {
|
|
7
|
+
return castPubkey(user, User, store);
|
|
8
|
+
}
|
|
9
|
+
/** A class representing a Nostr user */
|
|
10
|
+
export class User extends PubkeyCast {
|
|
11
|
+
/** A global cache of pubkey -> weak {@link User} reference */
|
|
12
|
+
static cache = new Map();
|
|
13
|
+
/** Returns the NIP-19 npub for this user */
|
|
14
|
+
get npub() {
|
|
15
|
+
return npubEncode(this.pubkey);
|
|
16
|
+
}
|
|
17
|
+
/** Returns the NIP-19 nprofile for this user */
|
|
18
|
+
get nprofile() {
|
|
19
|
+
return nprofileEncode(this.pointer);
|
|
20
|
+
}
|
|
21
|
+
/** Subscribe to a replaceable event for this user */
|
|
22
|
+
replaceable(kind, identifier, relays) {
|
|
23
|
+
return chainable(this.store.replaceable({ kind, pubkey: this.pointer.pubkey, identifier, relays }));
|
|
24
|
+
}
|
|
25
|
+
/** Subscribe to an addressable event for this user */
|
|
26
|
+
addressable(kind, identifier, relays) {
|
|
27
|
+
return chainable(this.store.addressable({ kind, pubkey: this.pointer.pubkey, identifier, relays }));
|
|
28
|
+
}
|
|
29
|
+
timeline$(input, cast) {
|
|
30
|
+
let filters = [];
|
|
31
|
+
if (typeof input === "number") {
|
|
32
|
+
filters.push({ kinds: [input] });
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(input)) {
|
|
35
|
+
filters.push(...input.map((f) => (typeof f === "number" ? { kinds: [f] } : f)));
|
|
36
|
+
}
|
|
37
|
+
else if (input instanceof Object) {
|
|
38
|
+
filters.push(input);
|
|
39
|
+
}
|
|
40
|
+
// Use hash_sum to create a unique key for the timeline observable
|
|
41
|
+
const key = "timeline$|" + hash_sum(filters);
|
|
42
|
+
const base$ = this.$$ref(key, (store) => store.timeline(filters.map((f) => ({ ...f, authors: [this.pubkey] }))));
|
|
43
|
+
// Cast the timeline stream into a cast if provided
|
|
44
|
+
if (cast)
|
|
45
|
+
return base$.pipe(castTimelineStream(cast));
|
|
46
|
+
else
|
|
47
|
+
return base$;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { NostrEvent, StoreEvent } from "../helpers/event.js";
|
|
3
|
+
import { DeleteEventNotification, IAsyncDeleteManager } from "./interface.js";
|
|
4
|
+
/** Async manager for deletion state, ensuring users can only delete their own events */
|
|
5
|
+
export declare class AsyncDeleteManager<E extends StoreEvent = NostrEvent> implements IAsyncDeleteManager<E> {
|
|
6
|
+
/** A stream of pointers that may have been deleted */
|
|
7
|
+
readonly deleted$: Observable<DeleteEventNotification>;
|
|
8
|
+
/** Internal sync delete manager instance for state */
|
|
9
|
+
private internal;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Process a kind 5 delete event
|
|
13
|
+
* Extracts event pointers and address pointers from the delete event
|
|
14
|
+
* Enforces that users can only delete their own events
|
|
15
|
+
*/
|
|
16
|
+
add(deleteEvent: E): Promise<DeleteEventNotification[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Check if an event is deleted
|
|
19
|
+
* Verifies the event was deleted by its own author
|
|
20
|
+
*/
|
|
21
|
+
check(event: E): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Filter out all deleted events from an array of events
|
|
24
|
+
*/
|
|
25
|
+
filter(events: E[]): Promise<E[]>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DeleteManager } from "./delete-manager.js";
|
|
2
|
+
/** Async manager for deletion state, ensuring users can only delete their own events */
|
|
3
|
+
export class AsyncDeleteManager {
|
|
4
|
+
/** A stream of pointers that may have been deleted */
|
|
5
|
+
deleted$;
|
|
6
|
+
/** Internal sync delete manager instance for state */
|
|
7
|
+
internal;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.internal = new DeleteManager();
|
|
10
|
+
this.deleted$ = this.internal.deleted$;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Process a kind 5 delete event
|
|
14
|
+
* Extracts event pointers and address pointers from the delete event
|
|
15
|
+
* Enforces that users can only delete their own events
|
|
16
|
+
*/
|
|
17
|
+
async add(deleteEvent) {
|
|
18
|
+
return this.internal.add(deleteEvent);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if an event is deleted
|
|
22
|
+
* Verifies the event was deleted by its own author
|
|
23
|
+
*/
|
|
24
|
+
async check(event) {
|
|
25
|
+
return this.internal.check(event);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Filter out all deleted events from an array of events
|
|
29
|
+
*/
|
|
30
|
+
async filter(events) {
|
|
31
|
+
return this.internal.filter(events);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Observable, Subject } from "rxjs";
|
|
2
|
+
import { NostrEvent, StoreEvent } from "../helpers/event.js";
|
|
3
|
+
import { Filter } from "../helpers/filter.js";
|
|
4
|
+
import { AddressPointer, AddressPointerWithoutD, EventPointer } from "../helpers/pointers.js";
|
|
5
|
+
import { EventMemory } from "./event-memory.js";
|
|
6
|
+
import { EventModels } from "./event-models.js";
|
|
7
|
+
import { IAsyncDeleteManager, IAsyncEventDatabase, IAsyncEventStore, IExpirationManager } from "./interface.js";
|
|
8
|
+
export type AsyncEventStoreOptions<E extends StoreEvent = NostrEvent> = {
|
|
9
|
+
/** Keep deleted events in the store */
|
|
10
|
+
keepDeleted?: boolean;
|
|
11
|
+
/** Keep expired events in the store */
|
|
12
|
+
keepExpired?: boolean;
|
|
13
|
+
/** Enable this to keep old versions of replaceable events */
|
|
14
|
+
keepOldVersions?: boolean;
|
|
15
|
+
/** The database to use for storing events */
|
|
16
|
+
database: IAsyncEventDatabase<E>;
|
|
17
|
+
/** Custom {@link IAsyncDeleteManager} implementation */
|
|
18
|
+
deleteManager?: IAsyncDeleteManager<E>;
|
|
19
|
+
/** Custom {@link IExpirationManager} implementation */
|
|
20
|
+
expirationManager?: IExpirationManager<E>;
|
|
21
|
+
/** The method used to verify events */
|
|
22
|
+
verifyEvent?: (event: E) => boolean;
|
|
23
|
+
};
|
|
24
|
+
/** An async wrapper around an async event database that handles replaceable events, deletes, and models */
|
|
25
|
+
export declare class AsyncEventStore<E extends StoreEvent = NostrEvent> extends EventModels<E> implements IAsyncEventStore<E> {
|
|
26
|
+
database: IAsyncEventDatabase<E>;
|
|
27
|
+
/** Optional memory database for ensuring single event instances */
|
|
28
|
+
memory: EventMemory<E>;
|
|
29
|
+
/** Manager for handling event deletions with authorization */
|
|
30
|
+
private deletes;
|
|
31
|
+
/** Manager for handling event expirations */
|
|
32
|
+
private expiration;
|
|
33
|
+
/** Enable this to keep old versions of replaceable events */
|
|
34
|
+
keepOldVersions: boolean;
|
|
35
|
+
/** Keep expired events in the store */
|
|
36
|
+
keepExpired: boolean;
|
|
37
|
+
/** Keep deleted events in the store */
|
|
38
|
+
keepDeleted: boolean;
|
|
39
|
+
/** The method used to verify events */
|
|
40
|
+
private _verifyEventMethod?;
|
|
41
|
+
/** Get the method used to verify events */
|
|
42
|
+
get verifyEvent(): undefined | ((event: E) => boolean);
|
|
43
|
+
/** Sets the method used to verify events */
|
|
44
|
+
set verifyEvent(method: undefined | ((event: E) => boolean));
|
|
45
|
+
/** A stream of new events added to the store */
|
|
46
|
+
insert$: Subject<E>;
|
|
47
|
+
/** A stream of events that have been updated (Warning: this is a very noisy stream, use with caution) */
|
|
48
|
+
update$: Subject<E>;
|
|
49
|
+
/** A stream of events that have been removed */
|
|
50
|
+
remove$: Subject<E>;
|
|
51
|
+
/**
|
|
52
|
+
* A method that will be called when an event isn't found in the store
|
|
53
|
+
*/
|
|
54
|
+
eventLoader?: (pointer: EventPointer | AddressPointer | AddressPointerWithoutD) => Observable<E> | Promise<E | undefined>;
|
|
55
|
+
/** Internal subscriptions (delete + expiration managers) torn down on dispose */
|
|
56
|
+
private internalSubscriptions;
|
|
57
|
+
constructor(options: AsyncEventStoreOptions<E>);
|
|
58
|
+
/** A method to add all events to memory to ensure there is only ever a single instance of an event */
|
|
59
|
+
private mapToMemory;
|
|
60
|
+
/** Handle a delete event by pointer */
|
|
61
|
+
private handleDeleteNotification;
|
|
62
|
+
/** Handle an expired event by id */
|
|
63
|
+
private handleExpiredNotification;
|
|
64
|
+
/**
|
|
65
|
+
* Adds an event to the store and update subscriptions
|
|
66
|
+
* @returns The existing event or the event that was added, if it was ignored returns null
|
|
67
|
+
*/
|
|
68
|
+
add(event: E, fromRelay?: string): Promise<E | null>;
|
|
69
|
+
/** Removes an event from the store and updates subscriptions */
|
|
70
|
+
remove(event: string | E): Promise<boolean>;
|
|
71
|
+
/** Remove multiple events that match the given filters */
|
|
72
|
+
removeByFilters(filters: Filter | Filter[]): Promise<number>;
|
|
73
|
+
/** Add an event to the store and notifies all subscribes it has updated */
|
|
74
|
+
update(event: E): Promise<void>;
|
|
75
|
+
/** Check if the store has an event by id */
|
|
76
|
+
hasEvent(id: string | EventPointer | AddressPointer | AddressPointerWithoutD): Promise<boolean>;
|
|
77
|
+
/** Get an event by id from the store */
|
|
78
|
+
getEvent(id: string | EventPointer | AddressPointer | AddressPointerWithoutD): Promise<E | undefined>;
|
|
79
|
+
/** Check if the store has a replaceable event */
|
|
80
|
+
hasReplaceable(kind: number, pubkey: string, d?: string): Promise<boolean>;
|
|
81
|
+
/** Gets the latest version of a replaceable event */
|
|
82
|
+
getReplaceable(kind: number, pubkey: string, identifier?: string): Promise<E | undefined>;
|
|
83
|
+
/** Returns all versions of a replaceable event */
|
|
84
|
+
getReplaceableHistory(kind: number, pubkey: string, identifier?: string): Promise<E[] | undefined>;
|
|
85
|
+
/** Get all events matching a filter */
|
|
86
|
+
getByFilters(filters: Filter | Filter[]): Promise<E[]>;
|
|
87
|
+
/** Returns a timeline of events that match filters */
|
|
88
|
+
getTimeline(filters: Filter | Filter[]): Promise<E[]>;
|
|
89
|
+
/** Passthrough method for the database.touch */
|
|
90
|
+
touch(event: E): void;
|
|
91
|
+
/** Increments the claim count on the event and touches it */
|
|
92
|
+
claim(event: E): void;
|
|
93
|
+
/** Checks if an event is claimed by anything */
|
|
94
|
+
isClaimed(event: E): boolean;
|
|
95
|
+
/** Decrements the claim count on an event */
|
|
96
|
+
removeClaim(event: E): void;
|
|
97
|
+
/** Removes all claims on an event */
|
|
98
|
+
clearClaim(event: E): void;
|
|
99
|
+
/** Pass through method for the database.unclaimed */
|
|
100
|
+
unclaimed(): Generator<E>;
|
|
101
|
+
/** Removes any event that is not being used by a subscription */
|
|
102
|
+
prune(limit?: number): number;
|
|
103
|
+
/**
|
|
104
|
+
* Tears down the store: disposes the attached event loader, completes the event streams, releases
|
|
105
|
+
* model keep-warm timers, unsubscribes internal manager listeners, and cancels any pending expiration timer.
|
|
106
|
+
* @note This is a terminal operation; the store should be discarded after calling it.
|
|
107
|
+
*/
|
|
108
|
+
dispose(): void;
|
|
109
|
+
/** Allows the store to be used with the `using` keyword */
|
|
110
|
+
[Symbol.dispose](): void;
|
|
111
|
+
}
|