channel-rpc
Advanced tools
Comparing version 0.0.1 to 0.0.2
export declare class ChannelServer<T extends object> { | ||
#private; | ||
readonly channelId: string; | ||
readonly source: WindowProxy; | ||
readonly channel: MessageChannel; | ||
private readonly _handlers; | ||
constructor(options: { | ||
@@ -8,2 +11,3 @@ channelId: string; | ||
}); | ||
private _handleMessage; | ||
} | ||
@@ -18,6 +22,8 @@ type Promisify<T> = T extends Promise<unknown> ? T : Promise<T>; | ||
export declare class ChannelClient<T extends object> { | ||
#private; | ||
readonly channelId: string; | ||
readonly stub: RemoteObject<T>; | ||
readonly target: WindowProxy; | ||
private readonly _deferreds; | ||
private readonly _deferredPort; | ||
private readonly _timeout; | ||
constructor(options: { | ||
@@ -28,3 +34,6 @@ target: WindowProxy; | ||
}); | ||
private _sendRequest; | ||
private _portMessageHandler; | ||
private _startHandshake; | ||
} | ||
export {}; |
@@ -1,13 +0,1 @@ | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _ChannelServer_instances, _ChannelServer_source, _ChannelServer_channelId, _ChannelServer_channel, _ChannelServer_handlers, _ChannelServer_handleMessage, _ChannelClient_instances, _ChannelClient_deferredPort, _ChannelClient_deferreds, _ChannelClient_timeout, _ChannelClient_sendRequest, _ChannelClient_portMessageHandler, _ChannelClient_startHandshake; | ||
const MessageTypes = { | ||
@@ -36,18 +24,19 @@ HandShakeRequest: "@channel-rpc/HANDSHAKE_REQUEST", | ||
reject: (_reason) => { }, | ||
promise: new Promise((resolve, reject) => { | ||
const t = timeout | ||
? setTimeout(() => { | ||
reject(new Error("timeout")); | ||
}, timeout) | ||
: undefined; | ||
deferred.resolve = (value) => { | ||
clearTimeout(t); | ||
return resolve(value); | ||
}; | ||
deferred.reject = (reason) => { | ||
clearTimeout(t); | ||
return reject(reason); | ||
}; | ||
}), | ||
promise: undefined, | ||
}; | ||
deferred.promise = new Promise((resolve, reject) => { | ||
const t = timeout | ||
? setTimeout(() => { | ||
reject(new Error("timeout")); | ||
}, timeout) | ||
: undefined; | ||
deferred.resolve = (value) => { | ||
clearTimeout(t); | ||
return resolve(value); | ||
}; | ||
deferred.reject = (reason) => { | ||
clearTimeout(t); | ||
return reject(reason); | ||
}; | ||
}); | ||
return deferred; | ||
@@ -57,11 +46,7 @@ } | ||
constructor(options) { | ||
_ChannelServer_instances.add(this); | ||
_ChannelServer_source.set(this, void 0); | ||
_ChannelServer_channelId.set(this, void 0); | ||
_ChannelServer_channel.set(this, void 0); | ||
_ChannelServer_handlers.set(this, new Map()); | ||
const { source, channelId, handler } = options; | ||
if (!channelId) | ||
throw new Error("id is required"); | ||
__classPrivateFieldSet(this, _ChannelServer_channelId, channelId, "f"); | ||
this.channelId = channelId; | ||
this._handlers = {}; | ||
const h = handler || {}; | ||
@@ -71,76 +56,83 @@ Object.keys(h).forEach((method) => { | ||
if (typeof fn === "function") { | ||
__classPrivateFieldGet(this, _ChannelServer_handlers, "f").set(method, fn.bind(h)); | ||
this._handlers[method] = fn.bind(h); | ||
} | ||
}); | ||
__classPrivateFieldSet(this, _ChannelServer_channel, new MessageChannel(), "f"); | ||
__classPrivateFieldSet(this, _ChannelServer_source, source || window, "f"); | ||
__classPrivateFieldGet(this, _ChannelServer_source, "f").addEventListener("message", (ev) => { | ||
this.channel = new MessageChannel(); | ||
this.source = source || window; | ||
this.source.addEventListener("message", (ev) => { | ||
// DEBUG | ||
if (ev.data.type === MessageTypes.HandShakeRequest) { | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest", ev.data); | ||
} | ||
// Send back the port to the source window | ||
if (ev.data && | ||
ev.data.type === MessageTypes.HandShakeRequest && | ||
ev.data.channelId === __classPrivateFieldGet(this, _ChannelServer_channelId, "f")) { | ||
ev.data.channelId === this.channelId) { | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest Sendback", this.channel.port2); | ||
ev.source.postMessage({ | ||
type: MessageTypes.HandShakeResponse, | ||
channelId: __classPrivateFieldGet(this, _ChannelServer_channelId, "f"), | ||
}, "*", [__classPrivateFieldGet(this, _ChannelServer_channel, "f").port2]); | ||
channelId: this.channelId, | ||
}, "*", [this.channel.port2]); | ||
} | ||
}); | ||
__classPrivateFieldGet(this, _ChannelServer_channel, "f").port1.onmessage = __classPrivateFieldGet(this, _ChannelServer_instances, "m", _ChannelServer_handleMessage); | ||
this.channel.port1.onmessage = this._handleMessage.bind(this); | ||
} | ||
async _handleMessage(ev) { | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest handleMessage", ev); | ||
const data = ev.data; | ||
if (!isJsonRpcRequest(data)) { | ||
const res = { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32600, | ||
message: "Invalid Request", | ||
}, | ||
id: data.id || null, | ||
}; | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
return; | ||
} | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest handleMessage method", data.method, this._handlers); | ||
const handler = this._handlers[data.method]; | ||
if (!handler) { | ||
const res = { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32601, | ||
message: "Method not found", | ||
}, | ||
id: data.id, | ||
}; | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
return; | ||
} | ||
try { | ||
const result = await handler(...(data.params || [])); | ||
const res = { | ||
jsonrpc: "2.0", | ||
result, | ||
id: data.id, | ||
}; | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
} | ||
catch (err) { | ||
const res = { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32603, | ||
message: "Internal error", | ||
data: err, | ||
}, | ||
id: data.id, | ||
}; | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
} | ||
} | ||
} | ||
_ChannelServer_source = new WeakMap(), _ChannelServer_channelId = new WeakMap(), _ChannelServer_channel = new WeakMap(), _ChannelServer_handlers = new WeakMap(), _ChannelServer_instances = new WeakSet(), _ChannelServer_handleMessage = async function _ChannelServer_handleMessage(ev) { | ||
const data = ev.data; | ||
if (!isJsonRpcRequest(data)) { | ||
const res = { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32600, | ||
message: "Invalid Request", | ||
}, | ||
id: data.id || null, | ||
}; | ||
__classPrivateFieldGet(this, _ChannelServer_channel, "f").port1.postMessage(res); | ||
return; | ||
} | ||
const handler = __classPrivateFieldGet(this, _ChannelServer_handlers, "f").get(data.method); | ||
if (!handler) { | ||
const res = { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32601, | ||
message: "Method not found", | ||
}, | ||
id: data.id, | ||
}; | ||
__classPrivateFieldGet(this, _ChannelServer_channel, "f").port1.postMessage(res); | ||
return; | ||
} | ||
try { | ||
const result = await handler(...(data.params || [])); | ||
const res = { | ||
jsonrpc: "2.0", | ||
result, | ||
id: data.id, | ||
}; | ||
__classPrivateFieldGet(this, _ChannelServer_channel, "f").port1.postMessage(res); | ||
} | ||
catch (err) { | ||
const res = { | ||
jsonrpc: "2.0", | ||
error: { | ||
code: -32603, | ||
message: "Internal error", | ||
data: err, | ||
}, | ||
id: data.id, | ||
}; | ||
__classPrivateFieldGet(this, _ChannelServer_channel, "f").port1.postMessage(res); | ||
} | ||
}; | ||
export class ChannelClient { | ||
constructor(options) { | ||
_ChannelClient_instances.add(this); | ||
_ChannelClient_deferredPort.set(this, void 0); | ||
_ChannelClient_deferreds.set(this, new Map()); | ||
_ChannelClient_timeout.set(this, void 0); | ||
const { target, channelId, timeout } = options; | ||
@@ -153,76 +145,86 @@ if (!target) | ||
this.channelId = channelId; | ||
__classPrivateFieldSet(this, _ChannelClient_deferredPort, defer(0), "f"); | ||
__classPrivateFieldSet(this, _ChannelClient_timeout, timeout || 1000, "f"); | ||
this._deferredPort = defer(0); | ||
this._deferreds = {}; | ||
this._timeout = timeout || 1000; | ||
this.stub = new Proxy({}, { | ||
get: (_target, prop) => { | ||
return async (...args) => { | ||
return __classPrivateFieldGet(this, _ChannelClient_instances, "m", _ChannelClient_sendRequest).call(this, String(prop), args); | ||
return (...args) => { | ||
console.log("[CHANNEL_RPC][CLIENT] invoke stub method", prop, args); | ||
return this._sendRequest(String(prop), args); | ||
}; | ||
}, | ||
}); | ||
__classPrivateFieldGet(this, _ChannelClient_instances, "m", _ChannelClient_startHandshake).call(this); | ||
this._startHandshake(); | ||
} | ||
} | ||
_ChannelClient_deferredPort = new WeakMap(), _ChannelClient_deferreds = new WeakMap(), _ChannelClient_timeout = new WeakMap(), _ChannelClient_instances = new WeakSet(), _ChannelClient_sendRequest = async function _ChannelClient_sendRequest(method, args) { | ||
const port = await __classPrivateFieldGet(this, _ChannelClient_deferredPort, "f").promise; | ||
const id = generateUUID(); | ||
const deferred = defer(__classPrivateFieldGet(this, _ChannelClient_timeout, "f")); | ||
deferred.promise | ||
.then((value) => { | ||
__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").delete(id); | ||
return value; | ||
}) | ||
.catch((err) => { | ||
__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").delete(id); | ||
throw err; | ||
}); | ||
__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").set(id, deferred); | ||
const req = { | ||
jsonrpc: "2.0", | ||
method, | ||
params: args, | ||
id, | ||
}; | ||
port.postMessage(req); | ||
return deferred.promise; | ||
}, _ChannelClient_portMessageHandler = function _ChannelClient_portMessageHandler(ev) { | ||
const { data } = ev; | ||
if (isJsonRpcSuccessResponse(data)) { | ||
const { id, result } = data; | ||
if (__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").has(id)) { | ||
__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").get(id).resolve(result); | ||
} | ||
async _sendRequest(method, args) { | ||
console.log("[CHANNEL_RPC][CLIENT] invoke fetching port"); | ||
const port = await this._deferredPort.promise; | ||
console.log("[CHANNEL_RPC][CLIENT] invoke fetch port", port); | ||
const id = generateUUID(); | ||
const deferred = defer(this._timeout); | ||
deferred.promise | ||
.then((value) => { | ||
delete this._deferreds[id]; | ||
return value; | ||
}) | ||
.catch((err) => { | ||
delete this._deferreds[id]; | ||
throw err; | ||
}); | ||
this._deferreds[id] = deferred; | ||
const req = { | ||
jsonrpc: "2.0", | ||
method, | ||
params: args, | ||
id, | ||
}; | ||
console.log("[CHANNEL_RPC][CLIENT] Send invoke", req); | ||
port.postMessage(req); | ||
return deferred.promise; | ||
} | ||
else if (isJsonRpcErrorResponse(data)) { | ||
const { id, error } = data; | ||
if (__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").has(id)) { | ||
__classPrivateFieldGet(this, _ChannelClient_deferreds, "f").get(id).reject(error); | ||
_portMessageHandler(ev) { | ||
console.log("[CHANNEL_RPC][CLIENT] portMessageHandler", ev); | ||
const { data } = ev; | ||
if (isJsonRpcSuccessResponse(data)) { | ||
const { id, result } = data; | ||
this._deferreds[id]?.resolve(result); | ||
} | ||
else if (isJsonRpcErrorResponse(data)) { | ||
const { id, error } = data; | ||
this._deferreds[id]?.reject(error); | ||
} | ||
else { | ||
console.warn("Unknown message", data); | ||
} | ||
} | ||
else { | ||
console.warn("Unknown message", data); | ||
_startHandshake() { | ||
const self = typeof globalThis === "object" ? globalThis : window; | ||
let port; | ||
const handler = (ev) => { | ||
if (ev.data && | ||
ev.data.type === MessageTypes.HandShakeResponse && | ||
ev.data.channelId === this.channelId && | ||
ev.ports.length) { | ||
console.log("[CHANNEL_RPC][CLIENT] receive port", ev); | ||
self.removeEventListener("message", handler); | ||
port = ev.ports[0]; | ||
console.log("[CHANNEL_RPC][CLIENT] connected", port); | ||
this._deferredPort.resolve(port); | ||
port.onmessage = this._portMessageHandler.bind(this); | ||
} | ||
}; | ||
self.addEventListener("message", handler); | ||
let interval = setInterval(() => { | ||
// DEBUG | ||
console.info("[CLIENT]HandShakeRequest", this.channelId, port); | ||
if (port) { | ||
clearInterval(interval); | ||
return; | ||
} | ||
this.target.postMessage({ | ||
type: MessageTypes.HandShakeRequest, | ||
channelId: this.channelId, | ||
}, "*"); | ||
}, 100); | ||
} | ||
}, _ChannelClient_startHandshake = function _ChannelClient_startHandshake() { | ||
const self = typeof globalThis === "object" ? globalThis : window; | ||
let interval = undefined; | ||
const handler = (ev) => { | ||
if (ev.data && | ||
ev.data.type === MessageTypes.HandShakeResponse && | ||
ev.data.channelId === this.channelId && | ||
ev.ports.length) { | ||
clearInterval(interval); | ||
this.target.removeEventListener("message", handler); | ||
const [port] = ev.ports; | ||
console.log("connected", port); | ||
__classPrivateFieldGet(this, _ChannelClient_deferredPort, "f").resolve(port); | ||
port.onmessage = __classPrivateFieldGet(this, _ChannelClient_instances, "m", _ChannelClient_portMessageHandler); | ||
} | ||
}; | ||
self.addEventListener("message", handler); | ||
interval = setInterval(() => { | ||
this.target.postMessage({ | ||
type: MessageTypes.HandShakeRequest, | ||
channelId: this.channelId, | ||
}, "*"); | ||
}, 100); | ||
}; | ||
} |
{ | ||
"name": "channel-rpc", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"author": "kouhin", | ||
@@ -5,0 +5,0 @@ "type": "module", |
165
src/index.ts
@@ -58,19 +58,20 @@ interface JsonRpcRequest { | ||
reject: (_reason: any) => {}, | ||
promise: new Promise<T>((resolve, reject) => { | ||
const t = timeout | ||
? setTimeout(() => { | ||
reject(new Error("timeout")); | ||
}, timeout) | ||
: undefined; | ||
promise: undefined as any as Promise<T>, | ||
}; | ||
deferred.promise = new Promise<T>((resolve, reject) => { | ||
const t = timeout | ||
? setTimeout(() => { | ||
reject(new Error("timeout")); | ||
}, timeout) | ||
: undefined; | ||
deferred.resolve = (value: T) => { | ||
clearTimeout(t); | ||
return resolve(value); | ||
}; | ||
deferred.reject = (reason: any) => { | ||
clearTimeout(t); | ||
return reject(reason); | ||
}; | ||
}), | ||
}; | ||
deferred.resolve = (value: T) => { | ||
clearTimeout(t); | ||
return resolve(value); | ||
}; | ||
deferred.reject = (reason: any) => { | ||
clearTimeout(t); | ||
return reject(reason); | ||
}; | ||
}); | ||
return deferred; | ||
@@ -80,7 +81,8 @@ } | ||
export class ChannelServer<T extends object> { | ||
#source: WindowProxy; | ||
#channelId: string; | ||
#channel: MessageChannel; | ||
#handlers = new Map<string, (...args: unknown[]) => unknown>(); | ||
readonly channelId: string; | ||
readonly source: WindowProxy; | ||
readonly channel: MessageChannel; | ||
private readonly _handlers: Record<string, (...args: unknown[]) => unknown>; | ||
constructor(options: { | ||
@@ -94,3 +96,4 @@ channelId: string; | ||
this.#channelId = channelId; | ||
this.channelId = channelId; | ||
this._handlers = {}; | ||
@@ -101,9 +104,14 @@ const h = handler || {}; | ||
if (typeof fn === "function") { | ||
this.#handlers.set(method, fn.bind(h)); | ||
this._handlers[method] = fn.bind(h); | ||
} | ||
}); | ||
this.#channel = new MessageChannel(); | ||
this.#source = source || window; | ||
this.#source.addEventListener("message", (ev) => { | ||
this.channel = new MessageChannel(); | ||
this.source = source || window; | ||
this.source.addEventListener("message", (ev) => { | ||
// DEBUG | ||
if (ev.data.type === MessageTypes.HandShakeRequest) { | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest", ev.data); | ||
} | ||
// Send back the port to the source window | ||
@@ -113,18 +121,23 @@ if ( | ||
ev.data.type === MessageTypes.HandShakeRequest && | ||
ev.data.channelId === this.#channelId | ||
ev.data.channelId === this.channelId | ||
) { | ||
console.log( | ||
"[CHANNEL_RPC][SERVER]HandShakeRequest Sendback", | ||
this.channel.port2 | ||
); | ||
(ev.source as WindowProxy).postMessage( | ||
{ | ||
type: MessageTypes.HandShakeResponse, | ||
channelId: this.#channelId, | ||
channelId: this.channelId, | ||
}, | ||
"*", | ||
[this.#channel.port2] | ||
[this.channel.port2] | ||
); | ||
} | ||
}); | ||
this.#channel.port1.onmessage = this.#handleMessage; | ||
this.channel.port1.onmessage = this._handleMessage.bind(this); | ||
} | ||
async #handleMessage(ev: MessageEvent): Promise<void> { | ||
private async _handleMessage(ev: MessageEvent): Promise<void> { | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest handleMessage", ev); | ||
const data = ev.data; | ||
@@ -140,7 +153,13 @@ if (!isJsonRpcRequest(data)) { | ||
}; | ||
this.#channel.port1.postMessage(res); | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
return; | ||
} | ||
const handler = this.#handlers.get(data.method); | ||
console.log( | ||
"[CHANNEL_RPC][SERVER]HandShakeRequest handleMessage method", | ||
data.method, | ||
this._handlers | ||
); | ||
const handler = this._handlers[data.method]; | ||
if (!handler) { | ||
@@ -155,3 +174,4 @@ const res: JsonRpcErrorResponse = { | ||
}; | ||
this.#channel.port1.postMessage(res); | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
return; | ||
@@ -166,3 +186,4 @@ } | ||
}; | ||
this.#channel.port1.postMessage(res); | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
} catch (err) { | ||
@@ -178,3 +199,4 @@ const res: JsonRpcErrorResponse = { | ||
}; | ||
this.#channel.port1.postMessage(res); | ||
console.log("[CHANNEL_RPC][SERVER]HandShakeRequest reply", res); | ||
this.channel.port1.postMessage(res); | ||
} | ||
@@ -194,6 +216,7 @@ } | ||
readonly target: WindowProxy; | ||
readonly #deferredPort: Deferred<MessagePort>; | ||
readonly #deferreds = new Map<string, Deferred<unknown>>(); | ||
readonly #timeout: number; | ||
private readonly _deferreds: Record<string, Deferred<unknown> | undefined>; | ||
private readonly _deferredPort: Deferred<MessagePort>; | ||
private readonly _timeout: number; | ||
constructor(options: { | ||
@@ -210,9 +233,11 @@ target: WindowProxy; | ||
this.channelId = channelId; | ||
this.#deferredPort = defer(0); | ||
this.#timeout = timeout || 1000; | ||
this._deferredPort = defer(0); | ||
this._deferreds = {}; | ||
this._timeout = timeout || 1000; | ||
this.stub = new Proxy({} as RemoteObject<T>, { | ||
get: (_target, prop) => { | ||
return async (...args: unknown[]) => { | ||
return this.#sendRequest(String(prop), args); | ||
return (...args: unknown[]) => { | ||
console.log("[CHANNEL_RPC][CLIENT] invoke stub method", prop, args); | ||
return this._sendRequest(String(prop), args); | ||
}; | ||
@@ -222,19 +247,24 @@ }, | ||
this.#startHandshake(); | ||
this._startHandshake(); | ||
} | ||
async #sendRequest(method: string, args: unknown[]): Promise<unknown> { | ||
const port = await this.#deferredPort.promise; | ||
private async _sendRequest( | ||
method: string, | ||
args: unknown[] | ||
): Promise<unknown> { | ||
console.log("[CHANNEL_RPC][CLIENT] invoke fetching port"); | ||
const port = await this._deferredPort.promise; | ||
console.log("[CHANNEL_RPC][CLIENT] invoke fetch port", port); | ||
const id = generateUUID(); | ||
const deferred = defer(this.#timeout); | ||
const deferred = defer(this._timeout); | ||
deferred.promise | ||
.then((value) => { | ||
this.#deferreds.delete(id); | ||
delete this._deferreds[id]; | ||
return value; | ||
}) | ||
.catch((err) => { | ||
this.#deferreds.delete(id); | ||
delete this._deferreds[id]; | ||
throw err; | ||
}); | ||
this.#deferreds.set(id, deferred); | ||
this._deferreds[id] = deferred; | ||
const req: JsonRpcRequest = { | ||
@@ -246,2 +276,3 @@ jsonrpc: "2.0", | ||
}; | ||
console.log("[CHANNEL_RPC][CLIENT] Send invoke", req); | ||
port.postMessage(req); | ||
@@ -251,14 +282,11 @@ return deferred.promise; | ||
#portMessageHandler(ev: MessageEvent) { | ||
private _portMessageHandler(ev: MessageEvent) { | ||
console.log("[CHANNEL_RPC][CLIENT] portMessageHandler", ev); | ||
const { data } = ev; | ||
if (isJsonRpcSuccessResponse(data)) { | ||
const { id, result } = data; | ||
if (this.#deferreds.has(id)) { | ||
this.#deferreds.get(id)!.resolve(result); | ||
} | ||
this._deferreds[id]?.resolve(result); | ||
} else if (isJsonRpcErrorResponse(data)) { | ||
const { id, error } = data; | ||
if (this.#deferreds.has(id)) { | ||
this.#deferreds.get(id)!.reject(error); | ||
} | ||
this._deferreds[id]?.reject(error); | ||
} else { | ||
@@ -269,6 +297,6 @@ console.warn("Unknown message", data); | ||
#startHandshake() { | ||
private _startHandshake() { | ||
const self = typeof globalThis === "object" ? globalThis : window; | ||
let interval: number | undefined = undefined; | ||
let port: MessagePort; | ||
const handler = (ev: MessageEvent) => { | ||
@@ -281,9 +309,9 @@ if ( | ||
) { | ||
clearInterval(interval); | ||
this.target.removeEventListener("message", handler); | ||
console.log("[CHANNEL_RPC][CLIENT] receive port", ev); | ||
self.removeEventListener("message", handler); | ||
const [port] = ev.ports; | ||
console.log("connected", port); | ||
this.#deferredPort.resolve(port); | ||
port.onmessage = this.#portMessageHandler; | ||
port = ev.ports[0]; | ||
console.log("[CHANNEL_RPC][CLIENT] connected", port); | ||
this._deferredPort.resolve(port); | ||
port.onmessage = this._portMessageHandler.bind(this); | ||
} | ||
@@ -293,3 +321,10 @@ }; | ||
interval = setInterval(() => { | ||
let interval = setInterval(() => { | ||
// DEBUG | ||
console.info("[CLIENT]HandShakeRequest", this.channelId, port); | ||
if (port) { | ||
clearInterval(interval); | ||
return; | ||
} | ||
this.target.postMessage( | ||
@@ -296,0 +331,0 @@ { |
551
22513