diff --git a/packages/app/src/relayLists.ts b/packages/app/src/relayLists.ts index 57f6763..f91e6e3 100644 --- a/packages/app/src/relayLists.ts +++ b/packages/app/src/relayLists.ts @@ -5,6 +5,7 @@ import { TrustedEvent, getRelaysFromList, RelayMode, + Filter, } from "@welshman/util" import { deriveItemsByKey, @@ -52,9 +53,9 @@ export const deriveRelayList = makeDeriveItem(relayListsByPubkey, loadRelayList) // Outbox loader export const makeOutboxLoader = - (kind: number) => + (kind: number, filter: Filter = {}) => async (pubkey: string, relayHints: string[] = []) => { - const filters = [{kinds: [kind], authors: [pubkey]}] + const filters = [{...filter, kinds: [kind], authors: [pubkey]}] const relays = Router.get().FromRelays(relayHints).policy(addMinimalFallbacks).getUrls() await Promise.all([ diff --git a/packages/net/src/policy.ts b/packages/net/src/policy.ts index 85ad4f9..fe1da4d 100644 --- a/packages/net/src/policy.ts +++ b/packages/net/src/policy.ts @@ -25,6 +25,35 @@ import {Unsubscriber} from "./util.js" */ export type SocketPolicy = (socket: Socket) => Unsubscriber +/** + * Sends a ping message every so often to ensure connection health + * @param socket - a Socket object + * @return a cleanup function + */ +export const socketPolicyPing = (socket: Socket) => { + let lastActivity = 0 + + const unsubscribers = [ + on(socket, SocketEvent.Send, (message: ClientMessage) => { + lastActivity = Date.now() + }), + on(socket, SocketEvent.Receive, (message: ClientMessage) => { + lastActivity = Date.now() + }), + ] + + const interval = setInterval(() => { + if (socket.status === SocketStatus.Open && lastActivity < Date.now() - 30_000) { + socket._ws?.send('["PING"]') + } + }, 30_000) + + return () => { + unsubscribers.forEach(call) + clearInterval(interval) + } +} + /** * Handles auth-related message management: * - Defers sending messages when a challenge is pending @@ -232,6 +261,7 @@ export const makeSocketPolicyAuth = (options: SocketPolicyAuthOptions) => (socke } export const defaultSocketPolicies = [ + socketPolicyPing, socketPolicyAuthBuffer, socketPolicyConnectOnSend, socketPolicyCloseInactive, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c121612..241fe5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ settings: overrides: '@tiptap/core': ^2.11.7 '@tiptap/pm': ^2.11.7 + '@pomade/core': link:../pomade/packages/core importers: @@ -172,6 +173,9 @@ importers: packages/app: dependencies: + '@pomade/core': + specifier: link:../../../pomade/packages/core + version: link:../../../pomade/packages/core '@types/throttle-debounce': specifier: ^5.0.2 version: 5.0.2 @@ -206,9 +210,6 @@ importers: specifier: ^5.0.2 version: 5.0.2 devDependencies: - '@pomade/core': - specifier: ^0.0.5 - version: 0.0.5(typescript@5.8.2)(ws@8.18.1) rimraf: specifier: ~6.0.0 version: 6.0.1 @@ -395,6 +396,9 @@ importers: '@noble/hashes': specifier: ^2.0.1 version: 2.0.1 + '@pomade/core': + specifier: link:../../../pomade/packages/core + version: link:../../../pomade/packages/core '@welshman/lib': specifier: workspace:* version: link:../lib @@ -411,9 +415,6 @@ importers: '@capacitor/core': specifier: ^7.2.0 version: 7.2.0 - '@pomade/core': - specifier: ^0.0.5 - version: 0.0.5(typescript@5.8.2)(ws@8.18.1) nostr-signer-capacitor-plugin: specifier: ~0.0.4 version: 0.0.4(@capacitor/core@7.2.0) @@ -581,15 +582,6 @@ packages: '@capacitor/core@7.2.0': resolution: {integrity: sha512-2zCnA6RJeZ9ec4470o8QMZEQTWpekw9FNoqm5TLc10jeCrhvHVI8MPgxdZVc3mOdFlyieYu4AS1fNxSqbS57Pw==} - '@cmdcode/buff@2.2.5': - resolution: {integrity: sha512-+nc3QDoJ+MU/fp+YkX6WuEjJrXLF6ME+eVX1sj5a+MfBKO9LWb4R9Y2zH6APBrySd7nFr48ozscAui7SKvLmXg==} - - '@cmdcode/frost@1.1.3': - resolution: {integrity: sha512-Aap5+IqJCisHJzdFJS4h+i5IRaw/yrZ5m5tpoGpKPBljMWjH3K17iD53VvLEQPI85l2asDrjj8vnrFKlwnK7zw==} - - '@cmdcode/nostr-p2p@2.0.11': - resolution: {integrity: sha512-hZpWYqRPdvXoaG5LaP2/dR1ObloQxPUYHAA1japQveGdhPbXWiS5aKPxOyUXqgjHDShWeXQ3giOTg6SsCJwnYA==} - '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -805,9 +797,6 @@ packages: resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@frostr/bifrost@1.0.7': - resolution: {integrity: sha512-9PO8s8ra7Cf94HqsF0sArRkLLFYqDyGfRKUOflTWMGgaDvSWIksNA8PckcXvy5/G6u4RtAkTAqki47+ga+7yow==} - '@gerrit0/mini-shiki@3.2.2': resolution: {integrity: sha512-vaZNGhGLKMY14HbF53xxHNgFO9Wz+t5lTlGNpl2N9xFiKQ0I5oIe0vKjU9dh7Nb3Dw6lZ7wqUE0ri+zcdpnK+Q==} @@ -895,10 +884,6 @@ packages: '@noble/ciphers@0.5.3': resolution: {integrity: sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==} - '@noble/ciphers@1.3.0': - resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} - engines: {node: ^14.21.3 || >=16} - '@noble/curves@1.1.0': resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} @@ -949,10 +934,6 @@ packages: resolution: {integrity: sha512-vsJDAkYR6qCPu+ioGScGiMYR7LvZYIXh/dlQeviqoTWNCVfKTLYD/LkNWH4Mxsv2a5vpIRc77FN5DnmK1eBggQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@pomade/core@0.0.5': - resolution: {integrity: sha512-LNKV+R/Il+Bmo4Wq7W+oWdsbcA784GhfjXVU4YXKBlhKvFfv2Mqw8JL+mYtS4REzs7MgUnwTtgUD7thD9GWTfg==} - engines: {node: '>=12.0.0'} - '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -1736,16 +1717,6 @@ packages: '@vueuse/shared@12.8.2': resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==} - '@welshman/lib@0.7.1': - resolution: {integrity: sha512-NQkxPwnAoUY4uSroQcfvR4YPG63j7Ke0R9YrLNXF9SQn2t2p6iAQ6A3GEOVu/koUQiVBseYn514lS7X1XkCP3A==} - engines: {node: '>=12.0.0'} - - '@welshman/net@0.7.1': - resolution: {integrity: sha512-S3dFH73Cy4phLy5I2KKEeefkRmNBYWB2qONK8txUVDhx1u7ezpALzZEMSPVqVIZk/vCQU3KJ0CyagvbuGF+F9Q==} - - '@welshman/util@0.7.1': - resolution: {integrity: sha512-UGryq1jfwRHFS7mjGa4fmuqN851iwKeR+616LmUpTJQHAfhGU7ifer2+JLdDLYBU/neI5iKHdRDO5hg92U6k8Q==} - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1841,10 +1812,6 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - base58-js@3.0.3: - resolution: {integrity: sha512-3hf42BysHnUqmZO7mK6e5X/hs1AvyEJIhdVLbG/Mxn/fhFnhGxOO37mWbMHg1RT4TxqcPKXgqj9/bp1YG0GBXA==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -2213,9 +2180,6 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - hash-wasm@4.12.0: - resolution: {integrity: sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -2519,14 +2483,6 @@ packages: typescript: optional: true - nostr-tools@2.19.4: - resolution: {integrity: sha512-qVLfoTpZegNYRJo5j+Oi6RPu0AwLP6jcvzcB3ySMnIT5DrAGNXfs5HNBspB/2HiGfH3GY+v6yXkTtcKSBQZwSg==} - peerDependencies: - typescript: '>=5.0.0' - peerDependenciesMeta: - typescript: - optional: true - nostr-wasm@0.1.0: resolution: {integrity: sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==} @@ -3250,12 +3206,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} - zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -3394,27 +3344,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@cmdcode/buff@2.2.5': - dependencies: - '@noble/hashes': 1.8.0 - '@scure/base': 1.2.4 - - '@cmdcode/frost@1.1.3': - dependencies: - '@cmdcode/buff': 2.2.5 - '@noble/curves': 1.9.7 - '@noble/hashes': 1.8.0 - - '@cmdcode/nostr-p2p@2.0.11(typescript@5.8.2)': - dependencies: - '@cmdcode/buff': 2.2.5 - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.7 - nostr-tools: 2.19.4(typescript@5.8.2) - zod: 3.25.76 - transitivePeerDependencies: - - typescript - '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -3575,17 +3504,6 @@ snapshots: '@eslint/core': 0.13.0 levn: 0.4.1 - '@frostr/bifrost@1.0.7(typescript@5.8.2)': - dependencies: - '@cmdcode/buff': 2.2.5 - '@cmdcode/frost': 1.1.3 - '@cmdcode/nostr-p2p': 2.0.11(typescript@5.8.2) - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.7 - zod: 3.25.76 - transitivePeerDependencies: - - typescript - '@gerrit0/mini-shiki@3.2.2': dependencies: '@shikijs/engine-oniguruma': 3.2.1 @@ -3706,8 +3624,6 @@ snapshots: '@noble/ciphers@0.5.3': {} - '@noble/ciphers@1.3.0': {} - '@noble/curves@1.1.0': dependencies: '@noble/hashes': 1.3.1 @@ -3748,21 +3664,6 @@ snapshots: '@pkgr/core@0.2.0': {} - '@pomade/core@0.0.5(typescript@5.8.2)(ws@8.18.1)': - dependencies: - '@frostr/bifrost': 1.0.7(typescript@5.8.2) - '@noble/hashes': 2.0.1 - '@welshman/lib': 0.7.1 - '@welshman/net': 0.7.1(typescript@5.8.2)(ws@8.18.1) - '@welshman/util': 0.7.1(typescript@5.8.2) - base58-js: 3.0.3 - hash-wasm: 4.12.0 - nostr-tools: 2.19.4(typescript@5.8.2) - zod: 4.3.5 - transitivePeerDependencies: - - typescript - - ws - '@popperjs/core@2.11.8': {} '@remirror/core-constants@3.0.0': {} @@ -4612,33 +4513,6 @@ snapshots: transitivePeerDependencies: - typescript - '@welshman/lib@0.7.1': - dependencies: - '@scure/base': 1.2.4 - '@types/events': 3.0.3 - events: 3.3.0 - - '@welshman/net@0.7.1(typescript@5.8.2)(ws@8.18.1)': - dependencies: - '@welshman/lib': 0.7.1 - '@welshman/util': 0.7.1(typescript@5.8.2) - events: 3.3.0 - isomorphic-ws: 5.0.0(ws@8.18.1) - transitivePeerDependencies: - - typescript - - ws - - '@welshman/util@0.7.1(typescript@5.8.2)': - dependencies: - '@noble/curves': 1.9.7 - '@types/ws': 8.18.1 - '@welshman/lib': 0.7.1 - js-base64: 3.7.7 - nostr-tools: 2.19.4(typescript@5.8.2) - nostr-wasm: 0.1.0 - transitivePeerDependencies: - - typescript - acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -4729,8 +4603,6 @@ snapshots: balanced-match@1.0.2: {} - base58-js@3.0.3: {} - binary-extensions@2.3.0: {} birpc@0.2.19: {} @@ -5148,8 +5020,6 @@ snapshots: has-flag@4.0.0: {} - hash-wasm@4.12.0: {} - hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -5444,18 +5314,6 @@ snapshots: optionalDependencies: typescript: 5.8.2 - nostr-tools@2.19.4(typescript@5.8.2): - dependencies: - '@noble/ciphers': 0.5.3 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.1 - '@scure/bip32': 1.3.1 - '@scure/bip39': 1.2.1 - nostr-wasm: 0.1.0 - optionalDependencies: - typescript: 5.8.2 - nostr-wasm@0.1.0: {} onchange@7.1.0: @@ -6308,8 +6166,4 @@ snapshots: yocto-queue@0.1.0: {} - zod@3.25.76: {} - - zod@4.3.5: {} - zwitch@2.0.4: {}