fix(core): Refactor and clean up class imports and exports
This commit is contained in:
135
ts/classes.asyncstore.ts
Normal file
135
ts/classes.asyncstore.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import * as plugins from './plugins.js';
|
||||
|
||||
export class AsyncStore {
|
||||
private static idCounter = 0;
|
||||
private id: number;
|
||||
private parentStore?: AsyncStore;
|
||||
private deletedKeys: string[] = [];
|
||||
private dataObject: { [key: string]: any } = {};
|
||||
|
||||
constructor(parentStore?: AsyncStore) {
|
||||
this.parentStore = parentStore;
|
||||
this.id = AsyncStore.idCounter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs debug info if process.env.DEBUG is set.
|
||||
*/
|
||||
private logDebug(functionName: string, before: Record<string, any>, after: Record<string, any>) {
|
||||
if (typeof process !== 'undefined' && process.env && process.env.DEBUG) {
|
||||
console.log(`Store ID: ${this.id}`);
|
||||
console.log(`Function: ${functionName}`);
|
||||
console.log('--- Before ---');
|
||||
console.log(before);
|
||||
console.log('--- After ---');
|
||||
console.log(after);
|
||||
console.log('-----------------------');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the deleted keys if they no longer exist in any parent store.
|
||||
*/
|
||||
private cleanUp() {
|
||||
for (const key of this.deletedKeys) {
|
||||
if (this.parentStore && this.parentStore.get(key)) {
|
||||
// Parent still has it, so keep in deletedKeys
|
||||
} else {
|
||||
const index = this.deletedKeys.indexOf(key);
|
||||
if (index !== -1) {
|
||||
this.deletedKeys.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or updates a value under a specific key in this store.
|
||||
*/
|
||||
public add(keyArg: string, objectArg: any) {
|
||||
// capture the before state
|
||||
const before = { ...this.dataObject, deletedKeys: [...this.deletedKeys] };
|
||||
|
||||
this.cleanUp();
|
||||
// If this key was previously deleted, remove it from deletedKeys.
|
||||
if (this.deletedKeys.includes(keyArg)) {
|
||||
this.deletedKeys = this.deletedKeys.filter((key) => key !== keyArg);
|
||||
}
|
||||
this.dataObject[keyArg] = objectArg;
|
||||
|
||||
// capture the after state
|
||||
const after = { ...this.dataObject, deletedKeys: [...this.deletedKeys] };
|
||||
this.logDebug('add', before, after);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a key from the current store.
|
||||
* If a parent store has the key, we record it in `deletedKeys` so the child store "shadows" it.
|
||||
*/
|
||||
public delete(paramName: string) {
|
||||
// capture the before state
|
||||
const before = { ...this.dataObject, deletedKeys: [...this.deletedKeys] };
|
||||
|
||||
this.cleanUp();
|
||||
if (this.parentStore?.get(paramName)) {
|
||||
// The parent store has this key; let's mark it as deleted in the child
|
||||
this.deletedKeys.push(paramName);
|
||||
}
|
||||
delete this.dataObject[paramName];
|
||||
|
||||
// capture the after state
|
||||
const after = { ...this.dataObject, deletedKeys: [...this.deletedKeys] };
|
||||
this.logDebug('delete', before, after);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a key, checking this store first, then the parent store if necessary.
|
||||
* Will log the store state before/after for debugging.
|
||||
*/
|
||||
public get(paramName: string) {
|
||||
// capture the before state
|
||||
const before = { ...this.dataObject, deletedKeys: [...this.deletedKeys] };
|
||||
|
||||
this.cleanUp();
|
||||
// figure out if paramName is deleted or present
|
||||
let result: any;
|
||||
if (this.deletedKeys.includes(paramName)) {
|
||||
result = undefined;
|
||||
} else {
|
||||
result = this.dataObject[paramName] ?? this.parentStore?.get(paramName);
|
||||
}
|
||||
|
||||
// capture the after state; we can also show the `result` in the log
|
||||
const after = {
|
||||
...this.dataObject,
|
||||
deletedKeys: [...this.deletedKeys],
|
||||
retrievedKey: paramName,
|
||||
result
|
||||
};
|
||||
this.logDebug('get', before, after);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all keys and values, merged with the parent store, but
|
||||
* does NOT include keys that are "deleted" in the child.
|
||||
* Child store should override parent if the same key exists in both.
|
||||
*/
|
||||
public getAll() {
|
||||
this.cleanUp();
|
||||
// first, get parent's data as a shallow copy
|
||||
const parentData = { ...(this.parentStore?.getAll() || {}) };
|
||||
|
||||
// remove keys from parent data that this child has deleted
|
||||
for (const key of this.deletedKeys) {
|
||||
delete parentData[key];
|
||||
}
|
||||
|
||||
// child's data overrides parent data for any matching keys
|
||||
return {
|
||||
...parentData,
|
||||
...this.dataObject
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user