50 lines
1.4 KiB
JavaScript
50 lines
1.4 KiB
JavaScript
/**
|
|
* The goal of this file is to "allocate" references
|
|
* via `alloc(ref)` and return a "pointer" as unique id.
|
|
* The reference is held in memory until that "pointer"
|
|
* is passed to `dealloc(ptr)` hence freed.
|
|
*/
|
|
|
|
let i = 0;
|
|
|
|
const ids = new Map;
|
|
const values = new WeakMap;
|
|
|
|
/**
|
|
* Create once a unique identifier that can easily travel or be serialized.
|
|
* It traps the reference until that identifier is passed to `dealloc` helper.
|
|
* @param {object | function} value a reference to relate via a unique identifier
|
|
* @returns {number} the unique identifier for the reference
|
|
*/
|
|
export const alloc = value => {
|
|
let id = values.get(value);
|
|
if (id == null) {
|
|
/* c8 ignore next */
|
|
while (ids.has(id = i++));
|
|
ids.set(id, value);
|
|
values.set(value, id);
|
|
}
|
|
return id;
|
|
};
|
|
|
|
/**
|
|
* Free any previously stored reference associated to the unique identifier.
|
|
* @param {number} id the unique identifier previously used to allocate memory
|
|
* @returns {boolean} `true` if the identifier was known and successfully freed
|
|
*/
|
|
export const dealloc = id => {
|
|
const value = ref(id);
|
|
if (value) {
|
|
ids.delete(id);
|
|
values.delete(value);
|
|
}
|
|
return !!value;
|
|
};
|
|
|
|
/**
|
|
* Return any previously stored reference associated to the unique identifier.
|
|
* @param {number} id the unique identifier previously used to allocate memory
|
|
* @returns {object | function | null} the identifier related reference, if any
|
|
*/
|
|
export const ref = id => ids.get(id);
|