PostMessageProvider with on('connected' | 'disconnected') (#279)
* PostMessageProvider with on('connected' | 'disconnected')
* Update packages/extension/src/background/types.ts
This commit is contained in:
parent
1dee8f1d0f
commit
956a2c37ad
@ -247,7 +247,7 @@ export default class State {
|
||||
public rpcSend (request: RequestRpcSend, port: chrome.runtime.Port): Promise<JsonRpcResponse> {
|
||||
const provider = this.#injectedProviders.get(port);
|
||||
|
||||
assert(provider, 'Cannot call pub(rpc.subscribe) before provider has been set');
|
||||
assert(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
|
||||
|
||||
return provider.send(request.method, request.params);
|
||||
}
|
||||
@ -280,15 +280,25 @@ export default class State {
|
||||
public rpcSubscribe ({ method, params, type }: RequestRpcSubscribe, cb: ProviderInterfaceCallback, port: chrome.runtime.Port): Promise<number> {
|
||||
const provider = this.#injectedProviders.get(port);
|
||||
|
||||
assert(provider, 'Cannot call pub(rpc.subscribe) before provider has been set');
|
||||
assert(provider, 'Cannot call pub(rpc.subscribe) before provider is set');
|
||||
|
||||
return provider.subscribe(type, method, params, cb);
|
||||
}
|
||||
|
||||
public rpcSubscribeConnected (_request: null, cb: ProviderInterfaceCallback, port: chrome.runtime.Port): void {
|
||||
const provider = this.#injectedProviders.get(port);
|
||||
|
||||
assert(provider, 'Cannot call pub(rpc.subscribeConnected) before provider is set');
|
||||
|
||||
cb(null, provider.isConnected()); // Immediately send back current isConnected
|
||||
provider.on('connected', () => cb(null, true));
|
||||
provider.on('disconnected', () => cb(null, false));
|
||||
}
|
||||
|
||||
public rpcUnsubscribe (request: RequestRpcUnsubscribe, port: chrome.runtime.Port): Promise<boolean> {
|
||||
const provider = this.#injectedProviders.get(port);
|
||||
|
||||
assert(provider, 'Cannot call pub(rpc.unsubscribe) before provider has been set');
|
||||
assert(provider, 'Cannot call pub(rpc.unsubscribe) before provider is set');
|
||||
|
||||
return provider.unsubscribe(request.type, request.method, request.subscriptionId);
|
||||
}
|
||||
|
||||
@ -98,6 +98,18 @@ export default class Tabs {
|
||||
return true;
|
||||
}
|
||||
|
||||
private rpcSubscribeConnected (request: null, id: string, port: chrome.runtime.Port): Promise<boolean> {
|
||||
const innerCb = createSubscription<'pub(rpc.subscribeConnected)'>(id, port);
|
||||
const cb = (_error: Error | null, data: SubscriptionMessageTypes['pub(rpc.subscribeConnected)']): void => innerCb(data);
|
||||
this.#state.rpcSubscribeConnected(request, cb, port);
|
||||
|
||||
port.onDisconnect.addListener((): void => {
|
||||
unsubscribe(id);
|
||||
});
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
private async rpcUnsubscribe (request: RequestRpcUnsubscribe, port: chrome.runtime.Port): Promise<boolean> {
|
||||
return this.#state.rpcUnsubscribe(request, port);
|
||||
}
|
||||
@ -135,6 +147,9 @@ export default class Tabs {
|
||||
case 'pub(rpc.subscribe)':
|
||||
return this.rpcSubscribe(request as RequestRpcSubscribe, id, port);
|
||||
|
||||
case 'pub(rpc.subscribeConnected)':
|
||||
return this.rpcSubscribeConnected(request as null, id, port);
|
||||
|
||||
case 'pub(rpc.unsubscribe)':
|
||||
return this.rpcUnsubscribe(request as RequestRpcUnsubscribe, port);
|
||||
|
||||
|
||||
@ -72,6 +72,7 @@ export interface RequestSignatures {
|
||||
'pub(rpc.send)': [RequestRpcSend, JsonRpcResponse];
|
||||
'pub(rpc.startProvider)': [string, ProviderMeta];
|
||||
'pub(rpc.subscribe)': [RequestRpcSubscribe, number, JsonRpcResponse];
|
||||
'pub(rpc.subscribeConnected)': [null, boolean, boolean];
|
||||
'pub(rpc.unsubscribe)': [RequestRpcUnsubscribe, boolean];
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@ interface SubscriptionHandler {
|
||||
export default class PostMessageProvider implements InjectedProvider {
|
||||
readonly #eventemitter: EventEmitter;
|
||||
|
||||
// Whether or not the actual extension background provider is connected
|
||||
#isConnected = false
|
||||
|
||||
readonly #sendRequest: SendRequest;
|
||||
|
||||
// Subscription IDs are (historically) not guaranteed to be globally unique;
|
||||
@ -43,11 +46,6 @@ export default class PostMessageProvider implements InjectedProvider {
|
||||
public constructor (sendRequest: SendRequest) {
|
||||
this.#eventemitter = new EventEmitter();
|
||||
this.#sendRequest = sendRequest;
|
||||
|
||||
// Give subscribers time to subscribe
|
||||
setTimeout((): void => {
|
||||
this.#eventemitter.emit('connected');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,8 +76,7 @@ export default class PostMessageProvider implements InjectedProvider {
|
||||
* @return {boolean} true if connected
|
||||
*/
|
||||
public isConnected (): boolean {
|
||||
// FIXME This should see if the extension's state's provider is connected
|
||||
return true;
|
||||
return this.#isConnected;
|
||||
}
|
||||
|
||||
public listProviders (): Promise<ProviderList> {
|
||||
@ -121,8 +118,29 @@ export default class PostMessageProvider implements InjectedProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public startProvider (key: string): Promise<ProviderMeta> {
|
||||
return this.#sendRequest('pub(rpc.startProvider)', key);
|
||||
/**
|
||||
* @summary Spawn a provider on the extension background.
|
||||
*/
|
||||
public async startProvider (key: string): Promise<ProviderMeta> {
|
||||
// Disconnect from the previous provider
|
||||
this.#isConnected = false;
|
||||
this.#eventemitter.emit('disconnected');
|
||||
|
||||
const meta = await this.#sendRequest('pub(rpc.startProvider)', key);
|
||||
|
||||
this.#sendRequest('pub(rpc.subscribeConnected)', null, (connected) => {
|
||||
this.#isConnected = connected;
|
||||
|
||||
if (connected) {
|
||||
this.#eventemitter.emit('connected');
|
||||
} else {
|
||||
this.#eventemitter.emit('disconnected');
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
Loading…
Reference in New Issue
Block a user