From f0df4c7297a05bd592d8717b8997284c80fd0500 Mon Sep 17 00:00:00 2001 From: polwex Date: Wed, 17 Sep 2025 15:56:00 +0700 Subject: argh --- front/src/logic/api.ts | 2 +- front/src/logic/nostril.ts | 36 --------- front/src/logic/nostrill.ts | 118 +++++++++++++++++++++++++++++ front/src/logic/requests/nostril.ts | 139 ----------------------------------- front/src/logic/requests/nostrill.ts | 139 +++++++++++++++++++++++++++++++++++ 5 files changed, 258 insertions(+), 176 deletions(-) delete mode 100644 front/src/logic/nostril.ts create mode 100644 front/src/logic/nostrill.ts delete mode 100644 front/src/logic/requests/nostril.ts create mode 100644 front/src/logic/requests/nostrill.ts (limited to 'front/src/logic') diff --git a/front/src/logic/api.ts b/front/src/logic/api.ts index b8acba2..52635e5 100644 --- a/front/src/logic/api.ts +++ b/front/src/logic/api.ts @@ -8,7 +8,7 @@ export async function start(): Promise { const ship = await res.text(); airlock.ship = ship.slice(1); airlock.our = ship; - airlock.desk = "nostril"; + airlock.desk = "nostrill"; await airlock.poke({ app: "hood", mark: "helm-hi", json: "opening airlock" }); await airlock.eventSource(); return airlock; diff --git a/front/src/logic/nostril.ts b/front/src/logic/nostril.ts deleted file mode 100644 index 4e5549d..0000000 --- a/front/src/logic/nostril.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { Event } from "@/types/nostr"; -import type { FC, FlatFeed, Poast } from "@/types/trill"; -import { engagementBunt, openLock } from "./bunts"; -export function eventsToFc(relayData: Record): FC { - const start = null; - const end = null; - const feed = Object.values(relayData).reduce((acc: FlatFeed, events) => { - const poasts = events.map(eventToPoast); - for (const p of poasts) { - if (p) acc[p.id] = p; - } - return acc; - }, {}); - return { feed, start, end }; -} -export function eventToPoast(event: Event): Poast | null { - if (event.kind !== 1) return null; - const contents = [{ paragraph: [{ text: event.content }] }]; - const ts = event.created_at * 1000; - const id = `${ts}`; - const poast: Poast = { - id, - host: event.pubkey, - author: event.pubkey, - contents, - thread: id, - parent: null, - read: openLock, - write: openLock, - tags: [], - time: ts, - engagement: engagementBunt, - children: [], - }; - return poast; -} diff --git a/front/src/logic/nostrill.ts b/front/src/logic/nostrill.ts new file mode 100644 index 0000000..bf9212d --- /dev/null +++ b/front/src/logic/nostrill.ts @@ -0,0 +1,118 @@ +import type { Event } from "@/types/nostr"; +import type { Content, FC, Poast } from "@/types/trill"; +import { engagementBunt, openLock } from "./bunts"; +export function eventsToFc(postEvents: Event[]): FC { + const fc = postEvents.reduce( + (acc: FC, event: Event) => { + const p = eventToPoast(event); + if (!p) return acc; + acc.feed[p.id] = p; + if (!acc.start || event.created_at < Number(acc.start)) acc.start = p.id; + if (!acc.end || event.created_at > Number(acc.end)) acc.end = p.id; + return acc; + }, + { feed: {}, start: null, end: null } as FC, + ); + return fc; +} +export function eventToPoast(event: Event): Poast | null { + if (event.kind !== 1) return null; + const contents: Content = [{ paragraph: [{ text: event.content }] }]; + const ts = event.created_at * 1000; + const id = `${ts}`; + const poast: Poast = { + id, + host: event.pubkey, + author: event.pubkey, + contents, + thread: id, + parent: null, + read: openLock, + write: openLock, + tags: [], + time: ts, + engagement: engagementBunt, + children: [], + }; + for (const tag of event.tags) { + const f = tag[0]; + if (!f) continue; + const ff = f.toLowerCase(); + console.log("tag", ff); + if (ff === "e") { + const [, eventId, _relayURL, marker, _pubkey, ..._] = tag; + // TODO + if (marker === "root") poast.thread = eventId; + else if (marker === "reply") poast.parent = eventId; + } + // + if (ff === "r") + contents.push({ + paragraph: [{ link: { show: tag[1]!, href: tag[1]! } }], + }); + if (ff === "p") + contents.push({ + paragraph: [{ ship: tag[1]! }], + }); + if (ff === "q") + contents.push({ + ref: { + type: "nostr", + ship: tag[1]!, + path: tag[2] || "" + `/${tag[3] || ""}`, + }, + }); + } + return poast; +} + +// NOTE common tags: +// imeta +// client +// nonce +// proxy + +// export function parseEventTags(event: Event) { +// const effects: any[] = []; +// for (const tag of event.tags) { +// const f = tag[0]; +// if (!f) continue; +// const ff = f.toLowerCase(); +// switch (ff) { +// case "p": { +// const [, pubkey, relayURL, ..._] = tag; +// // people mention +// break; +// } +// case "e": { +// // marker to be "root" or "reply" +// // event mention +// break; +// } +// case "q": { +// const [, eventId, relayURL, pubkey, ..._] = tag; +// // event mention +// break; +// } +// case "t": { +// const [, hashtag, ..._] = tag; +// // event mention +// break; +// } +// case "r": { +// const [, url, ..._] = tag; +// // event mention +// break; +// } +// case "alt": { +// const [, summary, ..._] = tag; +// // event mention +// break; +// } +// default: { +// break; +// } +// } +// } +// return effects; +// } diff --git a/front/src/logic/requests/nostril.ts b/front/src/logic/requests/nostril.ts deleted file mode 100644 index 6f0edcf..0000000 --- a/front/src/logic/requests/nostril.ts +++ /dev/null @@ -1,139 +0,0 @@ -import type Urbit from "urbit-api"; -import type { Cursor, PostID, SentPoast } from "@/types/trill"; -import type { Ship } from "@/types/urbit"; -import { FeedPostCount } from "../constants"; -import type { UserProfile } from "@/types/nostril"; - -// Subscribe -type Handler = (date: any) => void; -export default class IO { - airlock; - constructor(airlock: Urbit) { - this.airlock = airlock; - } - private async poke(json: any) { - return this.airlock.poke({ app: "nostril", mark: "json", json }); - } - private async scry(path: string) { - return this.airlock.scry({ app: "nostril", path }); - } - private async sub(path: string, handler: Handler) { - const err = (err: any, _id: string) => - console.log(err, "error on nostril subscription"); - const quit = (data: any) => - console.log(data, "nostril subscription kicked"); - const res = await this.airlock.subscribe({ - app: "nostril", - path, - event: handler, - err, - quit, - }); - console.log(res, "subscribed to nostril agent"); - } - async unsub(sub: number) { - return await this.airlock.unsubscribe(sub); - } - // subs - async subscribeStore(handler: Handler) { - const res = await this.sub("/ui", handler); - return res; - } - // scries - - async scryFeed(start: Cursor, end: Cursor, desc = true) { - const order = desc ? 1 : 0; - const term = "feed"; - - const path = `/j/feed/${term}/${start}/${end}/${FeedPostCount}/${order}`; - return await this.scry(path); - } - async scryPost( - host: Ship, - id: PostID, - start: Cursor, - end: Cursor, - desc = true, - ) { - const order = desc ? 1 : 0; - - const path = `/j/post/${host}/${id}/${start}/${end}/${FeedPostCount}/${order}`; - return await this.scry(path); - } - // pokes - - async pokeAlive() { - return await this.poke({ alive: true }); - } - async addPost(pubkey: string, content: string) { - const json = { add: { pubkey, content } }; - return this.poke({ post: json }); - } - // async addPost(post: SentPoast, gossip: boolean) { - // const json = { - // "new-post": { - // "sent-post": post, - // gossip, - // }, - // }; - // return this.poke(json); - // } - - async deletePost(id: string) { - const host = `~${this.airlock.ship}`; - const json = { - "del-post": { - ship: host, - id: id, - }, - }; - return this.poke(json); - } - - async addReact(ship: Ship, id: PostID, reaction: string) { - const json = { - "new-react": { - react: reaction, - pid: { - id: id, - ship: ship, - }, - }, - }; - - return this.poke(json); - } - - // follows - async follow(ship: Ship) { - const json = { add: ship }; - return this.poke({ fols: json }); - } - - async unfollow(ship: Ship) { - const json = { del: ship }; - return await this.poke({ fols: json }); - } - // profiles - async createProfile(pubkey: string, profile: UserProfile) { - const json = { add: { pubkey, profile } }; - return await this.poke({ prof: json }); - } - async createKey() { - const json = { add: null }; - return await this.poke({ keys: json }); - } - async removeKey(pubkey: string) { - const json = { del: pubkey }; - return await this.poke({ keys: json }); - } - // relaying - async relayPost(host: string, id: string, relays: string[]) { - const json = { send: { host, id, relays } }; - return await this.poke({ rela: json }); - } -} - -// notifications - -// mark as read diff --git a/front/src/logic/requests/nostrill.ts b/front/src/logic/requests/nostrill.ts new file mode 100644 index 0000000..6334c34 --- /dev/null +++ b/front/src/logic/requests/nostrill.ts @@ -0,0 +1,139 @@ +import type Urbit from "urbit-api"; +import type { Cursor, PostID } from "@/types/trill"; +import type { Ship } from "@/types/urbit"; +import { FeedPostCount } from "../constants"; +import type { UserProfile } from "@/types/nostrill"; + +// Subscribe +type Handler = (date: any) => void; +export default class IO { + airlock; + constructor(airlock: Urbit) { + this.airlock = airlock; + } + private async poke(json: any) { + return this.airlock.poke({ app: "nostrill", mark: "json", json }); + } + private async scry(path: string) { + return this.airlock.scry({ app: "nostrill", path }); + } + private async sub(path: string, handler: Handler) { + const err = (err: any, _id: string) => + console.log(err, "error on nostrill subscription"); + const quit = (data: any) => + console.log(data, "nostrill subscription kicked"); + const res = await this.airlock.subscribe({ + app: "nostrill", + path, + event: handler, + err, + quit, + }); + console.log(res, "subscribed to nostrill agent"); + } + async unsub(sub: number) { + return await this.airlock.unsubscribe(sub); + } + // subs + async subscribeStore(handler: Handler) { + const res = await this.sub("/ui", handler); + return res; + } + // scries + + async scryFeed(start: Cursor, end: Cursor, desc = true) { + const order = desc ? 1 : 0; + const term = "feed"; + + const path = `/j/feed/${term}/${start}/${end}/${FeedPostCount}/${order}`; + return await this.scry(path); + } + async scryPost( + host: Ship, + id: PostID, + start: Cursor, + end: Cursor, + desc = true, + ) { + const order = desc ? 1 : 0; + + const path = `/j/post/${host}/${id}/${start}/${end}/${FeedPostCount}/${order}`; + return await this.scry(path); + } + // pokes + + async pokeAlive() { + return await this.poke({ alive: true }); + } + async addPost(content: string) { + const json = { add: { content } }; + return this.poke({ post: json }); + } + // async addPost(post: SentPoast, gossip: boolean) { + // const json = { + // "new-post": { + // "sent-post": post, + // gossip, + // }, + // }; + // return this.poke(json); + // } + + async deletePost(id: string) { + const host = `~${this.airlock.ship}`; + const json = { + "del-post": { + ship: host, + id: id, + }, + }; + return this.poke(json); + } + + async addReact(ship: Ship, id: PostID, reaction: string) { + const json = { + "new-react": { + react: reaction, + pid: { + id: id, + ship: ship, + }, + }, + }; + + return this.poke(json); + } + + // follows + async follow(ship: Ship) { + const json = { add: ship }; + return this.poke({ fols: json }); + } + + async unfollow(ship: Ship) { + const json = { del: ship }; + return await this.poke({ fols: json }); + } + // profiles + async createProfile(pubkey: string, profile: UserProfile) { + const json = { add: { pubkey, profile } }; + return await this.poke({ prof: json }); + } + async createKey() { + const json = { add: null }; + return await this.poke({ keys: json }); + } + async removeKey(pubkey: string) { + const json = { del: pubkey }; + return await this.poke({ keys: json }); + } + // relaying + async relayPost(host: string, id: string, relays: string[]) { + const json = { send: { host, id, relays } }; + return await this.poke({ rela: json }); + } +} + +// notifications + +// mark as read -- cgit v1.2.3