UNPKG

stagehand

Version:

A type-safe library for communicating between JS processes, workers, or other message-passing boundaries.

71 lines (70 loc) 2.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class Serializer { constructor() { this.nextFunctionHandle = 0; this.handlesByFunction = new Map(); this.functionsByHandle = new Map(); } dehydrate(root) { return walk(root, obj => { if (typeof obj === 'function') { return functionHandle(this.handleIdFor(obj)); } }); } rehydrate(root, options) { return walk(root, obj => { if (isFunctionHandle(obj)) { return (...params) => options.hydrateFunction(obj, params); } }); } lookupFunction(handle) { return this.functionsByHandle.get(handle[HANDLE_ID]); } releaseFunction(f) { let handle = this.handlesByFunction.get(f); if (handle !== undefined) { this.functionsByHandle.delete(handle); } this.handlesByFunction.delete(f); } handleIdFor(f) { let handle = this.handlesByFunction.get(f); if (handle === undefined) { handle = this.nextFunctionHandle++; this.handlesByFunction.set(f, handle); this.functionsByHandle.set(handle, f); } return handle; } } exports.default = Serializer; const HANDLE_ID = '--stagehand-function-handle'; function functionHandle(id) { return { [HANDLE_ID]: id }; } function isFunctionHandle(obj) { return obj && typeof obj === 'object' && typeof obj[HANDLE_ID] === 'number'; } function walk(obj, handler) { let result = handler(obj); if (result !== undefined) { return result; } if (Array.isArray(obj)) { return obj.map(el => walk(el, handler)); } if (typeof obj === 'object' && obj) { if (Object.getPrototypeOf(obj) !== Object.prototype) { throw new Error('Unable to serialize non-POJO object'); } let result = {}; for (let key of Object.keys(obj)) { result[key] = walk(obj[key], handler); } return result; } return obj; }