/** | |
* 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); | |