Work on new net

This commit is contained in:
Jon Staab
2025-02-20 16:34:43 -08:00
parent d8bbb5dd6a
commit 7706034b99
7 changed files with 168 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
build
normalize-url
Negentropy.ts
+61
View File
@@ -0,0 +1,61 @@
# @welshman/net [![version](https://badgen.net/npm/v/@welshman/net)](https://npmjs.com/package/@welshman/net)
Utilities having to do with connection management and nostr messages.
```typescript
import {ctx, setContext} from '@welshman/lib'
import {type TrustedEvent, createEvent, NOTE} from '@welshman/util'
import {subscribe, publish, getDefaultNetContext} from '@welshman/net'
// Sets up customizable event valdation, handlers, etc
setContext(getDefaultNetContext())
// Send a subscription
const sub = subscribe({
relays: ['wss://relay.example.com/'],
filters: [{kinds: [1], limit: 1}],
closeOnEose: true,
timeout: 10000,
})
sub.on(SubscriptionEvent.Event, (url: string, event: TrustedEvent) => {
console.log(url, event)
sub.close()
})
// Publish an event
const pub = publish({
relays: ['wss://relay.example.com/'],
event: createEvent(NOTE, {content: 'hi'}),
})
pub.emitter.on('*', (status: PublishStatus, url: string) => {
console.log(status, url)
})
// The Tracker class can tell you which relays an event was read from or published to
console.log(ctx.net.tracker.getRelays(event.id))
```
The main reason this module exists is to support different backends via Executor and different `target` classes. For example, to add a local relay that automatically gets used:
```typescript
import {setContext} from '@welshman/lib'
import {LOCAL_RELAY_URL, Relay, Repository} from '@welshman/util'
import {getDefaultNetContext, Multi, Local, Relays, Executor} from '@welshman/net'
const repository = new Repository()
const relay = new Relay(repository)
setContext(getDefaultNetContext({
getExecutor: (relays: string[]) => {
return new Executor(
new Multi([
new Local(relay),
new Relays(remoteUrls.map(url => ctx.net.pool.get(url))),
])
)
},
}))
```
+39
View File
@@ -0,0 +1,39 @@
{
"name": "@welshman/net2",
"version": "0.0.48",
"author": "hodlbod",
"license": "MIT",
"description": "Utilities for connecting with nostr relays.",
"publishConfig": {
"access": "public"
},
"type": "module",
"files": [
"build"
],
"types": "./build/src/index.d.ts",
"exports": {
".": {
"types": "./build/src/index.d.ts",
"import": "./build/src/index.js",
"require": "./build/src/index.js"
}
},
"scripts": {
"pub": "npm run lint && npm run build && npm publish",
"build": "gts clean && tsc",
"lint": "gts lint",
"fix": "gts fix",
"test": "mocha"
},
"devDependencies": {
"mocha": "^10.7.3"
},
"dependencies": {
"@welshman/lib": "~0.0.40",
"@welshman/util": "~0.0.59",
"isomorphic-ws": "^5.0.0",
"rxjs": "^7.8.1",
"ws": "^8.16.0"
}
}
+38
View File
@@ -0,0 +1,38 @@
import type {WebSocketSubject} from "rxjs/websocket"
import {Subject} from "rxjs"
import type {SignedEvent} from "@welshman/util"
import {createEvent, CLIENT_AUTH} from "@welshman/util"
import type {SocketResponse} from "./socket.js"
export const createAuthEvent = (url: string, challenge: string) =>
createEvent(CLIENT_AUTH, {
tags: [
["relay", url],
["challenge", challenge],
],
})
export type AuthResult = {
ok: boolean
reason?: string
}
export const authenticate = (socket: WebSocketSubject<SocketResponse>, event: SignedEvent) => {
const subject = new Subject<AuthResult>()
socket.next(["AUTH", event])
socket.subscribe(message => {
if (message[0] === "OK") {
const [id, ok = false, reason = ""] = message.slice(1)
if (id === event.id) {
subject.next({ok, reason})
}
}
})
return subject
}
export const forceAuth = <T>(socket: WebSocketSubject<T>) => {}
+10
View File
@@ -0,0 +1,10 @@
import {webSocket} from "rxjs/websocket"
import type {SignedEvent} from "@welshman/util"
export type SocketResponse =
| ["AUTH", string]
| ["EVENT", string, SignedEvent]
| ["EOSE", string, SignedEvent]
| ["OK", string, boolean, string]
export const connect = (url: string) => webSocket<SocketResponse>(url)
+14
View File
@@ -0,0 +1,14 @@
{
"extends": "../../node_modules/gts/tsconfig-google.json",
"compilerOptions": {
"rootDir": ".",
"outDir": "build",
"module": "nodenext",
"moduleResolution": "nodenext",
"lib": ["esnext", "dom"]
},
"include": [
"src/**/*.ts",
"test/**/*.ts"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"entryPoints": ["src/index.ts"]
}