applesauce-core 3.1.0 → 4.0.0
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/event-store/async-event-store.d.ts +134 -0
- package/dist/event-store/async-event-store.js +349 -0
- package/dist/event-store/{event-set.d.ts → event-memory.d.ts} +15 -25
- package/dist/event-store/{event-set.js → event-memory.js} +43 -53
- package/dist/event-store/event-store.d.ts +57 -63
- package/dist/event-store/event-store.js +111 -190
- package/dist/event-store/index.d.ts +2 -1
- package/dist/event-store/index.js +2 -1
- package/dist/event-store/interface.d.ts +111 -38
- package/dist/event-store/model-mixin.d.ts +59 -0
- package/dist/event-store/model-mixin.js +147 -0
- package/dist/helpers/app-data.d.ts +39 -0
- package/dist/helpers/app-data.js +68 -0
- package/dist/helpers/bookmarks.d.ts +11 -1
- package/dist/helpers/bookmarks.js +29 -4
- package/dist/helpers/comment.d.ts +13 -20
- package/dist/helpers/comment.js +16 -27
- package/dist/helpers/contacts.d.ts +10 -1
- package/dist/helpers/contacts.js +30 -3
- package/dist/helpers/encrypted-content-cache.js +7 -7
- package/dist/helpers/encrypted-content.d.ts +9 -2
- package/dist/helpers/encrypted-content.js +12 -9
- package/dist/helpers/event-cache.d.ts +3 -1
- package/dist/helpers/event-cache.js +3 -1
- package/dist/helpers/event-tags.d.ts +6 -0
- package/dist/helpers/event-tags.js +4 -0
- package/dist/helpers/event.d.ts +8 -1
- package/dist/helpers/event.js +6 -0
- package/dist/helpers/file-metadata.d.ts +4 -9
- package/dist/helpers/file-metadata.js +2 -10
- package/dist/helpers/filter.d.ts +4 -3
- package/dist/helpers/filter.js +3 -3
- package/dist/helpers/gift-wraps.d.ts +35 -14
- package/dist/helpers/gift-wraps.js +59 -50
- package/dist/helpers/groups.d.ts +2 -5
- package/dist/helpers/groups.js +2 -5
- package/dist/helpers/hidden-content.d.ts +14 -5
- package/dist/helpers/hidden-content.js +19 -8
- package/dist/helpers/hidden-tags.d.ts +16 -7
- package/dist/helpers/hidden-tags.js +47 -26
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/legacy-messages.d.ts +17 -13
- package/dist/helpers/legacy-messages.js +21 -19
- package/dist/helpers/lists.js +2 -1
- package/dist/helpers/lnurl.d.ts +4 -0
- package/dist/helpers/lnurl.js +7 -3
- package/dist/helpers/mailboxes.d.ts +2 -6
- package/dist/helpers/mailboxes.js +26 -20
- package/dist/helpers/mutes.d.ts +11 -1
- package/dist/helpers/mutes.js +30 -5
- package/dist/helpers/picture-post.d.ts +2 -1
- package/dist/helpers/pointers.d.ts +1 -1
- package/dist/helpers/pointers.js +2 -1
- package/dist/helpers/profile.d.ts +7 -3
- package/dist/helpers/profile.js +7 -8
- package/dist/helpers/relay-selection.d.ts +13 -0
- package/dist/helpers/relay-selection.js +84 -0
- package/dist/helpers/relays.d.ts +3 -1
- package/dist/helpers/relays.js +18 -2
- package/dist/helpers/url.js +3 -3
- package/dist/helpers/wrapped-messages.d.ts +5 -3
- package/dist/helpers/wrapped-messages.js +5 -3
- package/dist/helpers/zap.d.ts +16 -14
- package/dist/helpers/zap.js +26 -28
- package/dist/models/common.d.ts +4 -4
- package/dist/models/common.js +79 -40
- package/dist/models/gift-wrap.d.ts +1 -1
- package/dist/models/gift-wrap.js +4 -4
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.js +1 -0
- package/dist/models/legacy-messages.d.ts +2 -2
- package/dist/models/legacy-messages.js +13 -10
- package/dist/models/outbox.d.ts +13 -0
- package/dist/models/outbox.js +18 -0
- package/dist/models/profile.d.ts +1 -1
- package/dist/models/zaps.d.ts +5 -4
- package/dist/models/zaps.js +2 -2
- package/dist/observable/index.d.ts +4 -3
- package/dist/observable/index.js +5 -4
- package/dist/observable/map-events-to-store.d.ts +5 -3
- package/dist/observable/map-events-to-store.js +14 -3
- package/dist/observable/map-events-to-timeline.js +12 -0
- package/dist/observable/relay-selection.d.ts +7 -0
- package/dist/observable/relay-selection.js +38 -0
- package/package.json +5 -3
- package/dist/observable/map-events-timeline.js +0 -9
- /package/dist/observable/{map-events-timeline.d.ts → map-events-to-timeline.d.ts} +0 -0
|
@@ -7,8 +7,8 @@ export declare function LegacyMessagesGroups(self: string): Model<{
|
|
|
7
7
|
lastMessage: NostrEvent;
|
|
8
8
|
}[]>;
|
|
9
9
|
/** Returns all legacy direct messages in a group */
|
|
10
|
-
export declare function LegacyMessagesGroup(self: string,
|
|
10
|
+
export declare function LegacyMessagesGroup(self: string, correspondent: string): Model<NostrEvent[]>;
|
|
11
11
|
/** Returns an array of legacy messages that have replies */
|
|
12
|
-
export declare function LegacyMessageThreads(self: string,
|
|
12
|
+
export declare function LegacyMessageThreads(self: string, correspondent: string): Model<NostrEvent[]>;
|
|
13
13
|
/** Returns all the legacy direct messages that are replies to a given message */
|
|
14
14
|
export declare function LegacyMessageReplies(self: string, message: NostrEvent): Model<NostrEvent[]>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { kinds } from "nostr-tools";
|
|
2
|
-
import {
|
|
2
|
+
import { getLegacyMessageCorrespondent, getLegacyMessageParent } from "../helpers/legacy-messages.js";
|
|
3
3
|
import { map } from "rxjs";
|
|
4
4
|
import { getConversationIdentifierFromMessage, getConversationParticipants } from "../helpers/messages.js";
|
|
5
|
+
import { hasNameValueTag } from "../helpers/event-tags.js";
|
|
5
6
|
/** A model that returns all legacy message groups (1-1) that a pubkey is participating in */
|
|
6
7
|
export function LegacyMessagesGroups(self) {
|
|
7
8
|
return (store) => store.timeline({ kinds: [kinds.EncryptedDirectMessage], "#p": [self] }).pipe(map((messages) => {
|
|
@@ -19,41 +20,43 @@ export function LegacyMessagesGroups(self) {
|
|
|
19
20
|
}));
|
|
20
21
|
}
|
|
21
22
|
/** Returns all legacy direct messages in a group */
|
|
22
|
-
export function LegacyMessagesGroup(self,
|
|
23
|
+
export function LegacyMessagesGroup(self, correspondent) {
|
|
23
24
|
return (store) => store.timeline([
|
|
24
25
|
{
|
|
25
26
|
kinds: [kinds.EncryptedDirectMessage],
|
|
26
27
|
"#p": [self],
|
|
27
|
-
authors: [
|
|
28
|
+
authors: [correspondent],
|
|
28
29
|
},
|
|
29
30
|
{
|
|
30
31
|
kinds: [kinds.EncryptedDirectMessage],
|
|
31
|
-
"#p": [
|
|
32
|
+
"#p": [correspondent],
|
|
32
33
|
authors: [self],
|
|
33
34
|
},
|
|
34
35
|
]);
|
|
35
36
|
}
|
|
36
37
|
/** Returns an array of legacy messages that have replies */
|
|
37
|
-
export function LegacyMessageThreads(self,
|
|
38
|
-
return (store) => store.model(LegacyMessagesGroup, self,
|
|
38
|
+
export function LegacyMessageThreads(self, correspondent) {
|
|
39
|
+
return (store) => store.model(LegacyMessagesGroup, self, correspondent).pipe(map((messages) => messages.filter((message) =>
|
|
39
40
|
// Only select messages that are not replies
|
|
40
41
|
!getLegacyMessageParent(message) &&
|
|
41
42
|
// Check if message has any replies
|
|
42
|
-
|
|
43
|
+
messages.some((m) => hasNameValueTag(m, "e", message.id)))));
|
|
43
44
|
}
|
|
44
45
|
/** Returns all the legacy direct messages that are replies to a given message */
|
|
45
46
|
export function LegacyMessageReplies(self, message) {
|
|
46
|
-
const
|
|
47
|
+
const correspondent = getLegacyMessageCorrespondent(message, self);
|
|
48
|
+
if (!correspondent)
|
|
49
|
+
throw new Error("Legacy message has no correspondent");
|
|
47
50
|
return (store) => store.timeline([
|
|
48
51
|
{
|
|
49
52
|
kinds: [kinds.EncryptedDirectMessage],
|
|
50
53
|
"#p": [self],
|
|
51
|
-
authors: [
|
|
54
|
+
authors: [correspondent],
|
|
52
55
|
"#e": [message.id],
|
|
53
56
|
},
|
|
54
57
|
{
|
|
55
58
|
kinds: [kinds.EncryptedDirectMessage],
|
|
56
|
-
"#p": [
|
|
59
|
+
"#p": [correspondent],
|
|
57
60
|
authors: [self],
|
|
58
61
|
"#e": [message.id],
|
|
59
62
|
},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProfilePointer } from "nostr-tools/nip19";
|
|
2
|
+
import { Model } from "../event-store/interface.js";
|
|
3
|
+
import { SelectOptimalRelaysOptions } from "../helpers/relay-selection.js";
|
|
4
|
+
import { ignoreBlacklistedRelays } from "../observable/relay-selection.js";
|
|
5
|
+
export type OutboxModelOptions = SelectOptimalRelaysOptions & {
|
|
6
|
+
type?: "inbox" | "outbox";
|
|
7
|
+
blacklist?: Parameters<typeof ignoreBlacklistedRelays>[0];
|
|
8
|
+
};
|
|
9
|
+
/** A model that returns the users contacts with the relays to connect to */
|
|
10
|
+
export declare function OutboxModel(user: string | ProfilePointer, opts: OutboxModelOptions): Model<ProfilePointer[]>;
|
|
11
|
+
export declare namespace OutboxModel {
|
|
12
|
+
var getKey: (user: string | ProfilePointer, opts: OutboxModelOptions) => string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import hash_sum from "hash-sum";
|
|
2
|
+
import { identity, map } from "rxjs";
|
|
3
|
+
import { selectOptimalRelays } from "../helpers/relay-selection.js";
|
|
4
|
+
import { ignoreBlacklistedRelays, includeMailboxes } from "../observable/relay-selection.js";
|
|
5
|
+
/** A model that returns the users contacts with the relays to connect to */
|
|
6
|
+
export function OutboxModel(user, opts) {
|
|
7
|
+
return (store) => store.contacts(user).pipe(
|
|
8
|
+
/** Ignore blacklisted relays */
|
|
9
|
+
opts?.blacklist ? ignoreBlacklistedRelays(opts.blacklist) : identity,
|
|
10
|
+
/** Include mailboxes */
|
|
11
|
+
includeMailboxes(store, opts.type),
|
|
12
|
+
/** Select the optimal relays */
|
|
13
|
+
map((users) => selectOptimalRelays(users, opts)));
|
|
14
|
+
}
|
|
15
|
+
OutboxModel.getKey = (user, opts) => {
|
|
16
|
+
const p = typeof user === "string" ? user : user.pubkey;
|
|
17
|
+
return hash_sum([p, opts.type, opts.maxConnections, opts.maxRelaysPerUser]);
|
|
18
|
+
};
|
package/dist/models/profile.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ProfilePointer } from "nostr-tools/nip19";
|
|
1
2
|
import { Model } from "../event-store/interface.js";
|
|
2
3
|
import { ProfileContent } from "../helpers/profile.js";
|
|
3
|
-
import { ProfilePointer } from "nostr-tools/nip19";
|
|
4
4
|
/** A model that gets and parses the kind 0 metadata for a pubkey */
|
|
5
5
|
export declare function ProfileModel(user: string | ProfilePointer): Model<ProfileContent | undefined>;
|
package/dist/models/zaps.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { kinds } from "nostr-tools";
|
|
2
2
|
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
|
|
3
3
|
import { Model } from "../event-store/interface.js";
|
|
4
|
+
import { KnownEvent } from "../helpers/index.js";
|
|
4
5
|
/** A model that gets all zap events for an event */
|
|
5
|
-
export declare function EventZapsModel(id: string | EventPointer | AddressPointer): Model<
|
|
6
|
+
export declare function EventZapsModel(id: string | EventPointer | AddressPointer): Model<KnownEvent<kinds.Zap>[]>;
|
|
6
7
|
/** A model that returns all zaps sent by a user */
|
|
7
|
-
export declare function SentZapsModel(pubkey: string): Model<
|
|
8
|
+
export declare function SentZapsModel(pubkey: string): Model<KnownEvent<kinds.Zap>[]>;
|
|
8
9
|
/** A model that returns all zaps received by a user */
|
|
9
|
-
export declare function ReceivedZapsModel(pubkey: string): Model<
|
|
10
|
+
export declare function ReceivedZapsModel(pubkey: string): Model<KnownEvent<kinds.Zap>[]>;
|
package/dist/models/zaps.js
CHANGED
|
@@ -18,9 +18,9 @@ export function EventZapsModel(id) {
|
|
|
18
18
|
}
|
|
19
19
|
/** A model that returns all zaps sent by a user */
|
|
20
20
|
export function SentZapsModel(pubkey) {
|
|
21
|
-
return (events) => events.timeline([{ kinds: [kinds.Zap], authors: [pubkey] }]);
|
|
21
|
+
return (events) => events.timeline([{ kinds: [kinds.Zap], authors: [pubkey] }]).pipe(map((events) => events.filter(isValidZap)));
|
|
22
22
|
}
|
|
23
23
|
/** A model that returns all zaps received by a user */
|
|
24
24
|
export function ReceivedZapsModel(pubkey) {
|
|
25
|
-
return (events) => events.timeline([{ kinds: [kinds.Zap], "#
|
|
25
|
+
return (events) => events.timeline([{ kinds: [kinds.Zap], "#p": [pubkey] }]).pipe(map((events) => events.filter(isValidZap)));
|
|
26
26
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
export { firstValueFrom, lastValueFrom, combineLatest, merge } from "rxjs";
|
|
2
|
+
export { Observable, Subject, BehaviorSubject, ReplaySubject } from "rxjs";
|
|
2
3
|
export * from "./defined.js";
|
|
3
4
|
export * from "./get-observable-value.js";
|
|
4
|
-
export * from "./map-events-timeline.js";
|
|
5
|
+
export * from "./map-events-to-timeline.js";
|
|
5
6
|
export * from "./map-events-to-store.js";
|
|
6
7
|
export * from "./simple-timeout.js";
|
|
7
8
|
export * from "./watch-event-updates.js";
|
|
8
9
|
export * from "./with-immediate-value.js";
|
|
9
|
-
export
|
|
10
|
+
export * from "./relay-selection.js";
|
package/dist/observable/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
// Re-export some useful rxjs functions
|
|
2
|
+
export { firstValueFrom, lastValueFrom, combineLatest, merge } from "rxjs";
|
|
3
|
+
export { Observable, Subject, BehaviorSubject, ReplaySubject } from "rxjs";
|
|
2
4
|
export * from "./defined.js";
|
|
3
5
|
export * from "./get-observable-value.js";
|
|
4
|
-
export * from "./map-events-timeline.js";
|
|
6
|
+
export * from "./map-events-to-timeline.js";
|
|
5
7
|
export * from "./map-events-to-store.js";
|
|
6
8
|
export * from "./simple-timeout.js";
|
|
7
9
|
export * from "./watch-event-updates.js";
|
|
8
10
|
export * from "./with-immediate-value.js";
|
|
9
|
-
|
|
10
|
-
export { firstValueFrom, lastValueFrom };
|
|
11
|
+
export * from "./relay-selection.js";
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { MonoTypeOperatorFunction } from "rxjs";
|
|
2
1
|
import { NostrEvent } from "nostr-tools";
|
|
3
|
-
import {
|
|
2
|
+
import { MonoTypeOperatorFunction } from "rxjs";
|
|
3
|
+
import { IAsyncEventStoreActions, IEventStoreActions } from "../event-store/interface.js";
|
|
4
4
|
/** Saves all events to an event store and filters out invalid events */
|
|
5
|
-
export declare function mapEventsToStore(store:
|
|
5
|
+
export declare function mapEventsToStore(store: IEventStoreActions | IAsyncEventStoreActions, removeDuplicates?: boolean): MonoTypeOperatorFunction<NostrEvent>;
|
|
6
|
+
/** Alias for {@link mapEventsToStore} */
|
|
7
|
+
export declare const filterDuplicateEvents: (store: IEventStoreActions | IAsyncEventStoreActions) => MonoTypeOperatorFunction<import("nostr-tools").Event>;
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import { distinct, filter, identity,
|
|
1
|
+
import { catchError, distinct, filter, from, identity, mergeMap, of } from "rxjs";
|
|
2
2
|
/** Saves all events to an event store and filters out invalid events */
|
|
3
3
|
export function mapEventsToStore(store, removeDuplicates = true) {
|
|
4
4
|
return (source) => source.pipe(
|
|
5
5
|
// Map all events to the store
|
|
6
|
-
// NOTE:
|
|
7
|
-
|
|
6
|
+
// NOTE: mergeMap is used here because we want to return the single instance of the event so that distinct() can be used later
|
|
7
|
+
mergeMap((event) => {
|
|
8
|
+
const r = store.add(event);
|
|
9
|
+
// Unwrap the promise from the async store
|
|
10
|
+
if (r instanceof Promise)
|
|
11
|
+
return from(r);
|
|
12
|
+
else
|
|
13
|
+
return of(r);
|
|
14
|
+
}),
|
|
15
|
+
// Ignore errors when inserting events into the store
|
|
16
|
+
catchError(() => of(null)),
|
|
8
17
|
// Ignore invalid events
|
|
9
18
|
filter((e) => e !== null),
|
|
10
19
|
// Remove duplicates if requested
|
|
11
20
|
removeDuplicates ? distinct() : identity);
|
|
12
21
|
}
|
|
22
|
+
/** Alias for {@link mapEventsToStore} */
|
|
23
|
+
export const filterDuplicateEvents = (store) => mapEventsToStore(store, true);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { insertEventIntoDescendingList } from "nostr-tools/utils";
|
|
2
|
+
import { pipe, scan } from "rxjs";
|
|
3
|
+
import { withImmediateValueOrDefault } from "./with-immediate-value.js";
|
|
4
|
+
/**
|
|
5
|
+
* Accumulate events into an ordered timeline
|
|
6
|
+
* @note This does not remove duplicate events
|
|
7
|
+
*/
|
|
8
|
+
export function mapEventsToTimeline() {
|
|
9
|
+
return pipe(scan((timeline, event) => insertEventIntoDescendingList(timeline, event), []),
|
|
10
|
+
// Emit an empty array first. This is to prevent empty observables completing without a value (EMPTY)
|
|
11
|
+
withImmediateValueOrDefault([]));
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ProfilePointer } from "nostr-tools/nip19";
|
|
2
|
+
import { type MonoTypeOperatorFunction, type Observable, type OperatorFunction } from "rxjs";
|
|
3
|
+
import { IEventSubscriptions } from "../event-store/interface.js";
|
|
4
|
+
/** RxJS operator that fetches outboxes for profile pointers from the event store */
|
|
5
|
+
export declare function includeMailboxes(store: IEventSubscriptions, type?: "inbox" | "outbox"): OperatorFunction<ProfilePointer[], ProfilePointer[]>;
|
|
6
|
+
/** Removes blacklisted relays from the user's relays */
|
|
7
|
+
export declare function ignoreBlacklistedRelays(blacklist: string[] | Observable<string[]>): MonoTypeOperatorFunction<ProfilePointer[]>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { combineLatest, combineLatestWith, isObservable, map, of, pipe, switchMap, } from "rxjs";
|
|
2
|
+
import { getInboxes, getOutboxes } from "../helpers/mailboxes.js";
|
|
3
|
+
import { addRelayHintsToPointer } from "../helpers/pointers.js";
|
|
4
|
+
/** RxJS operator that fetches outboxes for profile pointers from the event store */
|
|
5
|
+
export function includeMailboxes(store, type = "outbox") {
|
|
6
|
+
// Get the outboxes for all contacts
|
|
7
|
+
return switchMap((contacts) => combineLatest(contacts.map((user) =>
|
|
8
|
+
// Subscribe to the outboxes for the user
|
|
9
|
+
store
|
|
10
|
+
.replaceable({
|
|
11
|
+
kind: 10002,
|
|
12
|
+
pubkey: user.pubkey,
|
|
13
|
+
})
|
|
14
|
+
.pipe(
|
|
15
|
+
// Add the relays to the user
|
|
16
|
+
map((event) => {
|
|
17
|
+
if (!event)
|
|
18
|
+
return user;
|
|
19
|
+
// Get the relays from the event
|
|
20
|
+
const relays = type === "outbox" ? getOutboxes(event) : getInboxes(event);
|
|
21
|
+
if (!relays)
|
|
22
|
+
return user;
|
|
23
|
+
// Add the relays to the user
|
|
24
|
+
return addRelayHintsToPointer(user, relays);
|
|
25
|
+
})))));
|
|
26
|
+
}
|
|
27
|
+
/** Removes blacklisted relays from the user's relays */
|
|
28
|
+
export function ignoreBlacklistedRelays(blacklist) {
|
|
29
|
+
return pipe(
|
|
30
|
+
// Combine with the observable so it re-emits when the blacklist changes
|
|
31
|
+
combineLatestWith(isObservable(blacklist) ? blacklist : of(blacklist)),
|
|
32
|
+
// Filter the relays for the user
|
|
33
|
+
map(([users, blacklist]) => users.map((user) => {
|
|
34
|
+
if (!user.relays)
|
|
35
|
+
return user;
|
|
36
|
+
return { ...user, relays: user.relays.filter((relay) => !blacklist.includes(relay)) };
|
|
37
|
+
})));
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -64,21 +64,23 @@
|
|
|
64
64
|
"hash-sum": "^2.0.0",
|
|
65
65
|
"light-bolt11-decoder": "^3.2.0",
|
|
66
66
|
"nanoid": "^5.0.9",
|
|
67
|
-
"nostr-tools": "~2.
|
|
67
|
+
"nostr-tools": "~2.17",
|
|
68
68
|
"rxjs": "^7.8.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@hirez_io/observer-spy": "^2.2.0",
|
|
72
72
|
"@types/debug": "^4.1.12",
|
|
73
73
|
"@types/hash-sum": "^1.0.2",
|
|
74
|
+
"rimraf": "^6.0.1",
|
|
74
75
|
"typescript": "^5.8.3",
|
|
75
|
-
"vitest": "^3.2.
|
|
76
|
+
"vitest": "^3.2.4"
|
|
76
77
|
},
|
|
77
78
|
"funding": {
|
|
78
79
|
"type": "lightning",
|
|
79
80
|
"url": "lightning:nostrudel@geyser.fund"
|
|
80
81
|
},
|
|
81
82
|
"scripts": {
|
|
83
|
+
"prebuild": "rimraf dist",
|
|
82
84
|
"build": "tsc",
|
|
83
85
|
"watch:build": "tsc --watch > /dev/null",
|
|
84
86
|
"test": "vitest run --passWithNoTests",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { insertEventIntoDescendingList } from "nostr-tools/utils";
|
|
2
|
-
import { scan } from "rxjs";
|
|
3
|
-
/**
|
|
4
|
-
* Accumulate events into an ordered timeline
|
|
5
|
-
* @note This does not remove duplicate events
|
|
6
|
-
*/
|
|
7
|
-
export function mapEventsToTimeline() {
|
|
8
|
-
return scan((timeline, event) => insertEventIntoDescendingList(timeline, event), []);
|
|
9
|
-
}
|
|
File without changes
|