soapbox-pub / nostrify

Bring your projects to life on Nostr. 🌱 This repo is a mirror of the source on GitLab.
https://nostrify.dev/
MIT License
5 stars 2 forks source link

Suggestion: include parsers for outbox events #2

Open antonioconselheiro opened 2 months ago

antonioconselheiro commented 2 months ago

Suggestion: include parser to cast outbox event (relay list, following list and r tag) into Record<string, { read: true, write: true }> or string[].

antonioconselheiro commented 1 month ago

gm,

I wanna extend my suggestion. Some times, events bring relays hint to help load related content, I'm not sure how you're doing to load this related content in these cases, maybe I'm suggesting some existing thing but here is my idea:

Include a hint parameter to options object:

    opts?: {
      signal?: AbortSignal,
      hint?: Array<NostrEvent> | Array<WebSocket['url']>
    }

Then delivery this hint to reqRouter as parameter, and maybe for eventRouter too. Is these function will use these parsers if the hint comes as a list of events.

This make sense?

antonioconselheiro commented 6 days ago

I'm overriding your method in my code, this suggestion-issue can be satisfied by passing the opts to router, because with that I can send any aditional information I want to router:

image

Please, send the parameter and I'll be able to remove this override from my code

alexgleason commented 6 days ago

If you have a relay hint and want to use a specific relay, I think the way is to call pool.relay(url) to get the specific relay you want. I would do this:

const relay = pool.relay(hintUrl);

let [event] = await relay.query([filter], { signal });

// Optional: fall back to the pool
if (!event) {
  event = await pool.query([filter], { signal });
}

To use multiple relays from the pool, you could just do something like

const relays = relayUrls.map((url) => pool.relay(url));

Then you have total control over the relays. If you're just looking for a single event by ID, I'd probably try:

const [event] = Promise.race(
  relays.map((relay) => relay.query([filter], { signal }),
);

Using Promise.race, you can also try querying from a specific relay and the pool at the same time:

const [event] = Promise.race(
  pool.relay(hintUrl).query([filter], { signal }),
  pool.query([filter], { signal }),
);

^ this one is probably the best one.

antonioconselheiro commented 5 days ago

To avoid distribute complexity into my application, I've decided centralized the cast (extract of relay url) of NostrEvent, ProfilePointer and NProfile in reqRouter, this help to keep my code dry.

See how I customized my npool opts interface:

export interface NPoolRequestOptions {
  /**
   * A AbortSignal allow you to emit an 'abort' event and stop request / publication when unsubscribe
   */
  signal?: AbortSignal;

  /**
   * Relays to be included in the operation
   */
  hint?: Array<WebSocket['url'] | NostrEvent | ProfilePointer | NProfile | undefined | null>;

  /**
   * Limit operation to these relays
   */
  useOnly?: Array<WebSocket['url'] | NostrEvent | ProfilePointer | NProfile>;

  /**
   * Force ignore current configured ncache and nstore and request exclusively from relay 
   */
  ignoreCache?: boolean;
}

I've tried to centralize nostr complexity into the services of my core lib. With that, dumb components can interact with nostr using only this customized pool and custom configs. With that custom configs it can be able to open events from a single relay or to load related content from an event, all without know If it's interacting with a relay, a pool of relays, if is ignoring cache.

I'm not telling you too add that customized things to nostrify, I'm asking just to send opts from *req to reqRouter, so I can keep my customized things without overriding *req in my code.