Re work event types
This commit is contained in:
@@ -44,7 +44,7 @@ export type DVMItem = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ListItem = {
|
export type ListItem = {
|
||||||
addresses: string,
|
addresses: string[],
|
||||||
mappings?: TagFeedMapping[],
|
mappings?: TagFeedMapping[],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type {Event} from 'nostr-tools'
|
import type {Event} from 'nostr-tools'
|
||||||
import {Emitter, now, randomId, defer} from '@welshman/lib'
|
import {Emitter, now, randomId, defer} from '@welshman/lib'
|
||||||
import type {Deferred} from '@welshman/lib'
|
import type {Deferred} from '@welshman/lib'
|
||||||
import {asEvent,} from '@welshman/util'
|
import {asSignedEvent} from '@welshman/util'
|
||||||
import {NetworkContext} from './Context'
|
import {NetworkContext} from './Context'
|
||||||
|
|
||||||
export enum PublishStatus {
|
export enum PublishStatus {
|
||||||
@@ -43,7 +43,7 @@ export const makePublish = (request: PublishRequest) => {
|
|||||||
|
|
||||||
export const publish = (request: PublishRequest) => {
|
export const publish = (request: PublishRequest) => {
|
||||||
const pub = makePublish(request)
|
const pub = makePublish(request)
|
||||||
const event = asEvent(request.event)
|
const event = asSignedEvent(request.event)
|
||||||
const executor = NetworkContext.getExecutor(request.relays)
|
const executor = NetworkContext.getExecutor(request.relays)
|
||||||
|
|
||||||
const abort = (reason: PublishStatus) => {
|
const abort = (reason: PublishStatus) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type {UnsignedEvent} from 'nostr-tools'
|
import type {UnsignedEvent} from 'nostr-tools'
|
||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from 'nostr-tools'
|
||||||
import {Kind} from './Kinds'
|
import {GROUP, COMMUNITY} from './Kinds'
|
||||||
|
|
||||||
export type Address = {
|
export type Address = {
|
||||||
kind: number,
|
kind: number,
|
||||||
@@ -51,8 +51,8 @@ export const addressFromEvent = (e: UnsignedEvent, relays: string[] = []) =>
|
|||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
|
|
||||||
export const isGroupAddress = (a: Address) => a.kind === Kind.GroupDefinition
|
export const isGroupAddress = (a: Address) => a.kind === GROUP
|
||||||
|
|
||||||
export const isCommunityAddress = (a: Address) => a.kind === Kind.CommunityDefinition
|
export const isCommunityAddress = (a: Address) => a.kind === COMMUNITY
|
||||||
|
|
||||||
export const isContextAddress = (a: Address) => [Kind.GroupDefinition, Kind.CommunityDefinition].includes(a.kind)
|
export const isContextAddress = (a: Address) => [GROUP, COMMUNITY].includes(a.kind)
|
||||||
|
|||||||
+69
-20
@@ -1,13 +1,38 @@
|
|||||||
import type {Event, EventTemplate, UnsignedEvent} from 'nostr-tools'
|
import {verifiedSymbol} from 'nostr-tools'
|
||||||
export type {Event, EventTemplate, UnsignedEvent} from 'nostr-tools'
|
|
||||||
import {verifyEvent, getEventHash} from 'nostr-tools'
|
import {verifyEvent, getEventHash} from 'nostr-tools'
|
||||||
import {cached, now} from '@welshman/lib'
|
import {cached, pick, now} from '@welshman/lib'
|
||||||
import {Tags} from './Tags'
|
import {Tags} from './Tags'
|
||||||
import {addressFromEvent, encodeAddress} from './Address'
|
import {addressFromEvent, encodeAddress} from './Address'
|
||||||
import {isEphemeralKind, isReplaceableKind, isPlainReplaceableKind, isParameterizedReplaceableKind} from './Kinds'
|
import {isEphemeralKind, isReplaceableKind, isPlainReplaceableKind, isParameterizedReplaceableKind} from './Kinds'
|
||||||
|
|
||||||
export type Rumor = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey' | 'id'> & {
|
export type EventTemplate = {
|
||||||
wrap?: Event
|
kind: number
|
||||||
|
tags: string[][]
|
||||||
|
content: string
|
||||||
|
created_at: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OwnedEvent = EventTemplate & {
|
||||||
|
pubkey: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HashedEvent = OwnedEvent & {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SignedEvent = HashedEvent & {
|
||||||
|
sig: string
|
||||||
|
[verifiedSymbol]?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UnwrappedEvent = HashedEvent & {
|
||||||
|
wrap: SignedEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TrustedEvent = HashedEvent & {
|
||||||
|
sig?: string
|
||||||
|
wrap?: SignedEvent
|
||||||
|
[verifiedSymbol]?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CreateEventOpts = {
|
export type CreateEventOpts = {
|
||||||
@@ -19,28 +44,52 @@ export type CreateEventOpts = {
|
|||||||
export const createEvent = (kind: number, {content = "", tags = [], created_at = now()}: CreateEventOpts) =>
|
export const createEvent = (kind: number, {content = "", tags = [], created_at = now()}: CreateEventOpts) =>
|
||||||
({kind, content, tags, created_at})
|
({kind, content, tags, created_at})
|
||||||
|
|
||||||
export const asEventTemplate = ({kind, tags, content, created_at}: EventTemplate): EventTemplate =>
|
export const isEventTemplate = (e: EventTemplate): e is EventTemplate =>
|
||||||
({kind, tags, content, created_at})
|
Boolean(e.kind && e.tags && e.content && e.created_at)
|
||||||
|
|
||||||
export const asUnsignedEvent = ({kind, tags, content, created_at, pubkey}: UnsignedEvent): UnsignedEvent =>
|
export const isOwnedEvent = (e: OwnedEvent): e is OwnedEvent =>
|
||||||
({kind, tags, content, created_at, pubkey})
|
Boolean(isEventTemplate(e) && e.pubkey)
|
||||||
|
|
||||||
export const asRumor = ({kind, tags, content, created_at, pubkey, id}: Rumor): Rumor =>
|
export const isHashedEvent = (e: HashedEvent): e is HashedEvent =>
|
||||||
({kind, tags, content, created_at, pubkey, id})
|
Boolean(isOwnedEvent(e) && e.id)
|
||||||
|
|
||||||
export const asEvent = ({kind, tags, content, created_at, pubkey, id, sig}: Event): Event =>
|
export const isSignedEvent = (e: TrustedEvent): e is SignedEvent =>
|
||||||
({kind, tags, content, created_at, pubkey, id, sig})
|
Boolean(isHashedEvent(e) && e.sig)
|
||||||
|
|
||||||
export const hasValidSignature = cached<string, boolean, [Event]>({
|
export const isUnwrappedEvent = (e: TrustedEvent): e is UnwrappedEvent =>
|
||||||
|
Boolean(isHashedEvent(e) && e.wrap)
|
||||||
|
|
||||||
|
export const isTrustedEvent = (e: TrustedEvent): e is TrustedEvent =>
|
||||||
|
isSignedEvent(e) || isUnwrappedEvent(e)
|
||||||
|
|
||||||
|
export const asEventTemplate = (e: EventTemplate): EventTemplate =>
|
||||||
|
pick(['kind', 'tags', 'content', 'created_at'], e)
|
||||||
|
|
||||||
|
export const asOwnedEvent = (e: OwnedEvent): OwnedEvent =>
|
||||||
|
pick(['kind', 'tags', 'content', 'created_at', 'pubkey'], e)
|
||||||
|
|
||||||
|
export const asHashedEvent = (e: HashedEvent): HashedEvent =>
|
||||||
|
pick(['kind', 'tags', 'content', 'created_at', 'pubkey', 'id'], e)
|
||||||
|
|
||||||
|
export const asSignedEvent = (e: SignedEvent): SignedEvent =>
|
||||||
|
pick(['kind', 'tags', 'content', 'created_at', 'pubkey', 'id', 'sig'], e)
|
||||||
|
|
||||||
|
export const asUnwrappedEvent = (e: UnwrappedEvent): UnwrappedEvent =>
|
||||||
|
pick(['kind', 'tags', 'content', 'created_at', 'pubkey', 'id', 'wrap'], e)
|
||||||
|
|
||||||
|
export const asTrustedEvent = (e: TrustedEvent): TrustedEvent =>
|
||||||
|
pick(['kind', 'tags', 'content', 'created_at', 'pubkey', 'id', 'sig', 'wrap'], e)
|
||||||
|
|
||||||
|
export const hasValidSignature = cached<string, boolean, [SignedEvent]>({
|
||||||
maxSize: 10000,
|
maxSize: 10000,
|
||||||
getKey: ([e]: [Event]) => {
|
getKey: ([e]: [SignedEvent]) => {
|
||||||
try {
|
try {
|
||||||
return [getEventHash(e), e.sig].join(":")
|
return [getEventHash(e), e.sig].join(":")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return 'invalid'
|
return 'invalid'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getValue: ([e]: [Event]) => {
|
getValue: ([e]: [SignedEvent]) => {
|
||||||
try {
|
try {
|
||||||
return verifyEvent(e)
|
return verifyEvent(e)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -49,11 +98,11 @@ export const hasValidSignature = cached<string, boolean, [Event]>({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getAddress = (e: UnsignedEvent) => encodeAddress(addressFromEvent(e))
|
export const getAddress = (e: HashedEvent) => encodeAddress(addressFromEvent(e))
|
||||||
|
|
||||||
export const getIdOrAddress = (e: Rumor) => isReplaceable(e) ? getAddress(e) : e.id
|
export const getIdOrAddress = (e: HashedEvent) => isReplaceable(e) ? getAddress(e) : e.id
|
||||||
|
|
||||||
export const getIdAndAddress = (e: Rumor) => isReplaceable(e) ? [e.id, getAddress(e)] : [e.id]
|
export const getIdAndAddress = (e: HashedEvent) => isReplaceable(e) ? [e.id, getAddress(e)] : [e.id]
|
||||||
|
|
||||||
export const isEphemeral = (e: EventTemplate) => isEphemeralKind(e.kind)
|
export const isEphemeral = (e: EventTemplate) => isEphemeralKind(e.kind)
|
||||||
|
|
||||||
@@ -63,7 +112,7 @@ export const isPlainReplaceable = (e: EventTemplate) => isPlainReplaceableKind(e
|
|||||||
|
|
||||||
export const isParameterizedReplaceable = (e: EventTemplate) => isParameterizedReplaceableKind(e.kind)
|
export const isParameterizedReplaceable = (e: EventTemplate) => isParameterizedReplaceableKind(e.kind)
|
||||||
|
|
||||||
export const isChildOf = (child: EventTemplate, parent: Rumor) => {
|
export const isChildOf = (child: EventTemplate, parent: HashedEvent) => {
|
||||||
const {roots, replies} = Tags.fromEvent(child).ancestors()
|
const {roots, replies} = Tags.fromEvent(child).ancestors()
|
||||||
const parentIds = (replies.exists() ? replies : roots).values().valueOf()
|
const parentIds = (replies.exists() ? replies : roots).values().valueOf()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type {Event} from 'nostr-tools'
|
import {Event} from 'nostr-tools'
|
||||||
import {matchFilter as nostrToolsMatchFilter} from 'nostr-tools'
|
import {matchFilter as nostrToolsMatchFilter} from 'nostr-tools'
|
||||||
import {prop, avg, hash, groupBy, randomId, uniq} from '@welshman/lib'
|
import {prop, avg, hash, groupBy, randomId, uniq} from '@welshman/lib'
|
||||||
import type {Rumor} from './Events'
|
import type {HashedEvent, TrustedEvent} from './Events'
|
||||||
import {decodeAddress, addressFromEvent, encodeAddress} from './Address'
|
import {decodeAddress, addressFromEvent, encodeAddress} from './Address'
|
||||||
import {isReplaceableKind} from './Kinds'
|
import {isReplaceableKind} from './Kinds'
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ export type Filter = {
|
|||||||
[key: `#${string}`]: string[]
|
[key: `#${string}`]: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const matchFilter = <E extends Rumor>(filter: Filter, event: E) => {
|
export const matchFilter = <E extends HashedEvent>(filter: Filter, event: E) => {
|
||||||
if (!nostrToolsMatchFilter(filter, event as unknown as Event)) {
|
if (!nostrToolsMatchFilter(filter, event as unknown as Event)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ export const matchFilter = <E extends Rumor>(filter: Filter, event: E) => {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export const matchFilters = <E extends Rumor>(filters: Filter[], event: E) => {
|
export const matchFilters = <E extends HashedEvent>(filters: Filter[], event: E) => {
|
||||||
for (const filter of filters) {
|
for (const filter of filters) {
|
||||||
if (matchFilter(filter, event)) {
|
if (matchFilter(filter, event)) {
|
||||||
return true
|
return true
|
||||||
@@ -155,7 +155,7 @@ export const getIdFilters = (idsOrAddresses: string[]) => {
|
|||||||
return filters
|
return filters
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getReplyFilters = (events: Rumor[], filter: Filter) => {
|
export const getReplyFilters = (events: TrustedEvent[], filter: Filter) => {
|
||||||
const a = []
|
const a = []
|
||||||
const e = []
|
const e = []
|
||||||
|
|
||||||
|
|||||||
+138
-76
@@ -7,79 +7,141 @@ export const isParameterizedReplaceableKind = kinds.isParameterizedReplaceableKi
|
|||||||
export const isReplaceableKind = (kind: number) =>
|
export const isReplaceableKind = (kind: number) =>
|
||||||
isPlainReplaceableKind(kind) || isParameterizedReplaceableKind(kind)
|
isPlainReplaceableKind(kind) || isParameterizedReplaceableKind(kind)
|
||||||
|
|
||||||
export enum Kind {
|
export const PROFILE = 0
|
||||||
Profile = 0,
|
export const NOTE = 1
|
||||||
Note = 1,
|
export const FOLLOWS = 3
|
||||||
Relay = 2,
|
export const DELETE = 5
|
||||||
DM = 4,
|
export const REPOST = 6
|
||||||
Delete = 5,
|
export const REACTION = 7
|
||||||
Repost = 6,
|
export const BADGE_AWARD = 8
|
||||||
Reaction = 7,
|
export const GROUP_CHAT_MESSAGE = 9
|
||||||
BadgeAward = 8,
|
export const GROUP_CHAT_REPLY = 10
|
||||||
GenericRepost = 16,
|
export const GROUP_CHAT_THREAD = 11
|
||||||
ChannelCreation = 40,
|
export const GROUP_CHAT_THREAD_REPLY = 12
|
||||||
ChannelMetadata = 41,
|
export const SEAL = 13
|
||||||
ChannelMessage = 42,
|
export const DIRECT_MESSAGE = 14
|
||||||
ChannelHideMessage = 43,
|
export const GENERIC_REPOST = 16
|
||||||
ChannelMuteUser = 44,
|
export const CHANNEL_CREATE = 40
|
||||||
OpenTimestamp = 1040,
|
export const CHANNEL_UPDATE = 41
|
||||||
GiftWrap = 1059,
|
export const CHANNEL_MESSAGE = 42
|
||||||
FileMetadata = 1063,
|
export const CHANNEL_HIDE_MESSAGE = 43
|
||||||
LiveChatMessage = 1311,
|
export const CHANNEL_MUTE_USER = 44
|
||||||
Remix = 1808,
|
export const BID = 1021
|
||||||
ProblemTracker = 1971,
|
export const BID_CONFIRMATION = 1022
|
||||||
Report = 1984,
|
export const OTS = 1040
|
||||||
Label = 1985,
|
export const WRAP = 1059
|
||||||
CommunityPostApproval = 4550,
|
export const WRAP_NIP04 = 1060
|
||||||
JobRequest = 5999,
|
export const FILE_METADATA = 1063
|
||||||
JobResult = 6999,
|
export const LIVE_CHAT_MESSAGE = 1311
|
||||||
JobFeedback = 7000,
|
export const GIT_PATCH = 1617
|
||||||
ZapGoal = 9041,
|
export const GIT_ISSUE = 1617
|
||||||
ZapRequest = 9734,
|
export const GIT_REPLY = 1617
|
||||||
ZapResponse = 9735,
|
export const GIT_STATUS_OPEN = 1630
|
||||||
Highlight = 9802,
|
export const GIT_STATUS_COMPLETE = 1631
|
||||||
UserListMutes = 10000,
|
export const GIT_STATUS_CLOSED = 1632
|
||||||
UserListPins = 10001,
|
export const GIT_STATUS_DRAFT = 1633
|
||||||
UserListRelays = 10002,
|
export const GIT_REPOSITORY = 30403
|
||||||
UserListBookmarks = 10003,
|
export const REMIX = 1808
|
||||||
UserListCommunities = 10004,
|
export const NOSTROCKER_PROBLEM = 1971
|
||||||
UserListPublicChats = 10005,
|
export const REPORT = 1984
|
||||||
UserListBlockedRelays = 10006,
|
export const LABEL = 1985
|
||||||
UserListSearchRelays = 10007,
|
export const APPROVAL = 4550
|
||||||
UserListInterests = 10015,
|
export const DVM_REQUEST_TEXT_EXTRACTION = 5000
|
||||||
UserListEmojis = 10030,
|
export const DVM_REQUEST_TEXT_SUMMARY = 5001
|
||||||
LightningPubRpc = 21000,
|
export const DVM_REQUEST_TEXT_TRANSLATION = 5002
|
||||||
ClientAuth = 22242,
|
export const DVM_REQUEST_TEXT_GENERATION = 5050
|
||||||
NWCInfo = 13194,
|
export const DVM_REQUEST_IMAGE_GENERATION = 5100
|
||||||
NWCRequest = 23194,
|
export const DVM_REQUEST_VIDEO_CONVERSION = 5200
|
||||||
NWCResponse = 23195,
|
export const DVM_REQUEST_VIDEO_TRANSLATION = 5201
|
||||||
NostrConnect = 24133,
|
export const DVM_REQUEST_IMAGE_TO_VIDEO_CONVERSION = 5202
|
||||||
HttpAuth = 27235,
|
export const DVM_REQUEST_TEXT_TO_SPEECH = 5250
|
||||||
ListFollows = 3,
|
export const DVM_REQUEST_DISCOVER_CONTENT = 5300
|
||||||
ListPeople = 30000,
|
export const DVM_REQUEST_DISCOVER_PEOPLE = 5301
|
||||||
ListGeneric = 30001,
|
export const DVM_REQUEST_SEARCH_CONTENT = 5302
|
||||||
ListRelays = 30002,
|
export const DVM_REQUEST_SEARCH_PEOPLE = 5303
|
||||||
ListBookmarks = 30003,
|
export const DVM_REQUEST_COUNT = 5400
|
||||||
ListCurations = 30004,
|
export const DVM_REQUEST_MALWARE_SCAN = 5500
|
||||||
ProfileBadges = 30008,
|
export const DVM_REQUEST_OTS = 5900
|
||||||
BadgeDefinition = 30009,
|
export const DVM_REQUEST_OP_RETURN = 5901
|
||||||
ListEmojis = 30030,
|
export const DVM_REQUEST_PUBLISH_SCHEDULE = 5905
|
||||||
ListInterests = 30015,
|
export const DVM_RESPONSE_TEXT_EXTRACTION = 6000
|
||||||
LongFormArticle = 30023,
|
export const DVM_RESPONSE_TEXT_SUMMARY = 6001
|
||||||
LongFormArticleDraft = 30024,
|
export const DVM_RESPONSE_TEXT_TRANSLATION = 6002
|
||||||
Application = 30078,
|
export const DVM_RESPONSE_TEXT_GENERATION = 6050
|
||||||
LiveEvent = 30311,
|
export const DVM_RESPONSE_IMAGE_GENERATION = 6100
|
||||||
UserStatuses = 30315,
|
export const DVM_RESPONSE_VIDEO_CONVERSION = 6200
|
||||||
ClassifiedListing = 30402,
|
export const DVM_RESPONSE_VIDEO_TRANSLATION = 6201
|
||||||
DraftClassifiedListing = 30403,
|
export const DVM_RESPONSE_IMAGE_TO_VIDEO_CONVERSION = 6202
|
||||||
Audio = 31337,
|
export const DVM_RESPONSE_TEXT_TO_SPEECH = 6250
|
||||||
Feed = 31890,
|
export const DVM_RESPONSE_DISCOVER_CONTENT = 6300
|
||||||
Calendar = 31924,
|
export const DVM_RESPONSE_DISCOVER_PEOPLE = 6301
|
||||||
CalendarEventDate = 31922,
|
export const DVM_RESPONSE_SEARCH_CONTENT = 6302
|
||||||
CalendarEventTime = 31923,
|
export const DVM_RESPONSE_SEARCH_PEOPLE = 6303
|
||||||
CalendarEventRsvp = 31925,
|
export const DVM_RESPONSE_COUNT = 6400
|
||||||
HandlerRecommendation = 31989,
|
export const DVM_RESPONSE_MALWARE_SCAN = 6500
|
||||||
HandlerInformation = 31990,
|
export const DVM_RESPONSE_OTS = 6900
|
||||||
CommunityDefinition = 34550,
|
export const DVM_RESPONSE_OP_RETURN = 6901
|
||||||
GroupDefinition = 35834,
|
export const DVM_RESPONSE_PUBLISH_SCHEDULE = 6905
|
||||||
}
|
export const DVM_FEEDBACK = 7000
|
||||||
|
export const ZAP_GOAL = 9041
|
||||||
|
export const ZAP_REQUEST = 9734
|
||||||
|
export const ZAP_RESPONSE = 9735
|
||||||
|
export const HIGHLIGHT = 9802
|
||||||
|
export const MUTES = 10000
|
||||||
|
export const PINS = 10001
|
||||||
|
export const RELAYS = 10002
|
||||||
|
export const BOOKMARKS = 10003
|
||||||
|
export const COMMUNITIES = 10004
|
||||||
|
export const CHANNELS = 10005
|
||||||
|
export const BLOCKED_RELAYS = 10006
|
||||||
|
export const SEARCH_RELAYS = 10007
|
||||||
|
export const GROUPS = 10009
|
||||||
|
export const TOPICS = 10015
|
||||||
|
export const EMOJIS = 10030
|
||||||
|
export const DM_INBOX_RELAYS = 10050
|
||||||
|
export const FILE_SERVERS = 10096
|
||||||
|
export const LIGHTNING_PUB_RPC = 21000
|
||||||
|
export const CLIENT_AUTH = 22242
|
||||||
|
export const WALLET_INFO = 13194
|
||||||
|
export const WALLET_REQUEST = 23194
|
||||||
|
export const WALLET_RESPONSE = 23195
|
||||||
|
export const NOSTR_CONNECT = 24133
|
||||||
|
export const HTTP_AUTH = 27235
|
||||||
|
export const NAMED_PEOPLE = 30000
|
||||||
|
export const NAMED_RELAYS = 30002
|
||||||
|
export const NAMED_BOOKMARKS = 30003
|
||||||
|
export const NAMED_CURATIONS = 30004
|
||||||
|
export const NAMED_WIKI_AUTHORS = 30101
|
||||||
|
export const NAMED_WIKI_RELAYS = 30102
|
||||||
|
export const NAMED_EMOJIS = 30030
|
||||||
|
export const NAMED_TOPICS = 30015
|
||||||
|
export const NAMED_ARTIFACTS = 30063
|
||||||
|
export const BADGES = 30008
|
||||||
|
export const BADGE_DEFINITION = 30009
|
||||||
|
export const STALL = 30017
|
||||||
|
export const PRODUCT = 30018
|
||||||
|
export const MARKET_UI = 30019
|
||||||
|
export const PRODUCT_SOLD_AS_AUCTION = 30020
|
||||||
|
export const WIKI = 30818
|
||||||
|
export const LONG_FORM = 30023
|
||||||
|
export const LONG_FORM_DRAFT = 30024
|
||||||
|
export const APPLICATION = 30078
|
||||||
|
export const LIVE_EVENT = 30311
|
||||||
|
export const STATUSES = 30315
|
||||||
|
export const CLASSIFIED = 30402
|
||||||
|
export const DRAFT_CLASSIFIED = 30403
|
||||||
|
export const AUDIO = 31337
|
||||||
|
export const FEED = 31890
|
||||||
|
export const CALENDAR = 31924
|
||||||
|
export const EVENT_DATE = 31922
|
||||||
|
export const EVENT_TIME = 31923
|
||||||
|
export const EVENT_RSVP = 31925
|
||||||
|
export const HANDLER_RECOMMENDATION = 31989
|
||||||
|
export const HANDLER_INFORMATION = 31990
|
||||||
|
export const COMMUNITY = 34550
|
||||||
|
export const GROUP = 35834
|
||||||
|
|
||||||
|
export const DEPRECATED_RELAY_RECOMMENDATION = 2
|
||||||
|
export const DEPRECATED_DIRECT_MESSAGE = 4
|
||||||
|
export const DEPRECATED_NAMED_GENERIC = 30001
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import {Emitter} from '@welshman/lib'
|
|||||||
import {matchFilters} from './Filters'
|
import {matchFilters} from './Filters'
|
||||||
import type {Repository} from './Repository'
|
import type {Repository} from './Repository'
|
||||||
import type {Filter} from './Filters'
|
import type {Filter} from './Filters'
|
||||||
import type {Rumor} from './Events'
|
import type {TrustedEvent} from './Events'
|
||||||
|
|
||||||
export class Relay<E extends Rumor> extends Emitter {
|
export class Relay<E extends TrustedEvent> extends Emitter {
|
||||||
subs = new Map<string, Filter[]>()
|
subs = new Map<string, Filter[]>()
|
||||||
|
|
||||||
constructor(readonly repository: Repository<E>) {
|
constructor(readonly repository: Repository<E>) {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {throttle} from 'throttle-debounce'
|
import {throttle} from 'throttle-debounce'
|
||||||
import type {IReadable, Subscriber, Invalidator} from '@welshman/lib'
|
import type {IReadable, Subscriber, Invalidator} from '@welshman/lib'
|
||||||
import {Derived, Emitter, writable, first, always, chunk, sleep, uniq, omit, now, range, identity} from '@welshman/lib'
|
import {Derived, Emitter, writable, first, always, chunk, sleep, uniq, omit, now, range, identity} from '@welshman/lib'
|
||||||
import {Kind} from './Kinds'
|
import {DELETE} from './Kinds'
|
||||||
import {matchFilter, getIdFilters, matchFilters} from './Filters'
|
import {matchFilter, getIdFilters, matchFilters} from './Filters'
|
||||||
import {encodeAddress, addressFromEvent} from './Address'
|
import {encodeAddress, addressFromEvent} from './Address'
|
||||||
import {isReplaceable} from './Events'
|
import {isReplaceable} from './Events'
|
||||||
import type {Filter} from './Filters'
|
import type {Filter} from './Filters'
|
||||||
import type {Rumor} from './Events'
|
import type {TrustedEvent} from './Events'
|
||||||
|
|
||||||
export const DAY = 86400
|
export const DAY = 86400
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export type RepositoryOptions = {
|
|||||||
throttle?: number
|
throttle?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Repository<E extends Rumor> extends Emitter implements IReadable<Repository<E>> {
|
export class Repository<E extends TrustedEvent> extends Emitter implements IReadable<Repository<E>> {
|
||||||
eventsById = new Map<string, E>()
|
eventsById = new Map<string, E>()
|
||||||
eventsByAddress = new Map<string, E>()
|
eventsByAddress = new Map<string, E>()
|
||||||
eventsByTag = new Map<string, E[]>()
|
eventsByTag = new Map<string, E[]>()
|
||||||
@@ -225,7 +225,7 @@ export class Repository<E extends Rumor> extends Emitter implements IReadable<Re
|
|||||||
if (tag[0].length === 1) {
|
if (tag[0].length === 1) {
|
||||||
this._updateIndex(this.eventsByTag, tag.slice(0, 2).join(':'), event, duplicate)
|
this._updateIndex(this.eventsByTag, tag.slice(0, 2).join(':'), event, duplicate)
|
||||||
|
|
||||||
if (event.kind === Kind.Delete) {
|
if (event.kind === DELETE) {
|
||||||
const id = tag[1]
|
const id = tag[1]
|
||||||
const ts = Math.max(event.created_at, this.deletes.get(tag[1]) || 0)
|
const ts = Math.max(event.created_at, this.deletes.get(tag[1]) || 0)
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ export class Repository<E extends Rumor> extends Emitter implements IReadable<Re
|
|||||||
|
|
||||||
if (!this.isDeleted(event)) {
|
if (!this.isDeleted(event)) {
|
||||||
// Deletes are tricky, re-evaluate all subscriptions if that's what we're dealing with
|
// Deletes are tricky, re-evaluate all subscriptions if that's what we're dealing with
|
||||||
if (event.kind === Kind.Delete) {
|
if (event.kind === DELETE) {
|
||||||
this.notify()
|
this.notify()
|
||||||
} else {
|
} else {
|
||||||
this.notify(event)
|
this.notify(event)
|
||||||
|
|||||||
+12
-12
@@ -1,6 +1,6 @@
|
|||||||
import {first, splitAt, identity, sortBy, uniq, shuffle, pushToMapKey} from '@welshman/lib'
|
import {first, splitAt, identity, sortBy, uniq, shuffle, pushToMapKey} from '@welshman/lib'
|
||||||
import {Tags, Tag} from '@welshman/util'
|
import {Tags, Tag} from '@welshman/util'
|
||||||
import type {Rumor} from './Events'
|
import type {TrustedEvent} from './Events'
|
||||||
import {getAddress, isReplaceable} from './Events'
|
import {getAddress, isReplaceable} from './Events'
|
||||||
import {isShareableRelayUrl} from './Relays'
|
import {isShareableRelayUrl} from './Relays'
|
||||||
import {addressFromEvent, decodeAddress, isCommunityAddress, isGroupAddress} from './Address'
|
import {addressFromEvent, decodeAddress, isCommunityAddress, isGroupAddress} from './Address'
|
||||||
@@ -178,19 +178,19 @@ export class Router {
|
|||||||
this.getPubkeySelection(pubkey, RelayMode.Read),
|
this.getPubkeySelection(pubkey, RelayMode.Read),
|
||||||
]).policy(this.addMinimalFallbacks)
|
]).policy(this.addMinimalFallbacks)
|
||||||
|
|
||||||
Event = (event: Rumor) =>
|
Event = (event: TrustedEvent) =>
|
||||||
this.scenario(this.forceValue(event.id, [
|
this.scenario(this.forceValue(event.id, [
|
||||||
this.getPubkeySelection(event.pubkey, RelayMode.Write),
|
this.getPubkeySelection(event.pubkey, RelayMode.Write),
|
||||||
...this.getContextSelections(Tags.fromEvent(event).context()),
|
...this.getContextSelections(Tags.fromEvent(event).context()),
|
||||||
]))
|
]))
|
||||||
|
|
||||||
EventChildren = (event: Rumor) =>
|
EventChildren = (event: TrustedEvent) =>
|
||||||
this.scenario(this.forceValue(event.id, [
|
this.scenario(this.forceValue(event.id, [
|
||||||
this.getPubkeySelection(event.pubkey, RelayMode.Read),
|
this.getPubkeySelection(event.pubkey, RelayMode.Read),
|
||||||
...this.getContextSelections(Tags.fromEvent(event).context()),
|
...this.getContextSelections(Tags.fromEvent(event).context()),
|
||||||
]))
|
]))
|
||||||
|
|
||||||
EventAncestors = (event: Rumor, type: "mentions" | "replies" | "roots") => {
|
EventAncestors = (event: TrustedEvent, type: "mentions" | "replies" | "roots") => {
|
||||||
const tags = Tags.fromEvent(event)
|
const tags = Tags.fromEvent(event)
|
||||||
const ancestors = tags.ancestors()[type]
|
const ancestors = tags.ancestors()[type]
|
||||||
const pubkeys = tags.whereKey("p").values().valueOf()
|
const pubkeys = tags.whereKey("p").values().valueOf()
|
||||||
@@ -207,13 +207,13 @@ export class Router {
|
|||||||
return this.product(ancestors.values().valueOf(), relays)
|
return this.product(ancestors.values().valueOf(), relays)
|
||||||
}
|
}
|
||||||
|
|
||||||
EventMentions = (event: Rumor) => this.EventAncestors(event, "mentions")
|
EventMentions = (event: TrustedEvent) => this.EventAncestors(event, "mentions")
|
||||||
|
|
||||||
EventParents = (event: Rumor) => this.EventAncestors(event, "replies")
|
EventParents = (event: TrustedEvent) => this.EventAncestors(event, "replies")
|
||||||
|
|
||||||
EventRoots = (event: Rumor) => this.EventAncestors(event, "roots")
|
EventRoots = (event: TrustedEvent) => this.EventAncestors(event, "roots")
|
||||||
|
|
||||||
PublishEvent = (event: Rumor) => {
|
PublishEvent = (event: TrustedEvent) => {
|
||||||
const tags = Tags.fromEvent(event)
|
const tags = Tags.fromEvent(event)
|
||||||
const mentions = tags.values("p").valueOf()
|
const mentions = tags.values("p").valueOf()
|
||||||
|
|
||||||
@@ -279,13 +279,13 @@ export class Router {
|
|||||||
tagPubkey = (pubkey: string) =>
|
tagPubkey = (pubkey: string) =>
|
||||||
Tag.from(["p", pubkey, this.FromPubkeys([pubkey]).getUrl()])
|
Tag.from(["p", pubkey, this.FromPubkeys([pubkey]).getUrl()])
|
||||||
|
|
||||||
tagEventId = (event: Rumor, mark = "") =>
|
tagEventId = (event: TrustedEvent, mark = "") =>
|
||||||
Tag.from(["e", event.id, this.Event(event).getUrl(), mark, event.pubkey])
|
Tag.from(["e", event.id, this.Event(event).getUrl(), mark, event.pubkey])
|
||||||
|
|
||||||
tagEventAddress = (event: Rumor, mark = "") =>
|
tagEventAddress = (event: TrustedEvent, mark = "") =>
|
||||||
Tag.from(["a", getAddress(event), this.Event(event).getUrl(), mark, event.pubkey])
|
Tag.from(["a", getAddress(event), this.Event(event).getUrl(), mark, event.pubkey])
|
||||||
|
|
||||||
tagEvent = (event: Rumor, mark = "") => {
|
tagEvent = (event: TrustedEvent, mark = "") => {
|
||||||
const tags = [this.tagEventId(event, mark)]
|
const tags = [this.tagEventId(event, mark)]
|
||||||
|
|
||||||
if (isReplaceable(event)) {
|
if (isReplaceable(event)) {
|
||||||
@@ -295,7 +295,7 @@ export class Router {
|
|||||||
return new Tags(tags)
|
return new Tags(tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
address = (event: Rumor) =>
|
address = (event: TrustedEvent) =>
|
||||||
addressFromEvent(event, this.Event(event).redundancy(3).getUrls())
|
addressFromEvent(event, this.Event(event).redundancy(3).getUrls())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {Fluent, ensurePlural} from '@welshman/lib'
|
|||||||
import {isShareableRelayUrl, normalizeRelayUrl} from './Relays'
|
import {isShareableRelayUrl, normalizeRelayUrl} from './Relays'
|
||||||
import type {Address} from './Address'
|
import type {Address} from './Address'
|
||||||
import {encodeAddress, decodeAddress} from './Address'
|
import {encodeAddress, decodeAddress} from './Address'
|
||||||
import {Kind} from './Kinds'
|
import {GROUP, COMMUNITY} from './Kinds'
|
||||||
|
|
||||||
export class Tag extends (Fluent<string> as OmitStatics<typeof Fluent<string>, 'from'>) {
|
export class Tag extends (Fluent<string> as OmitStatics<typeof Fluent<string>, 'from'>) {
|
||||||
static from = (xs: Iterable<string>) => new Tag(Array.from(xs))
|
static from = (xs: Iterable<string>) => new Tag(Array.from(xs))
|
||||||
@@ -33,11 +33,11 @@ export class Tag extends (Fluent<string> as OmitStatics<typeof Fluent<string>, '
|
|||||||
|
|
||||||
isAddress = (kind?: number) => this.key() === "a" && this.value()?.startsWith(`${kind}:`)
|
isAddress = (kind?: number) => this.key() === "a" && this.value()?.startsWith(`${kind}:`)
|
||||||
|
|
||||||
isGroup = () => this.isAddress(Kind.GroupDefinition)
|
isGroup = () => this.isAddress(GROUP)
|
||||||
|
|
||||||
isCommunity = () => this.isAddress(Kind.CommunityDefinition)
|
isCommunity = () => this.isAddress(COMMUNITY)
|
||||||
|
|
||||||
isContext = () => this.isAddress(Kind.GroupDefinition) || this.isAddress(Kind.CommunityDefinition)
|
isContext = () => this.isAddress(GROUP) || this.isAddress(COMMUNITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Tags extends (Fluent<Tag> as OmitStatics<typeof Fluent<Tag>, 'from'>) {
|
export class Tags extends (Fluent<Tag> as OmitStatics<typeof Fluent<Tag>, 'from'>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user