@ndn/util
Version:
NDNts: general utilities
80 lines (79 loc) • 2.4 kB
JavaScript
import { __importDefault, __importStar } from "tslib";
import _cjsDefaultImport0 from "event-iterator"; const EventIterator = __importDefault(_cjsDefaultImport0).default;
import assert from "tiny-invariant";
/**
* Create an iterable that you can push values into.
* @typeParam T - Value type.
* @returns AsyncIterable with push method.
*
* @remarks
* Inspired by {@link https://www.npmjs.com/package/it-pushable | it-pushable} but implemented on
* top of {@link https://www.npmjs.com/package/event-iterator | event-iterator} library.
*/
export function pushable() {
let q;
const ei = new EventIterator((queue) => { q = queue; }, { highWaterMark: Infinity });
const it = ei[Symbol.asyncIterator]();
assert(!!q);
return {
[Symbol.asyncIterator]: () => it,
push: q.push,
stop: q.stop,
fail: q.fail,
};
}
/**
* Yield all values from an iterable but catch any error.
* @param iterable - Input iterable.
* @param onError - Callback to receive errors thrown by the iterable.
* @returns Iterable that does not throw errors.
*/
export async function* safeIter(iterable, onError) {
try {
yield* iterable;
}
catch (err) {
onError?.(err);
}
}
/**
* Perform flatMap on an (async) iterable, but flatten at most once.
* @remarks
* flatMap of streaming-iterables recursively flattens the result.
* This function flattens at most once.
*/
export async function* flatMapOnce(f, iterable) {
for await (const item of iterable) {
yield* f(item);
}
}
/**
* Retrieve or insert value in a Map-like container.
* @param ct - Map-like container.
* @param key - Map key.
* @param make - Function to create the value if needed.
* @returns Existing or newly created value.
*/
export function getOrInsert(ct, key, make) {
let value = ct.get(key);
if (value === undefined) {
ct.set(key, value = make());
}
return value;
}
/**
* Delete keys from a Set or Map until its size is below capacity.
* @param capacity - Maximum size after eviction.
* @param ct - Container.
* @param deleteCallback - Callback before item is deleted.
*/
export function evict(capacity, ct, deleteCallback) {
assert(capacity >= 0);
for (const key of ct.keys()) {
if (ct.size <= capacity) {
break;
}
deleteCallback?.(key);
ct.delete(key);
}
}