Skip to content

Commit

Permalink
fix(atoms): disable ecosystem.find() fuzzy search if params are pas…
Browse files Browse the repository at this point in the history
…sed (#103)
  • Loading branch information
bowheart authored Jun 11, 2024
1 parent 90b9c46 commit 20e2319
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
27 changes: 23 additions & 4 deletions packages/atoms/src/classes/Ecosystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ export class Ecosystem<Context extends Record<string, any> | undefined = any>
/**
* Get an atom instance. Don't create the atom instance if it doesn't exist.
* Don't register any graph dependencies.
*
* Tries to find an exact match, but falls back to doing a fuzzy search if no
* exact match is found. Pass atom params (or an empty array if no params or
* when passing a search string) for the second argument to disable fuzzy
* search.
*/
public find<A extends AnyAtomTemplate>(
template: A,
Expand All @@ -302,14 +307,16 @@ export class Ecosystem<Context extends Record<string, any> | undefined = any>
): AtomInstanceType<A> | undefined

public find<A extends AnyAtomTemplate = any>(
key: string
searchStr: string,
params?: []
): AtomInstanceType<A> | undefined

public find<A extends AnyAtomTemplate>(
template: A | string,
params?: AtomParamsType<A>
) {
const isString = typeof template === 'string'

if (!isString) {
const id = (template as A).getInstanceId(this, params)

Expand All @@ -319,6 +326,18 @@ export class Ecosystem<Context extends Record<string, any> | undefined = any>
if (instance) return instance
}

// if params are passed, don't fuzzy search
if (params) {
return this._instances[
isString
? template
: `${template.key}-${this._idGenerator.hashParams(
params,
this.complexParams
)}`
]
}

const matches = this.findAll(template)

return (
Expand All @@ -328,10 +347,10 @@ export class Ecosystem<Context extends Record<string, any> | undefined = any>
}

/**
* Get an object of all atom instances in this ecosystem.
* Get an object of all atom instances in this ecosystem keyed by their id.
*
* Pass an atom template or atom template key string to only return instances
* whose id weakly matches the passed key.
* Pass an atom template to only find instances of that atom. Pass an atom key
* string to only return instances whose id weakly matches the passed key.
*/
public findAll(template?: AnyAtomTemplate | string) {
const isAtom = (template as AnyAtomTemplate)?.key
Expand Down
19 changes: 19 additions & 0 deletions packages/react/test/units/Ecosystem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ describe('Ecosystem', () => {
)
})

test('find() with params only returns exact matches', () => {
const atom1 = atom('1', (id?: string) => id)
const atom2 = atom('someLongKey1', 1)
const atom3 = atom('someLongKey11', 1)
const atom4 = atom('someLongKey111', 1)

ecosystem.getInstance(atom1, ['a'])
ecosystem.getInstance(atom1)
ecosystem.getInstance(atom1, ['b'])
ecosystem.getInstance(atom2)
ecosystem.getInstance(atom3)
ecosystem.getInstance(atom4)

expect(ecosystem.find('someLongKey', [])).toBeUndefined()
expect(ecosystem.find(atom1, ['b'])?.getState()).toBe('b')
expect(ecosystem.find(atom1, ['c'])).toBeUndefined()
expect(ecosystem.find(atom3, [])?.getState()).toBe(1)
})

test('findAll() with no params returns all atom instances', () => {
const atom1 = atom('1', (id: number) => id)

Expand Down

0 comments on commit 20e2319

Please sign in to comment.