UNPKG

@nori-zk/mina-token-bridge

Version:

A Mina zk-program contract allowing users to mint tokens on Nori Bridge.

249 lines 12.1 kB
var _WorkerParentBase_instances, _WorkerParentBase_child, _WorkerParentBase_pendingRequests, _WorkerParentBase_requestId, _WorkerParentBase_onMessage, _WorkerParentBase_onError, _WorkerChildBase_instances, _WorkerChildBase_pendingRequests, _WorkerChildBase_parent, _WorkerChildBase_onMessage, _WorkerChildBase_sendResponse, _WorkerChildBase_sendError, _WorkerChildBase_onError; import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; /** * A deferred promise pattern with externally accessible resolve and reject. */ export class DeferredPromise { constructor() { this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; }); } } /** * Parent-side base handler for managing requests sent to the child. */ export class WorkerParentBase { /** * Constructs the WorkerParentBase and attaches communication handlers. * @param child - The child endpoint to communicate with. */ constructor(child) { _WorkerParentBase_instances.add(this); _WorkerParentBase_child.set(this, void 0); _WorkerParentBase_pendingRequests.set(this, new Map()); _WorkerParentBase_requestId.set(this, 0); __classPrivateFieldSet(this, _WorkerParentBase_child, child, "f"); __classPrivateFieldGet(this, _WorkerParentBase_child, "f").onMessageHandler(__classPrivateFieldGet(this, _WorkerParentBase_instances, "m", _WorkerParentBase_onMessage).bind(this)); __classPrivateFieldGet(this, _WorkerParentBase_child, "f").onErrorHandler(__classPrivateFieldGet(this, _WorkerParentBase_instances, "m", _WorkerParentBase_onError).bind(this)); } /** * Sends a request to the child with a method name and arguments, and returns a promise for the response. * * @param methodName - The name of the method to invoke on the child. * @param args - Arguments to pass to the child method. * @returns A promise that resolves with the result of the child method call. */ async call(methodName, ...args) { var _a; // Await child readyness await __classPrivateFieldGet(this, _WorkerParentBase_child, "f").ready(); // Generate a unique ID for this request const id = __classPrivateFieldSet(this, _WorkerParentBase_requestId, (_a = __classPrivateFieldGet(this, _WorkerParentBase_requestId, "f"), ++_a), "f"); // Construct the message to send to the child const message = { id, methodName, args }; // Serialise the message into a JSON string const messageStr = JSON.stringify(message); // Create a deferred promise to be resolved/rejected upon response const deferred = new DeferredPromise(); // Track the pending request using its ID __classPrivateFieldGet(this, _WorkerParentBase_pendingRequests, "f").set(id, deferred); // Send the serialized message to the child await __classPrivateFieldGet(this, _WorkerParentBase_child, "f").call(messageStr); // Return the promise to the caller return deferred.promise; } /** * Terminates the child endpoint. */ terminate() { __classPrivateFieldGet(this, _WorkerParentBase_child, "f").terminate(); } } _WorkerParentBase_child = new WeakMap(), _WorkerParentBase_pendingRequests = new WeakMap(), _WorkerParentBase_requestId = new WeakMap(), _WorkerParentBase_instances = new WeakSet(), _WorkerParentBase_onMessage = function _WorkerParentBase_onMessage(messageStr) { // Attempt to parse the JSON response string let response; try { response = JSON.parse(messageStr); } catch { // If message is not valid JSON, silently ignore it return; } // Extract relevant data from the parsed message const { id, data, error } = response; // Retrieve the pending promise associated with the message ID const deferred = __classPrivateFieldGet(this, _WorkerParentBase_pendingRequests, "f").get(id); if (!deferred) return; // Reject the promise if there was an error in the response if (error) deferred.reject(new Error(error)); // Otherwise, resolve the promise with the response data else deferred.resolve(data); // Clean up by removing the resolved/rejected promise from the map __classPrivateFieldGet(this, _WorkerParentBase_pendingRequests, "f").delete(id); }, _WorkerParentBase_onError = function _WorkerParentBase_onError(error) { __classPrivateFieldGet(this, _WorkerParentBase_pendingRequests, "f").forEach((deferred) => deferred.reject(error)); __classPrivateFieldGet(this, _WorkerParentBase_pendingRequests, "f").clear(); }; /** * Child-side base handler for responding to messages from the parent. */ export class WorkerChildBase { /** * Constructs the WorkerChildBase and attaches communication handlers. * @param parent - The parent endpoint to respond to. */ constructor(parent) { _WorkerChildBase_instances.add(this); _WorkerChildBase_pendingRequests.set(this, new Map()); _WorkerChildBase_parent.set(this, void 0); __classPrivateFieldSet(this, _WorkerChildBase_parent, parent, "f"); __classPrivateFieldGet(this, _WorkerChildBase_parent, "f").onMessageHandler(__classPrivateFieldGet(this, _WorkerChildBase_instances, "m", _WorkerChildBase_onMessage).bind(this)); __classPrivateFieldGet(this, _WorkerChildBase_parent, "f").onErrorHandler(__classPrivateFieldGet(this, _WorkerChildBase_instances, "m", _WorkerChildBase_onError).bind(this)); } } _WorkerChildBase_pendingRequests = new WeakMap(), _WorkerChildBase_parent = new WeakMap(), _WorkerChildBase_instances = new WeakSet(), _WorkerChildBase_onMessage = /** * Handles a message received from the parent. * @param messageStr - JSON string message. */ async function _WorkerChildBase_onMessage(messageStr) { let message; // Parse the message or return if invalid. try { message = JSON.parse(messageStr); } catch { return; } // Handle a response to a previous call if (__classPrivateFieldGet(this, _WorkerChildBase_pendingRequests, "f").has(message.id)) { const deferred = __classPrivateFieldGet(this, _WorkerChildBase_pendingRequests, "f").get(message.id); if (message.error) deferred.reject(new Error(message.error)); else deferred.resolve(message.data); __classPrivateFieldGet(this, _WorkerChildBase_pendingRequests, "f").delete(message.id); return; } const { id, methodName, args = [] } = message; // Reject if the method doesn't exist if (typeof this[methodName] !== 'function') { __classPrivateFieldGet(this, _WorkerChildBase_instances, "m", _WorkerChildBase_sendError).call(this, id, methodName, `Method '${methodName}' not found`); return; } try { // Call the method and send back the result const result = await this[methodName](...args); __classPrivateFieldGet(this, _WorkerChildBase_instances, "m", _WorkerChildBase_sendResponse).call(this, id, methodName, result); } catch (error) { console.error(error); __classPrivateFieldGet(this, _WorkerChildBase_instances, "m", _WorkerChildBase_sendError).call(this, id, methodName, error?.message ?? String(error)); } }, _WorkerChildBase_sendResponse = function _WorkerChildBase_sendResponse(id, methodName, data) { const response = { id, methodName, data }; __classPrivateFieldGet(this, _WorkerChildBase_parent, "f").send(JSON.stringify(response)); }, _WorkerChildBase_sendError = function _WorkerChildBase_sendError(id, methodName, error) { const response = { id, methodName, error }; __classPrivateFieldGet(this, _WorkerChildBase_parent, "f").send(JSON.stringify(response)); }, _WorkerChildBase_onError = function _WorkerChildBase_onError(error) { __classPrivateFieldGet(this, _WorkerChildBase_pendingRequests, "f").forEach((deferred) => deferred.reject(error)); __classPrivateFieldGet(this, _WorkerChildBase_pendingRequests, "f").clear(); }; /** * Binds worker logic implementation to a communication channel as a child. * * @param parent - The parent communication endpoint * @param ChildClass - The class defining worker logic * @param args - Arguments passed to the worker logic constructor * @returns An object with a terminate method */ export function createWorker(parent, ChildClass, ...args) { // Instantiate the actual worker logic const workerLogic = new ChildClass(...args); // Create the child base to handle communication const childBase = new WorkerChildBase(parent); // Get all methods from the worker logic const proto = Object.getPrototypeOf(workerLogic); // Bind all methods to the child base for handling incoming requests for (const key of Object.getOwnPropertyNames(proto)) { if (key === 'constructor') continue; if (typeof proto[key] !== 'function') continue; // Bind the actual method to the child base childBase[key] = (...args) => workerLogic[key](...args); } // Return terminate return { terminate: () => parent.terminate() }; } /** * Creates a proxy for the parent to invoke child logic via async calls. * * @param child - The child endpoint * @param ChildClass - The class defining the child’s logic * @param args - Arguments passed to the logic class constructor * @returns A proxy object with async methods and a terminate method */ export function createProxy(child, ChildClass, ...args) { // Create parent base to handle communication const parentBase = new WorkerParentBase(child); // Get method names from the target class const temp = new ChildClass(...args); const proto = Object.getPrototypeOf(temp); // Create a proxy const proxyInstance = {}; for (const key of Object.getOwnPropertyNames(proto)) { if (key === 'constructor') continue; if (typeof proto[key] !== 'function') continue; // For each method of the child, emit a message which calls the worker. proxyInstance[key] = (...args) => parentBase.call(key, ...args); } // Extend the proxy with terminate. proxyInstance.terminate = () => parentBase.terminate(); // Return the proxy return proxyInstance; } /** * Creates a proxy for the parent to invoke child logic via async calls, * using a predefined method specification instead of inferring methods * from a class prototype. * * @param child - The child endpoint * @param methodSpec - An object whose keys are method names and values are functions * describing the expected parameters/return type for each call * @returns A proxy object with async methods matching the provided specification * and a terminate method for stopping the worker. * * @remarks * - This is useful when the child logic is not represented by a single class * or when you want to strictly control which methods are exposed to the parent. * - It also avoids the need to construct a class instance in the parent context, * which can be valuable if that constructor has heavy setup logic or depends on * modules with top-level async/await that would otherwise block initialization. * - All generated methods return Promises, since worker communication is asynchronous. */ export function createProxyFromSpec(child, methodSpec) { // Create parent base to handle communication const parentBase = new WorkerParentBase(child); // Build a typed proxy const proxy = {}; for (const key of Object.keys(methodSpec)) { // Always wrap in async to ensure Promise return type proxy[key] = (async (...args) => { return parentBase.call(key, ...args); }); } // Extend the proxy with terminate method to cleanly stop the worker proxy.terminate = () => parentBase.terminate(); // Return the fully typed proxy instance return proxy; } //# sourceMappingURL=index.js.map