Skip to content

Commit

Permalink
feat: add branded key to CommonKeyValueDao (#19)
Browse files Browse the repository at this point in the history
* chore: add branded key to CommonKeyValueDao

* chore: rename generics
  • Loading branch information
mrnagydavid authored Oct 11, 2024
1 parent e38afa7 commit 773638b
Showing 1 changed file with 28 additions and 30 deletions.
58 changes: 28 additions & 30 deletions src/kv/commonKeyValueDao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ export type CommonKeyValueDaoSaveOptions = CommonKeyValueDBSaveBatchOptions
// todo: logging
// todo: readonly

export class CommonKeyValueDao<T> {
constructor(cfg: CommonKeyValueDaoCfg<T>) {
export class CommonKeyValueDao<V, K extends string = string> {
constructor(cfg: CommonKeyValueDaoCfg<V>) {
this.cfg = {
hooks: {},
logger: console,
Expand All @@ -70,8 +70,8 @@ export class CommonKeyValueDao<T> {
}
}

cfg: CommonKeyValueDaoCfg<T> & {
hooks: NonNullable<CommonKeyValueDaoCfg<T>['hooks']>
cfg: CommonKeyValueDaoCfg<V> & {
hooks: NonNullable<CommonKeyValueDaoCfg<V>['hooks']>
logger: CommonLogger
}

Expand All @@ -83,25 +83,25 @@ export class CommonKeyValueDao<T> {
await this.cfg.db.createTable(this.cfg.table, opt)
}

create(input: Partial<T> = {}): T {
create(input: Partial<V> = {}): V {
return {
...this.cfg.hooks.beforeCreate?.(input),
} as T
} as V
}

async getById(id?: string): Promise<T | null> {
async getById(id?: K): Promise<V | null> {
if (!id) return null
const [r] = await this.getByIds([id])
return r?.[1] || null
}

async getByIdAsBuffer(id?: string): Promise<Buffer | null> {
async getByIdAsBuffer(id?: K): Promise<Buffer | null> {
if (!id) return null
const [r] = await this.cfg.db.getByIds(this.cfg.table, [id])
return r?.[1] || null
}

async requireById(id: string): Promise<T> {
async requireById(id: K): Promise<V> {
const [r] = await this.getByIds([id])

if (!r) {
Expand All @@ -115,7 +115,7 @@ export class CommonKeyValueDao<T> {
return r[1]
}

async requireByIdAsBuffer(id: string): Promise<Buffer> {
async requireByIdAsBuffer(id: K): Promise<Buffer> {
const [r] = await this.cfg.db.getByIds(this.cfg.table, [id])

if (!r) {
Expand All @@ -129,18 +129,18 @@ export class CommonKeyValueDao<T> {
return r[1]
}

async getByIdOrEmpty(id: string, part: Partial<T> = {}): Promise<T> {
async getByIdOrEmpty(id: K, part: Partial<V> = {}): Promise<V> {
const [r] = await this.getByIds([id])
if (r) return r[1]

return {
...this.cfg.hooks.beforeCreate?.({}),
...part,
} as T
} as V
}

async patch(id: string, patch: Partial<T>, opt?: CommonKeyValueDaoSaveOptions): Promise<T> {
const v: T = {
async patch(id: K, patch: Partial<V>, opt?: CommonKeyValueDaoSaveOptions): Promise<V> {
const v: V = {
...(await this.getByIdOrEmpty(id)),
...patch,
}
Expand All @@ -150,7 +150,7 @@ export class CommonKeyValueDao<T> {
return v
}

async getByIds(ids: string[]): Promise<KeyValueTuple<string, T>[]> {
async getByIds(ids: K[]): Promise<KeyValueTuple<string, V>[]> {
const entries = await this.cfg.db.getByIds(this.cfg.table, ids)
if (!this.cfg.hooks.mapBufferToValue) return entries as any

Expand All @@ -160,20 +160,20 @@ export class CommonKeyValueDao<T> {
])
}

async getByIdsAsBuffer(ids: string[]): Promise<KeyValueTuple<string, Buffer>[]> {
return await this.cfg.db.getByIds(this.cfg.table, ids)
async getByIdsAsBuffer(ids: K[]): Promise<KeyValueTuple<K, Buffer>[]> {
return (await this.cfg.db.getByIds(this.cfg.table, ids)) as KeyValueTuple<K, Buffer>[]
}

async save(id: string, value: T, opt?: CommonKeyValueDaoSaveOptions): Promise<void> {
async save(id: K, value: V, opt?: CommonKeyValueDaoSaveOptions): Promise<void> {
await this.saveBatch([[id, value]], opt)
}

async saveAsBuffer(id: string, value: Buffer, opt?: CommonKeyValueDaoSaveOptions): Promise<void> {
async saveAsBuffer(id: K, value: Buffer, opt?: CommonKeyValueDaoSaveOptions): Promise<void> {
await this.cfg.db.saveBatch(this.cfg.table, [[id, value]], opt)
}

async saveBatch(
entries: KeyValueTuple<string, T>[],
entries: KeyValueTuple<K, V>[],
opt?: CommonKeyValueDaoSaveOptions,
): Promise<void> {
const { mapValueToBuffer } = this.cfg.hooks
Expand All @@ -195,23 +195,23 @@ export class CommonKeyValueDao<T> {
await this.cfg.db.saveBatch(this.cfg.table, entries, opt)
}

async deleteByIds(ids: string[]): Promise<void> {
async deleteByIds(ids: K[]): Promise<void> {
await this.cfg.db.deleteByIds(this.cfg.table, ids)
}

async deleteById(id: string): Promise<void> {
async deleteById(id: K): Promise<void> {
await this.cfg.db.deleteByIds(this.cfg.table, [id])
}

streamIds(limit?: number): ReadableTyped<string> {
return this.cfg.db.streamIds(this.cfg.table, limit)
}

streamValues(limit?: number): ReadableTyped<T> {
streamValues(limit?: number): ReadableTyped<V> {
const { mapBufferToValue } = this.cfg.hooks

if (!mapBufferToValue) {
return this.cfg.db.streamValues(this.cfg.table, limit) as ReadableTyped<T>
return this.cfg.db.streamValues(this.cfg.table, limit) as ReadableTyped<V>
}

return this.cfg.db.streamValues(this.cfg.table, limit).flatMap(
Expand All @@ -229,19 +229,17 @@ export class CommonKeyValueDao<T> {
)
}

streamEntries(limit?: number): ReadableTyped<KeyValueTuple<string, T>> {
streamEntries(limit?: number): ReadableTyped<KeyValueTuple<K, V>> {
const { mapBufferToValue } = this.cfg.hooks

if (!mapBufferToValue) {
return this.cfg.db.streamEntries(this.cfg.table, limit) as ReadableTyped<
KeyValueTuple<string, T>
>
return this.cfg.db.streamEntries(this.cfg.table, limit) as ReadableTyped<KeyValueTuple<K, V>>
}

return this.cfg.db.streamEntries(this.cfg.table, limit).flatMap(
async ([id, buf]) => {
try {
return [[id, await mapBufferToValue(buf)]]
return [[id as K, await mapBufferToValue(buf)]]
} catch (err) {
this.cfg.logger.error(err)
return [] // SKIP
Expand All @@ -259,7 +257,7 @@ export class CommonKeyValueDao<T> {
*
* Returns the new value of the field.
*/
async increment(id: string, by = 1): Promise<number> {
async increment(id: K, by = 1): Promise<number> {
return await this.cfg.db.increment(this.cfg.table, id, by)
}
}

0 comments on commit 773638b

Please sign in to comment.