You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.5 KiB
54 lines
1.5 KiB
import { STORAGE_OP_READ } from './consts';
|
|
import { StorageEntryDefaultsMismatchError } from './errors';
|
|
import type { StorageErrorContext } from './types';
|
|
|
|
export interface RegisterStorageDefaultInput {
|
|
readonly registryKey: string;
|
|
readonly key: string;
|
|
readonly fullKey: string;
|
|
readonly initialDefault: unknown;
|
|
readonly adapterName: string;
|
|
report(ctx: Omit<StorageErrorContext, 'adapter'>, adapterName: string): void;
|
|
}
|
|
|
|
export interface StorageDefaultsRegistry {
|
|
register(input: RegisterStorageDefaultInput): () => void;
|
|
}
|
|
|
|
export function createStorageDefaultsRegistry(): StorageDefaultsRegistry {
|
|
const defaults = new Map<string, { value: unknown; refs: number }>();
|
|
|
|
function register(input: RegisterStorageDefaultInput): () => void {
|
|
const previous = defaults.get(input.registryKey);
|
|
if (previous !== undefined) {
|
|
try {
|
|
if (JSON.stringify(previous.value) !== JSON.stringify(input.initialDefault)) {
|
|
input.report(
|
|
{
|
|
key: input.key,
|
|
fullKey: input.fullKey,
|
|
op: STORAGE_OP_READ,
|
|
error: new StorageEntryDefaultsMismatchError(input.key)
|
|
},
|
|
input.adapterName
|
|
);
|
|
}
|
|
} catch {
|
|
/* circular default — skip the diagnostic */
|
|
}
|
|
previous.refs += 1;
|
|
} else {
|
|
defaults.set(input.registryKey, { value: input.initialDefault, refs: 1 });
|
|
}
|
|
|
|
return () => {
|
|
const slot = defaults.get(input.registryKey);
|
|
if (slot === undefined) return;
|
|
slot.refs -= 1;
|
|
if (slot.refs <= 0) defaults.delete(input.registryKey);
|
|
};
|
|
}
|
|
|
|
return { register };
|
|
}
|