Skip to content

Commit

Permalink
getFilterLimit: handle parameterized replaceable events
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgleason authored and fiatjaf committed Jul 21, 2024
1 parent a87099f commit 9c009ac
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
10 changes: 10 additions & 0 deletions filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ describe('Filter', () => {
expect(getFilterLimit({ kinds: [0, 3], authors: ['alex', 'fiatjaf'] })).toEqual(4)
})

test('should handle parameterized replaceable events', () => {
expect(getFilterLimit({ kinds: [30078], authors: ['alex'] })).toEqual(Infinity)
expect(getFilterLimit({ kinds: [30078], authors: ['alex'], '#d': ['ditto'] })).toEqual(1)
expect(getFilterLimit({ kinds: [30078], authors: ['alex'], '#d': ['ditto', 'soapbox'] })).toEqual(2)
expect(getFilterLimit({ kinds: [30078], authors: ['alex', 'fiatjaf'], '#d': ['ditto', 'soapbox'] })).toEqual(4)
expect(
getFilterLimit({ kinds: [30000, 30078], authors: ['alex', 'fiatjaf'], '#d': ['ditto', 'soapbox'] }),
).toEqual(8)
})

test('should return Infinity for authors with regular kinds', () => {
expect(getFilterLimit({ kinds: [1], authors: ['alex'] })).toEqual(Infinity)
})
Expand Down
17 changes: 15 additions & 2 deletions filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Event } from './core.ts'
import { isReplaceableKind } from './kinds.ts'
import { isParameterizedReplaceableKind, isReplaceableKind } from './kinds.ts'

export type Filter = {
ids?: string[]
Expand Down Expand Up @@ -72,7 +72,10 @@ export function mergeFilters(...filters: Filter[]): Filter {
return result
}

/** Calculate the intrinsic limit of a filter. This function may return `Infinity`. */
/**
* Calculate the intrinsic limit of a filter.
* This function returns a positive integer, or `Infinity` if there is no intrinsic limit.
*/
export function getFilterLimit(filter: Filter): number {
if (filter.ids && !filter.ids.length) return 0
if (filter.kinds && !filter.kinds.length) return 0
Expand All @@ -83,10 +86,20 @@ export function getFilterLimit(filter: Filter): number {
}

return Math.min(
// The `limit` property creates an artificial limit.
Math.max(0, filter.limit ?? Infinity),

// There can only be one event per `id`.
filter.ids?.length ?? Infinity,

// Replaceable events are limited by the number of authors and kinds.
filter.authors?.length && filter.kinds?.every(kind => isReplaceableKind(kind))
? filter.authors.length * filter.kinds.length
: Infinity,

// Parameterized replaceable events are limited by the number of authors, kinds, and "d" tags.
filter.authors?.length && filter.kinds?.every(kind => isParameterizedReplaceableKind(kind)) && filter['#d']?.length
? filter.authors.length * filter.kinds.length * filter['#d'].length
: Infinity,
)
}

0 comments on commit 9c009ac

Please sign in to comment.