import { resolveValueProvider } from '../function/value-provider.js'; type Provider = T | (() => T); const createMap = () => new Map(); const createWeakMap = () => new WeakMap(); const createSet = () => new Set(); const createWeakSet = () => new WeakSet(); /** * Get a `TValue` from the `map`, and add it first if it doesn't already exist in the map. * @param map - The map containing values. * @param key - The key to use when retrieving a value. * @param valueProvider - The creator function or value to use when the key does not already exist in the map. * @param retrieveAction - An optional action to perform on the value when it already exists in the map. */ export const lazyMap = >( map: TMap, key: Parameters['0'], valueProvider: Provider, undefined>>, retrieveAction?: (value: Exclude, undefined>) => void, ): Exclude, undefined> => { if (map.has(key)) { const val = map.get(key)!; retrieveAction?.(val); return val; } const val = resolveValueProvider(valueProvider); map.set(key, val); return val; }; lazyMap.createMap = createMap; lazyMap.createWeakMap = createWeakMap; lazyMap.createSet = createSet; lazyMap.createWeakSet = createWeakSet; /** * Wrapper for mapGetLazy that accepts weak map. * * {@link lazyMap} */ export const lazyWeakmap = >( map: TMap, key: Parameters['0'], valueProvider: Provider, undefined>>, retrieveAction?: (value: Exclude, undefined>) => void, ): Exclude, undefined> => lazyMap( map as unknown as Map, key, valueProvider, retrieveAction, ); lazyWeakmap.createMap = createMap; lazyWeakmap.createWeakMap = createWeakMap; lazyWeakmap.createSet = createSet; lazyWeakmap.createWeakSet = createWeakSet;