From 599e6a508570e8308858b482a79faf4da4be9684 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Tue, 9 Sep 2025 16:12:16 -0700 Subject: [PATCH] Add some type utils, findFeed, and fix feed listener to use limit: 0 instead of since --- .ackrc | 1 + docs/feeds/controller.md | 12 ++++++++++++ docs/feeds/utils.md | 17 +++++++++++++++++ docs/lib/tools.md | 30 ++++++++++++++++++++++++++++++ package.json | 2 +- packages/app/package.json | 2 +- packages/content/package.json | 2 +- packages/editor/package.json | 2 +- packages/feeds/package.json | 2 +- packages/feeds/src/controller.ts | 5 +---- packages/feeds/src/utils.ts | 14 ++++++++++++++ packages/lib/package.json | 2 +- packages/lib/src/Tools.ts | 8 ++++++++ packages/net/package.json | 2 +- packages/relay/package.json | 2 +- packages/router/package.json | 2 +- packages/signer/package.json | 2 +- packages/store/package.json | 2 +- packages/util/package.json | 2 +- 19 files changed, 95 insertions(+), 16 deletions(-) diff --git a/.ackrc b/.ackrc index 4c505ae..f817b38 100644 --- a/.ackrc +++ b/.ackrc @@ -1,3 +1,4 @@ +--ignore-dir=docs/assets --ignore-dir=docs/reference --ignore-dir=docs/.vitepress/cache --ignore-dir=dist diff --git a/docs/feeds/controller.md b/docs/feeds/controller.md index 00b5c74..f80cbb3 100644 --- a/docs/feeds/controller.md +++ b/docs/feeds/controller.md @@ -30,6 +30,12 @@ export class FeedController { // Load events with specified limit load(limit: number): Promise + + // Get listener function (memoized) + getListener(): Promise<() => Promise> + + // Listen for new events in the feed + listen(): Promise } ``` @@ -90,4 +96,10 @@ await controller.load(50) // Load more events await controller.load(50) + +// Listen for new events +const unlisten = controller.listen() + +// Unsubscribe from listener +unlisten() ``` diff --git a/docs/feeds/utils.md b/docs/feeds/utils.md index 2ff1e07..b1e0aa6 100644 --- a/docs/feeds/utils.md +++ b/docs/feeds/utils.md @@ -123,6 +123,23 @@ walkFeed(feed, (node) => { }) ``` +Find a specific feed in a feed tree: + +```typescript +const feed = makeIntersectionFeed( + makeAuthorFeed("pubkey1"), + makeUnionFeed( + makeKindFeed(1), + makeTagFeed("#t", "bitcoin") + ) +) + +// Find a feed matching a specific condition +const bitcoinTagFeed = findFeed(feed, (f) => + isTagFeed(f) && getFeedArgs(f)[1] === "bitcoin" +) +``` + ## Feed Simplification Flatten nested feeds of the same type: diff --git a/docs/lib/tools.md b/docs/lib/tools.md index 2282004..2e7e85a 100644 --- a/docs/lib/tools.md +++ b/docs/lib/tools.md @@ -2,6 +2,36 @@ The `Tools` module provides a comprehensive collection of utility functions for common programming tasks. It includes functions for array manipulation, object handling, type checking, math operations, and more. +## Working with types + +Utility types for TypeScript development: + +```typescript +// Override properties of type T with properties from type R +export type Override = Omit & R; + +// Make specific properties of type T optional +export type MakeOptional = Override>>; +``` + +Examples: +```typescript +interface User { + id: string; + name: string; + email: string; + age: number; +} + +// Override the id to be a number instead +type UserWithNumericId = Override; +// Result: { id: number; name: string; email: string; age: number; } + +// Make email and age optional +type PartialUser = MakeOptional; +// Result: { id: string; name: string; email?: string; age?: number; } +``` + ## Basic functional programming utilities ```typescript diff --git a/package.json b/package.json index 3cebefb..3d8a0a2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@welshman", "private": true, - "version": "0.4.5", + "version": "0.4.6", "workspaces": [ "packages/*" ], diff --git a/packages/app/package.json b/packages/app/package.json index bc73687..6a1195a 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/app", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A collection of svelte stores for use in building nostr client applications.", diff --git a/packages/content/package.json b/packages/content/package.json index a8ed2b1..d31e37a 100644 --- a/packages/content/package.json +++ b/packages/content/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/content", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A collection of utilities for parsing nostr note content.", diff --git a/packages/editor/package.json b/packages/editor/package.json index c42fce5..3a136a2 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/editor", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A batteries-included nostr editor.", diff --git a/packages/feeds/package.json b/packages/feeds/package.json index 0129eff..c5dde58 100644 --- a/packages/feeds/package.json +++ b/packages/feeds/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/feeds", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "Utilities for building dynamic nostr feeds.", diff --git a/packages/feeds/src/controller.ts b/packages/feeds/src/controller.ts index 182cbbc..2eb3ef1 100644 --- a/packages/feeds/src/controller.ts +++ b/packages/feeds/src/controller.ts @@ -350,12 +350,9 @@ export class FeedController { } return () => { - const since = now() const controller = new AbortController() const signal = AbortSignal.any(removeNil([controller.signal, this.options.signal])) - const requestFilters = filters! - .filter((filter: Filter) => !filter.until || filter.until <= since) - .map((filter: Filter) => ({...filter, since})) + const requestFilters = filters!.map((filter: Filter) => ({...filter, limit: 0})) requestPage( omitVals([undefined], { diff --git a/packages/feeds/src/utils.ts b/packages/feeds/src/utils.ts index 9eb3a4d..b05f8b2 100644 --- a/packages/feeds/src/utils.ts +++ b/packages/feeds/src/utils.ts @@ -214,6 +214,20 @@ export const walkFeed = (feed: Feed, visit: (feed: Feed) => void) => { } } +export const findFeed = (feed: Feed, match: (feed: Feed) => boolean): Feed | undefined => { + if (match(feed)) return feed + + if (hasSubFeeds(feed)) { + for (const subFeed of getFeedArgs(feed)) { + const found = findFeed(subFeed, match) + + if (found) { + return found + } + } + } +} + export const simplifyFeed = (feed: Feed): Feed => { if (isUnionFeed(feed)) { const args = getFeedArgs(feed) diff --git a/packages/lib/package.json b/packages/lib/package.json index 7c08f74..60a87d9 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/lib", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A collection of utilities.", diff --git a/packages/lib/src/Tools.ts b/packages/lib/src/Tools.ts index 40b6e0b..d2bffcd 100644 --- a/packages/lib/src/Tools.ts +++ b/packages/lib/src/Tools.ts @@ -14,6 +14,14 @@ export const isNotNil = (x: T, ...args: unknown[]) => x !== undefined && x != export const assertNotNil = (x: T, ...args: unknown[]) => x! +// ---------------------------------------------------------------------------- +// Working with types +// ---------------------------------------------------------------------------- + +export type Override = Omit & R + +export type MakeOptional = Override>> + // ---------------------------------------------------------------------------- // Basic functional programming utilities // ---------------------------------------------------------------------------- diff --git a/packages/net/package.json b/packages/net/package.json index e444569..7c79fd4 100644 --- a/packages/net/package.json +++ b/packages/net/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/net", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "Utilities for connecting with nostr relays.", diff --git a/packages/relay/package.json b/packages/relay/package.json index 99ed6df..af51160 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/relay", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "An in-memory nostr relay implementation.", diff --git a/packages/router/package.json b/packages/router/package.json index 87d8b82..03120e6 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/router", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A collection of utilities for nostr relay selection.", diff --git a/packages/signer/package.json b/packages/signer/package.json index ceb4890..1d7a571 100644 --- a/packages/signer/package.json +++ b/packages/signer/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/signer", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A nostr signer implemenation supporting several login methods.", diff --git a/packages/store/package.json b/packages/store/package.json index 572810d..3033d13 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/store", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A collection of utilities based on svelte/store for use with welshman", diff --git a/packages/util/package.json b/packages/util/package.json index 729ad60..2f8c2e4 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@welshman/util", - "version": "0.4.5", + "version": "0.4.6", "author": "hodlbod", "license": "MIT", "description": "A collection of nostr-related utilities.",