@nori-zk/mina-token-bridge
Version:
A Mina zk-program contract allowing users to mint tokens on Nori Bridge.
249 lines • 12.1 kB
JavaScript
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