From 131e952e3259f8966957d690084eb5e852e73f20 Mon Sep 17 00:00:00 2001 From: hasundue Date: Wed, 4 Oct 2023 11:39:26 +0900 Subject: [PATCH] refactor(nips/01): abondan enum for EventKind --- core/clients_test.ts | 3 +- core/nips/01.ts | 77 +++++++++++++++++++++++++++++--------------- core/relays_test.ts | 18 +++++++---- core/types.ts | 3 +- lib/events.ts | 2 +- lib/notes.ts | 4 +-- lib/pools.ts | 7 +++- lib/signs_test.ts | 3 +- lib/std/streams.ts | 1 + lib/streams.ts | 2 +- 10 files changed, 79 insertions(+), 41 deletions(-) create mode 100644 lib/std/streams.ts diff --git a/core/clients_test.ts b/core/clients_test.ts index 15f333f..6fd06ec 100644 --- a/core/clients_test.ts +++ b/core/clients_test.ts @@ -1,4 +1,5 @@ import { + EventKind, EventMessage, NostrEvent, OkMessage, @@ -57,7 +58,7 @@ describe("Client", () => { }); it("should receive requests", async () => { subid = "test" as SubscriptionId; - const req = { kinds: [0] }; + const req = { kinds: [EventKind[0]] }; ws.dispatchEvent( new MessageEvent("message", { data: JSON.stringify(["REQ", subid, req]), diff --git a/core/nips/01.ts b/core/nips/01.ts index 3a44749..f7dece7 100644 --- a/core/nips/01.ts +++ b/core/nips/01.ts @@ -139,42 +139,67 @@ export type SubscriptionFilter< // Basic event kinds // ---------------------- -export enum EventKind { - Metadata = 0, - TextNote = 1, -} +export type EventKind = Brand; -export type RegularEventKind = Brand; -export type ReplaceableEventKind = Brand; -export type EphemeralEventKind = Brand; -export type ParameterizedReplaceableEventKind = Brand< - EventKind, - "ParameterizedReplaceableEventKind" ->; +export type MetadataEvent = NostrEvent>; +export type TextNoteEvent = NostrEvent>; + +// TODO: Use template literal for T -// deno-lint-ignore no-namespace -export namespace EventKind { - export function isRegularEventKind( - kind: EventKind | number, +export type RegularEventKind = Brand< + T, + "EventKind", + "Regular" +>; +export type ReplaceableEventKind = Brand< + T, + "EventKind", + "Replaceable" +>; +export type EphemeralEventKind = Brand< + T, + "EventKind", + "Ephemeral" +>; +export type ParameterizedReplaceableEventKind = + Brand< + T, + "EventKind", + "ParameterizedReplaceable" + >; + +export const EventKind = { + 0: 0 as EventKind<0>, + Metadata: 0 as EventKind<0>, + + 1: 1 as EventKind<1>, + TextNote: 1 as EventKind<1>, + + $(kind: T): EventKind { + return kind as EventKind; + }, + + isRegularEventKind( + kind: EventKind, ): kind is RegularEventKind { return 1000 <= kind && kind < 10000; - } - export function isReplaceableEventKind( - kind: EventKind | number, + }, + isReplaceableEventKind( + kind: EventKind, ): kind is ReplaceableEventKind { return (10000 <= kind && kind < 20000) || kind === 0 || kind === 3; - } - export function isEphemeralEventKind( - kind: EventKind | number, + }, + isEphemeralEventKind( + kind: EventKind, ): kind is EphemeralEventKind { return 20000 <= kind && kind < 30000; - } - export function isParameterizedReplaceableEventKind( - kind: EventKind | number, + }, + isParameterizedReplaceableEventKind( + kind: EventKind, ): kind is ParameterizedReplaceableEventKind { return 30000 <= kind && kind < 40000; - } -} + }, +}; export type EventContent = [ MetadataContent, diff --git a/core/relays_test.ts b/core/relays_test.ts index aa1b0f2..cb14104 100644 --- a/core/relays_test.ts +++ b/core/relays_test.ts @@ -1,8 +1,10 @@ import { EventId, - NostrEvent, + EventKind, + MetadataEvent, OkMessage, PublishMessage, + TextNoteEvent, } from "../core/nips/01.ts"; import { EventRejected, Relay, RelayClosed } from "./relays.ts"; import { afterAll, beforeAll, describe, it } from "../lib/std/testing.ts"; @@ -74,8 +76,8 @@ describe("Relay constructor", () => { describe("Relay", () => { const url = "wss://localhost:8080"; let relay: Relay; - let sub_0: ReadableStream>; - let sub_1: ReadableStream>; + let sub_0: ReadableStream; + let sub_1: ReadableStream; beforeAll(() => { globalThis.WebSocket = MockWebSocket; @@ -91,7 +93,7 @@ describe("Relay", () => { assertEquals(relay.status, WebSocket.CLOSED); }); it("should not connect when a subscription is created", () => { - sub_1 = relay.subscribe({ kinds: [1] }, { id: "test-1" }); + sub_1 = relay.subscribe({ kinds: [EventKind[1]] }, { id: "test-1" }); assert(sub_1 instanceof ReadableStream); assertEquals(relay.status, WebSocket.CLOSED); }); @@ -110,7 +112,9 @@ describe("Relay", () => { reader.releaseLock(); }); it("should be able to open multiple subscriptions", () => { - sub_0 = relay.subscribe({ kinds: [0], limit: 1 }, { id: "test-0" }); + sub_0 = relay.subscribe({ kinds: [EventKind[0]], limit: 1 }, { + id: "test-0", + }); assert(sub_0 instanceof ReadableStream); }); it("should recieve metas and notes simultaneously", async () => { @@ -146,7 +150,7 @@ describe("Relay", () => { ws.remote.addEventListener( "message", (ev: MessageEvent) => { - const [, event] = JSON.parse(ev.data) as PublishMessage<1>; + const [, event] = JSON.parse(ev.data) as PublishMessage>; if (event.id === eid) { assertEquals(event.kind, 1); resolve(true); @@ -168,7 +172,7 @@ describe("Relay", () => { ws.remote.addEventListener( "message", (ev: MessageEvent) => { - const [, event] = JSON.parse(ev.data) as PublishMessage<1>; + const [, event] = JSON.parse(ev.data) as PublishMessage>; if (event.id === eid) { assertEquals(event.kind, 1); resolve(true); diff --git a/core/types.ts b/core/types.ts index 2062c53..e1fd807 100644 --- a/core/types.ts +++ b/core/types.ts @@ -1,7 +1,8 @@ /** * Constructor of branded types */ -export type Brand = K & { __brand: T }; +// deno-lint-ignore no-explicit-any +export type Brand = T & { __brand: B; __kind: K }; // // Records and maps diff --git a/lib/events.ts b/lib/events.ts index f697097..026165b 100644 --- a/lib/events.ts +++ b/lib/events.ts @@ -6,7 +6,7 @@ import type { Stringified, Tag, } from "../core/nips/01.ts"; -import type { RelayLike } from "../client.ts"; +import type { RelayLike } from "../core/relays.ts"; export { EventKind } from "../core/nips/01.ts"; diff --git a/lib/notes.ts b/lib/notes.ts index 31a1daa..d733f40 100644 --- a/lib/notes.ts +++ b/lib/notes.ts @@ -2,7 +2,7 @@ import { EventKind, NostrEvent, RelayUrl, TagName } from "../core/nips/01.ts"; import type { Optional } from "../core/types.ts"; import { EventInit } from "./events.ts"; -export type TextNote = EventInit; +export type TextNote = EventInit>; export type TextNoteInit = Optional; @@ -29,6 +29,6 @@ export class TextNoteComposer extends TransformStream { ["p" as TagName, opts.replyTo.pubkey, relayRecommend ?? ""], ] : []); - return { ...init, kind: EventKind.TextNote, tags }; + return { ...init, kind: EventKind.$(1), tags }; } } diff --git a/lib/pools.ts b/lib/pools.ts index 7884c05..93828b3 100644 --- a/lib/pools.ts +++ b/lib/pools.ts @@ -4,7 +4,12 @@ import type { RelayUrl, SubscriptionFilter, } from "../core/nips/01.ts"; -import { Relay, RelayInit, RelayLike, SubscriptionOptions } from "../client.ts"; +import { + Relay, + RelayInit, + RelayLike, + SubscriptionOptions, +} from "../core/relays.ts"; import { NonExclusiveWritableStream } from "../core/streams.ts"; import { Distinctor, merge } from "../lib/streams.ts"; diff --git a/lib/signs_test.ts b/lib/signs_test.ts index 7af7cb2..0837e05 100644 --- a/lib/signs_test.ts +++ b/lib/signs_test.ts @@ -1,3 +1,4 @@ +import { EventKind } from "../core/nips/01.ts"; import { describe, it } from "../lib/std/testing.ts"; import { assert, assertEquals } from "../lib/std/assert.ts"; import { Timestamp } from "../lib/times.ts"; @@ -24,7 +25,7 @@ describe("Signer/Verifier", () => { const event = { pubkey: PublicKey.from(nsec), created_at: Timestamp.now, - kind: 1, + kind: EventKind[1], tags: [], content: "lophus", }; diff --git a/lib/std/streams.ts b/lib/std/streams.ts new file mode 100644 index 0000000..a807df2 --- /dev/null +++ b/lib/std/streams.ts @@ -0,0 +1 @@ +export { mergeReadableStreams } from "https://deno.land/std@0.203.0/streams/mod.ts"; diff --git a/lib/streams.ts b/lib/streams.ts index 23c580a..4e64151 100644 --- a/lib/streams.ts +++ b/lib/streams.ts @@ -1,4 +1,4 @@ -export { mergeReadableStreams as merge } from "https://deno.land/std@0.203.0/streams/mod.ts"; +export { mergeReadableStreams as merge } from "./std/streams.ts"; /** * TransformStream which filters out duplicate values from a stream.