@furystack/core
Version:
Core FuryStack package
85 lines • 3.13 kB
JavaScript
import { EventHub } from '@furystack/utils';
import { NotFoundError } from './errors/not-found-error.js';
import { filterItems } from './filter-items.js';
import { selectFields } from './models/physical-store.js';
/**
* In-memory {@link PhysicalStore} backed by a `Map`. Intended for tests, dev
* fixtures and small reference datasets — entries are lost on process exit.
* Production deployments should bind a real adapter (filesystem, MongoDB,
* Sequelize, Redis) via `defineXxxStore`.
*/
export class InMemoryStore extends EventHub {
async remove(...keys) {
keys.forEach((key) => {
this.cache.delete(key);
this.emit('onEntityRemoved', { key });
});
}
async add(...entries) {
const created = entries.map((e) => {
const entry = { ...e };
if (this.cache.has(entry[this.primaryKey])) {
throw new Error('Item with the primary key already exists.');
}
this.cache.set(entry[this.primaryKey], entry);
this.emit('onEntityAdded', { entity: entry });
return entry;
});
return { created };
}
cache = new Map();
get = (key, select) => {
const item = this.cache.get(key);
return Promise.resolve(item && select ? selectFields(item, ...select) : item);
};
async find(searchOptions) {
let value = filterItems([...this.cache.values()], searchOptions.filter);
if (searchOptions.order) {
const orderRecord = searchOptions.order;
for (const fieldName of Object.keys(searchOptions.order)) {
value = value.sort((a, b) => {
const order = orderRecord[fieldName];
if (a[fieldName] < b[fieldName])
return order === 'ASC' ? -1 : 1;
if (a[fieldName] > b[fieldName])
return order === 'ASC' ? 1 : -1;
return 0;
});
}
}
if (searchOptions.top || searchOptions.skip) {
value = value.slice(searchOptions.skip, (searchOptions.skip || 0) + (searchOptions.top || this.cache.size));
}
if (searchOptions.select) {
value = value.map((item) => {
return selectFields(item, ...searchOptions.select);
});
}
return value;
}
async count(filter) {
return filterItems([...this.cache.values()], filter).length;
}
async update(id, data) {
if (!this.cache.has(id)) {
throw new NotFoundError(`Entity not found with id '${id}', cannot update`);
}
this.cache.set(id, {
...this.cache.get(id),
...data,
});
this.emit('onEntityUpdated', { id, change: data });
}
[Symbol.dispose]() {
this.cache.clear();
super[Symbol.dispose]();
}
primaryKey;
model;
constructor(options) {
super();
this.primaryKey = options.primaryKey;
this.model = options.model;
}
}
//# sourceMappingURL=in-memory-store.js.map