Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 1x 1x 1x 48x 48x 48x 50x 50x 48x 2x 2x 48x 48x 40x 40x 48x 48x 39x 39x 48x 17x 17x 17x 48x 12x 12x 12x 48x 5x 5x 5x 48x 1x 1x 1x 48x 4x 4x 4x 4x 4x 48x 35x 35x 48x 43x 43x 48x | import { anchor } from '@anchorlib/core';
import { isObject } from '@beerush/utils';
import type { StorageEvent, StorageSubscriber } from './types.js';
/**
* A memory-based storage implementation that provides a key-value store with subscription capabilities.
*
* @template T - The type of the storage object, defaults to Record<string, unknown>
*/
export class MemoryStorage<T extends Record<string, unknown> = Record<string, unknown>> {
readonly #storage: T = {} as T;
readonly #subscribers: Set<StorageSubscriber> = new Set();
/**
* Gets the number of items in the storage.
* @returns The number of stored items
*/
public get length() {
return Object.keys(this.#storage).length;
}
/**
* Gets all the keys in the storage.
* @returns An array of all storage keys
*/
public get keys() {
return Object.keys(this.#storage) as (keyof T)[];
}
/**
* Creates a new MemoryStorage instance.
* @param init - Optional initial data to populate the storage
*/
constructor(init?: T) {
if (isObject(init)) {
this.#storage = init;
}
}
/**
* Gets a value from storage by key.
* @param key - The key to retrieve
* @returns The stored value or undefined if not found
*/
public get(key: keyof T): T[keyof T] | undefined {
return this.#storage[key] as T[keyof T] | undefined;
}
/**
* Sets a value in storage by key.
* @param key - The key to set
* @param value - The value to store
*/
public set(key: keyof T, value: T[keyof T]) {
this.#storage[key] = value;
this.publish({ type: 'set', name: key, value });
}
/**
* Deletes a value from storage by key.
* @param key - The key to delete
*/
public delete(key: keyof T) {
delete this.#storage[key];
this.publish({ type: 'delete', name: key });
}
/**
* Assigns multiple values to the storage.
* @param data - The data to merge into storage
*/
public assign(data: Record<string, unknown>) {
Object.assign(this.#storage, data);
this.publish({ type: 'assign', name: '', value: data });
}
/**
* Clears all values from the storage.
*/
public clear() {
anchor.clear(this.#storage);
this.publish({ type: 'clear', name: '' });
}
/**
* Subscribes to storage events.
* @param callback - The function to call when storage events occur
* @returns A function to unsubscribe from events
*/
public subscribe(callback: StorageSubscriber) {
this.#subscribers.add(callback);
return () => {
this.#subscribers.delete(callback);
};
}
/**
* Publishes a storage event to all subscribers.
* @param event - The event to publish
*/
public publish(event: StorageEvent) {
this.#subscribers.forEach((callback) => callback(event));
}
/**
* Converts the storage to a JSON string.
* @param space - Adds indentation, white space, and line break characters to the return-value JSON text
* @param replacer - A function that alters the behavior of the stringification process
* @returns A JSON string representation of the storage
*/
public json(space?: string | number, replacer?: (key: string, value: unknown) => unknown) {
return JSON.stringify(this.#storage, replacer, space);
}
}
|