Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions spec/filter/util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { HRef } from '../../src/core/HRef'
import { makeRelativeHaystackFilter } from '../../src/filter/util'
import { HMarker } from '../../src/core/HMarker'
import { HStr } from '../../src/core/HStr'
import { HSymbol } from '../../src/core/HSymbol'
import { HNamespace } from '../../src/core/HNamespace'

describe('haystack', () => {
describe('makeRelativeHaystackFilter()', () => {
Expand Down Expand Up @@ -87,5 +89,57 @@ describe('haystack', () => {
)
).toEqual('id == @id')
})

it('returns a haystack filter without excluded tags', () => {
expect(
makeRelativeHaystackFilter(
new HDict({
id: HRef.make('id'),
dis: 'an equip',
equip: HMarker.make(),
his: HMarker.make(),
aux: HMarker.make(),
})
)
).toEqual('equip and dis == "an equip"')
})

it('returns a haystack filter without connPoint subtype tags', () => {
const mockNamespace = {
allSubTypesOf: () => [
HDict.make({ def: HSymbol.make('demoPoint') }),
],
} as unknown as HNamespace

expect(
makeRelativeHaystackFilter(
new HDict({
id: HRef.make('id'),
dis: 'an equip',
equip: HMarker.make(),
demoPoint: HMarker.make(),
}),
{
namespace: mockNamespace,
}
)
).toEqual('equip and dis == "an equip"')
})

it('returns a haystack filter without custom excluded tags', () => {
expect(
makeRelativeHaystackFilter(
new HDict({
id: HRef.make('id'),
dis: 'an equip',
equip: HMarker.make(),
customTag: HMarker.make(),
}),
{
getExcludedTags: () => ['customTag'],
}
)
).toEqual('equip and dis == "an equip"')
})
}) // makeRelativeHaystackFilter()
})
47 changes: 44 additions & 3 deletions src/filter/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2025, J2 Innovations. All Rights Reserved
*/

import { HNamespace } from '../core/HNamespace'
import { HDict } from '../core/dict/HDict'
import { HMarker } from '../core/HMarker'
import { HRef } from '../core/HRef'
Expand All @@ -15,14 +16,24 @@ import { HFilterBuilder } from '../filter/HFilterBuilder'
*/
export interface RelativizeOptions {
/**
* True (or undefined) if the display name should be used in the relativization.
* True (or undefined) if the display name should be used in the relative filter.
*/
useDisplayName?: boolean

/**
* True (or undefined) if a point's kind should be used in the relativization.
* True (or undefined) if a point's kind should be used in the relative filter.
*/
useKind?: boolean

/**
* The namespace to use for determining excluded tags.
*/
namespace?: HNamespace

/**
* Optional function to determine the list of tags that should be excluded from the relative filter.
*/
getExcludedTags?: (namespace?: HNamespace) => string[]
}

/**
Expand All @@ -37,12 +48,18 @@ export function makeRelativeHaystackFilter(
): string {
const useDisplayName = options?.useDisplayName ?? true
const useKind = options?.useKind ?? true
const getExcludedTags =
options?.getExcludedTags ?? getDefaultRelativizationExcludedTags
const excludedTags = new Set(getExcludedTags(options?.namespace))

const builder = new HFilterBuilder()

// Build the marker tags.
for (const { name, value } of record) {
if (valueIsKind<HMarker>(value, Kind.Marker)) {
if (
valueIsKind<HMarker>(value, Kind.Marker) &&
!excludedTags.has(name)
) {
if (!builder.isEmpty()) {
builder.and()
}
Expand Down Expand Up @@ -73,6 +90,30 @@ export function makeRelativeHaystackFilter(
return builder.build()
}

export function getDefaultRelativizationExcludedTags(
namespace?: HNamespace
): string[] {
const excludedTags = [
'aux',
'his',
'hisCollectCOV',
'hisCollectNA',
'hisTotalized',
'axStatus',
'axAnnotated',
]

if (namespace) {
const connectorPointTags = namespace
.allSubTypesOf('connPoint')
.map((def) => def.defName)

excludedTags.push(...connectorPointTags)
}

return excludedTags
}

function addPointKindToFilter(record: HDict, builder: HFilterBuilder): void {
const kind = record.get<HStr>('kind')?.value
if (kind) {
Expand Down