getFilterLimit: handle parameterized replaceable events
This commit is contained in:
parent
a87099fa5c
commit
9c009ac543
|
@ -215,6 +215,16 @@ describe('Filter', () => {
|
||||||
expect(getFilterLimit({ kinds: [0, 3], authors: ['alex', 'fiatjaf'] })).toEqual(4)
|
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', () => {
|
test('should return Infinity for authors with regular kinds', () => {
|
||||||
expect(getFilterLimit({ kinds: [1], authors: ['alex'] })).toEqual(Infinity)
|
expect(getFilterLimit({ kinds: [1], authors: ['alex'] })).toEqual(Infinity)
|
||||||
})
|
})
|
||||||
|
|
17
filter.ts
17
filter.ts
|
@ -1,5 +1,5 @@
|
||||||
import { Event } from './core.ts'
|
import { Event } from './core.ts'
|
||||||
import { isReplaceableKind } from './kinds.ts'
|
import { isParameterizedReplaceableKind, isReplaceableKind } from './kinds.ts'
|
||||||
|
|
||||||
export type Filter = {
|
export type Filter = {
|
||||||
ids?: string[]
|
ids?: string[]
|
||||||
|
@ -72,7 +72,10 @@ export function mergeFilters(...filters: Filter[]): Filter {
|
||||||
return result
|
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 {
|
export function getFilterLimit(filter: Filter): number {
|
||||||
if (filter.ids && !filter.ids.length) return 0
|
if (filter.ids && !filter.ids.length) return 0
|
||||||
if (filter.kinds && !filter.kinds.length) return 0
|
if (filter.kinds && !filter.kinds.length) return 0
|
||||||
|
@ -83,10 +86,20 @@ export function getFilterLimit(filter: Filter): number {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.min(
|
return Math.min(
|
||||||
|
// The `limit` property creates an artificial limit.
|
||||||
Math.max(0, filter.limit ?? Infinity),
|
Math.max(0, filter.limit ?? Infinity),
|
||||||
|
|
||||||
|
// There can only be one event per `id`.
|
||||||
filter.ids?.length ?? Infinity,
|
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?.every(kind => isReplaceableKind(kind))
|
||||||
? filter.authors.length * filter.kinds.length
|
? filter.authors.length * filter.kinds.length
|
||||||
: Infinity,
|
: 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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue