Skip to content

Commit

Permalink
fix: stop namespaced datastore throwing when queried
Browse files Browse the repository at this point in the history
  • Loading branch information
saul-jb committed Jan 25, 2024
1 parent 2401e95 commit ca09950
Showing 1 changed file with 78 additions and 2 deletions.
80 changes: 78 additions & 2 deletions packages/datastore-core/src/namespace.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Key } from 'interface-datastore'
import { Key, type Datastore, type Query, type Pair, type KeyQuery } from 'interface-datastore'
import map from 'it-map'
import { KeyTransformDatastore } from './keytransform.js'
import type { Datastore } from 'interface-datastore'
import type { AbortOptions } from 'interface-store'

/**
* Wraps a given datastore into a keytransform which
Expand All @@ -11,6 +12,9 @@ import type { Datastore } from 'interface-datastore'
* `/hello/world`.
*/
export class NamespaceDatastore extends KeyTransformDatastore {
private readonly iChild: Datastore
private readonly iKey: Key

constructor (child: Datastore, prefix: Key) {
super(child, {
convert (key) {
Expand All @@ -28,5 +32,77 @@ export class NamespaceDatastore extends KeyTransformDatastore {
return new Key(key.toString().slice(prefix.toString().length), false)
}
})

this.iChild = child
this.iKey = prefix
}

query (q: Query, options?: AbortOptions): AsyncIterable<Pair> {
const query: Query = {
...q
}

query.filters = (query.filters ?? []).map(filter => {
return ({ key, value }) => filter({ key: this.transform.convert(key), value })
})

const { prefix } = q
if (prefix != null && prefix !== '/') {
delete query.prefix
query.filters.push(({ key }) => {
return this.transform.invert(key).toString().startsWith(prefix)
})
}

if (query.orders != null) {
query.orders = query.orders.map(order => {
return (a, b) => order(
{ key: this.transform.invert(a.key), value: a.value },
{ key: this.transform.invert(b.key), value: b.value }
)
})
}

query.filters.unshift(({ key }) => this.iKey.isAncestorOf(key))

return map(this.iChild.query(query, options), ({ key, value }) => {
return {
key: this.transform.invert(key),
value
}
})
}

queryKeys (q: KeyQuery, options?: AbortOptions): AsyncIterable<Key> {
const query = {
...q
}

query.filters = (query.filters ?? []).map(filter => {
return (key) => filter(this.transform.convert(key))
})

const { prefix } = q
if (prefix != null && prefix !== '/') {
delete query.prefix
query.filters.push((key) => {
return this.transform.invert(key).toString().startsWith(prefix)
})
}

if (query.orders != null) {
query.orders = query.orders.map(order => {
return (a, b) => order(
this.transform.invert(a),
this.transform.invert(b)
)
})
}

query.filters.unshift(key => this.iKey.isAncestorOf(key))

return map(this.iChild.queryKeys(query, options), key => {
return this.transform.invert(key)
})
}
}

0 comments on commit ca09950

Please sign in to comment.