Add getFilterLimit function

This commit is contained in:
Alex Gleason
2024-01-03 16:59:38 -06:00
committed by fiatjaf_
parent 498c1603b0
commit 348d118ce4
2 changed files with 41 additions and 1 deletions

View File

@@ -1,5 +1,5 @@
import { describe, test, expect } from 'bun:test' import { describe, test, expect } from 'bun:test'
import { matchFilter, matchFilters, mergeFilters } from './filter.ts' import { getFilterLimit, matchFilter, matchFilters, mergeFilters } from './filter.ts'
import { buildEvent } from './test-helpers.ts' import { buildEvent } from './test-helpers.ts'
describe('Filter', () => { describe('Filter', () => {
@@ -241,4 +241,27 @@ describe('Filter', () => {
).toEqual({ kinds: [1, 7, 9, 10], since: 10, until: 30 }) ).toEqual({ kinds: [1, 7, 9, 10], since: 10, until: 30 })
}) })
}) })
describe('getFilterLimit', () => {
test('should handle ids', () => {
expect(getFilterLimit({ ids: ['123'] })).toEqual(1)
expect(getFilterLimit({ ids: ['123'], limit: 2 })).toEqual(1)
expect(getFilterLimit({ ids: ['123'], limit: 0 })).toEqual(0)
expect(getFilterLimit({ ids: ['123'], limit: -1 })).toEqual(0)
})
test('should count the authors times replaceable kinds', () => {
expect(getFilterLimit({ kinds: [0], authors: ['alex'] })).toEqual(1)
expect(getFilterLimit({ kinds: [0, 3], authors: ['alex'] })).toEqual(2)
expect(getFilterLimit({ kinds: [0, 3], authors: ['alex', 'fiatjaf'] })).toEqual(4)
})
test('should return Infinity for authors with regular kinds', () => {
expect(getFilterLimit({ kinds: [1], authors: ['alex'] })).toEqual(Infinity)
})
test('should return Infinity for empty filters', () => {
expect(getFilterLimit({})).toEqual(Infinity)
})
})
}) })

View File

@@ -1,4 +1,5 @@
import { Event } from './core.ts' import { Event } from './core.ts'
import { isReplaceableKind } from './kinds.ts'
export type Filter = { export type Filter = {
ids?: string[] ids?: string[]
@@ -70,3 +71,19 @@ export function mergeFilters(...filters: Filter[]): Filter {
return result return result
} }
/** Calculate the intrinsic limit of a filter. This function may return `Infinity`. */
export function getFilterLimit(filter: Filter): number {
if (filter.ids && !filter.ids.length) return 0
if (filter.kinds && !filter.kinds.length) return 0
if (filter.authors && !filter.authors.length) return 0
return Math.min(
Math.max(0, filter.limit ?? Infinity),
filter.ids?.length ?? Infinity,
filter.authors?.length &&
filter.kinds?.every((kind) => isReplaceableKind(kind))
? filter.authors.length * filter.kinds.length
: Infinity,
)
}