From 87a91c2dafbdae4432b6a4295f1f91099fd8677b Mon Sep 17 00:00:00 2001
From: fiatjaf <fiatjaf@gmail.com>
Date: Wed, 29 May 2024 13:37:45 -0300
Subject: [PATCH] fix useWebSocketImplementation so it works with pool on
 nodejs esm.

---
 README.md         |  9 ++++++---
 abstract-pool.ts  | 17 +++++++++++++++--
 abstract-relay.ts | 20 +++++++++-----------
 index.ts          |  4 ++--
 package.json      |  2 +-
 pool.test.ts      |  3 +--
 pool.ts           | 14 +++++++++++++-
 relay.ts          | 14 +++++++++++++-
 8 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index c131560f..c89a536a 100644
--- a/README.md
+++ b/README.md
@@ -104,8 +104,11 @@ relay.close()
 To use this on Node.js you first must install `ws` and call something like this:
 
 ```js
-import { useWebSocketImplementation } from 'nostr-tools/relay'
-useWebSocketImplementation(require('ws'))
+import { useWebSocketImplementation } from 'nostr-tools/pool'
+// or import { useWebSocketImplementation } from 'nostr-tools/relay' if you're using the Relay directly
+
+import WebSocket from 'ws'
+useWebSocketImplementation(WebSocket)
 ```
 
 ### Interacting with multiple relays
@@ -197,7 +200,7 @@ declare global {
 
 ### Generating NIP-06 keys
 ```js
-import { 
+import {
   privateKeyFromSeedWords,
   accountFromSeedWords,
   extendedKeysFromSeedWords,
diff --git a/abstract-pool.ts b/abstract-pool.ts
index 730147e2..263a962f 100644
--- a/abstract-pool.ts
+++ b/abstract-pool.ts
@@ -1,4 +1,11 @@
-import { AbstractRelay as AbstractRelay, SubscriptionParams, Subscription } from './abstract-relay.ts'
+/* global WebSocket */
+
+import {
+  AbstractRelay as AbstractRelay,
+  SubscriptionParams,
+  Subscription,
+  type AbstractRelayConstructorOptions,
+} from './abstract-relay.ts'
 import { normalizeURL } from './utils.ts'
 
 import type { Event, Nostr } from './core.ts'
@@ -7,6 +14,8 @@ import { alwaysTrue } from './helpers.ts'
 
 export type SubCloser = { close: () => void }
 
+export type AbstractPoolConstructorOptions = AbstractRelayConstructorOptions & {}
+
 export type SubscribeManyParams = Omit<SubscriptionParams, 'onclose' | 'id'> & {
   maxWait?: number
   onclose?: (reasons: string[]) => void
@@ -21,8 +30,11 @@ export class AbstractSimplePool {
   public verifyEvent: Nostr['verifyEvent']
   public trustedRelayURLs: Set<string> = new Set()
 
-  constructor(opts: { verifyEvent: Nostr['verifyEvent'] }) {
+  private _WebSocket?: typeof WebSocket
+
+  constructor(opts: AbstractPoolConstructorOptions) {
     this.verifyEvent = opts.verifyEvent
+    this._WebSocket = opts.websocketImplementation
   }
 
   async ensureRelay(url: string, params?: { connectionTimeout?: number }): Promise<AbstractRelay> {
@@ -32,6 +44,7 @@ export class AbstractSimplePool {
     if (!relay) {
       relay = new AbstractRelay(url, {
         verifyEvent: this.trustedRelayURLs.has(url) ? alwaysTrue : this.verifyEvent,
+        websocketImplementation: this._WebSocket,
       })
       if (params?.connectionTimeout) relay.connectionTimeout = params.connectionTimeout
       this.relays.set(url, relay)
diff --git a/abstract-relay.ts b/abstract-relay.ts
index 30370033..69a2306a 100644
--- a/abstract-relay.ts
+++ b/abstract-relay.ts
@@ -7,14 +7,9 @@ import { Queue, normalizeURL } from './utils.ts'
 import { makeAuthEvent } from './nip42.ts'
 import { yieldThread } from './helpers.ts'
 
-var _WebSocket: typeof WebSocket
-
-try {
-  _WebSocket = WebSocket
-} catch {}
-
-export function useWebSocketImplementation(websocketImplementation: any) {
-  _WebSocket = websocketImplementation
+export type AbstractRelayConstructorOptions = {
+  verifyEvent: Nostr['verifyEvent']
+  websocketImplementation?: typeof WebSocket
 }
 
 export class AbstractRelay {
@@ -42,12 +37,15 @@ export class AbstractRelay {
   private serial: number = 0
   private verifyEvent: Nostr['verifyEvent']
 
-  constructor(url: string, opts: { verifyEvent: Nostr['verifyEvent'] }) {
+  private _WebSocket: typeof WebSocket
+
+  constructor(url: string, opts: AbstractRelayConstructorOptions) {
     this.url = normalizeURL(url)
     this.verifyEvent = opts.verifyEvent
+    this._WebSocket = opts.websocketImplementation || WebSocket
   }
 
-  static async connect(url: string, opts: { verifyEvent: Nostr['verifyEvent'] }): Promise<AbstractRelay> {
+  static async connect(url: string, opts: AbstractRelayConstructorOptions): Promise<AbstractRelay> {
     const relay = new AbstractRelay(url, opts)
     await relay.connect()
     return relay
@@ -87,7 +85,7 @@ export class AbstractRelay {
       }, this.connectionTimeout)
 
       try {
-        this.ws = new _WebSocket(this.url)
+        this.ws = new this._WebSocket(this.url)
       } catch (err) {
         reject(err)
         return
diff --git a/index.ts b/index.ts
index dd80f8bd..2a19672f 100644
--- a/index.ts
+++ b/index.ts
@@ -1,7 +1,7 @@
 export * from './pure.ts'
-export * from './relay.ts'
+export { Relay } from './relay.ts'
 export * from './filter.ts'
-export * from './pool.ts'
+export { SimplePool } from './pool.ts'
 export * from './references.ts'
 
 export * as nip04 from './nip04.ts'
diff --git a/package.json b/package.json
index 889d8eb3..cba80fb4 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "type": "module",
   "name": "nostr-tools",
-  "version": "2.6.0",
+  "version": "2.7.0",
   "description": "Tools for making a Nostr client.",
   "repository": {
     "type": "git",
diff --git a/pool.test.ts b/pool.test.ts
index 7b594f75..c90cac88 100644
--- a/pool.test.ts
+++ b/pool.test.ts
@@ -1,8 +1,7 @@
 import { afterEach, beforeEach, expect, test } from 'bun:test'
 
-import { SimplePool } from './pool.ts'
+import { SimplePool, useWebSocketImplementation } from './pool.ts'
 import { finalizeEvent, generateSecretKey, getPublicKey, type Event } from './pure.ts'
-import { useWebSocketImplementation } from './relay.ts'
 import { MockRelay, MockWebSocketClient } from './test-helpers.ts'
 import { hexToBytes } from '@noble/hashes/utils'
 
diff --git a/pool.ts b/pool.ts
index d8333ce2..37c970e3 100644
--- a/pool.ts
+++ b/pool.ts
@@ -1,9 +1,21 @@
+/* global WebSocket */
+
 import { verifyEvent } from './pure.ts'
 import { AbstractSimplePool } from './abstract-pool.ts'
 
+var _WebSocket: typeof WebSocket
+
+try {
+  _WebSocket = WebSocket
+} catch {}
+
+export function useWebSocketImplementation(websocketImplementation: any) {
+  _WebSocket = websocketImplementation
+}
+
 export class SimplePool extends AbstractSimplePool {
   constructor() {
-    super({ verifyEvent })
+    super({ verifyEvent, websocketImplementation: _WebSocket })
   }
 }
 
diff --git a/relay.ts b/relay.ts
index 3cb0deac..6277d232 100644
--- a/relay.ts
+++ b/relay.ts
@@ -1,3 +1,5 @@
+/* global WebSocket */
+
 import { verifyEvent } from './pure.ts'
 import { AbstractRelay } from './abstract-relay.ts'
 
@@ -8,9 +10,19 @@ export function relayConnect(url: string): Promise<Relay> {
   return Relay.connect(url)
 }
 
+var _WebSocket: typeof WebSocket
+
+try {
+  _WebSocket = WebSocket
+} catch {}
+
+export function useWebSocketImplementation(websocketImplementation: any) {
+  _WebSocket = websocketImplementation
+}
+
 export class Relay extends AbstractRelay {
   constructor(url: string) {
-    super(url, { verifyEvent })
+    super(url, { verifyEvent, websocketImplementation: _WebSocket })
   }
 
   static async connect(url: string): Promise<Relay> {