Map sub-id on types, not methods (#135)
This commit is contained in:
@@ -53,11 +53,11 @@ export default class HttpProvider implements ProviderInterface {
|
||||
return this.coder.decodeResponse(result);
|
||||
}
|
||||
|
||||
async subscribe (method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number> {
|
||||
async subscribe (types: string, method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number> {
|
||||
throw new Error('Subscriptions has not been implemented');
|
||||
}
|
||||
|
||||
async unsubscribe (method: string, id: number): Promise<boolean> {
|
||||
async unsubscribe (type: string, method: string, id: number): Promise<boolean> {
|
||||
throw new Error('Subscriptions has not been implemented');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ export default function mockProvider (): ProviderInterface {
|
||||
on(self, type, sub),
|
||||
send: (method: string, params: Array<any>): Promise<any> =>
|
||||
send(self, method, params),
|
||||
subscribe: (method: string, ...params: Array<any>): Promise<number> =>
|
||||
subscribe(self, method, params),
|
||||
unsubscribe: (method: string, id: number): Promise<boolean> =>
|
||||
unsubscribe(self, method, id)
|
||||
subscribe: (type: string, method: string, ...params: Array<any>): Promise<number> =>
|
||||
subscribe(self, type, method, params),
|
||||
unsubscribe: (type: string, method: string, id: number): Promise<boolean> =>
|
||||
unsubscribe(self, type, method, id)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ describe('subscribe', () => {
|
||||
});
|
||||
|
||||
it('fails on unknown methods', () => {
|
||||
return subscribe(state, 'test_notFound').catch((error) => {
|
||||
return subscribe(state, 'test', 'test_notFound').catch((error) => {
|
||||
expect(error.message).toMatch(/Invalid method 'test_notFound'/);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a subscription id', () => {
|
||||
return subscribe(state, 'chain_newHead', [() => void 0]).then((id) => {
|
||||
return subscribe(state, 'chain_newHead', 'chain_newHead', [() => void 0]).then((id) => {
|
||||
expect(id).toEqual(state.subscriptionId);
|
||||
});
|
||||
});
|
||||
@@ -27,7 +27,7 @@ describe('subscribe', () => {
|
||||
it('stores the mapping values', () => {
|
||||
const cb = () => void 0;
|
||||
|
||||
return subscribe(state, 'chain_newHead', [cb]).then((id) => {
|
||||
return subscribe(state, 'chain_newHead', 'chain_newHead', [cb]).then((id) => {
|
||||
expect(state.subscriptionMap[id]).toEqual('chain_newHead');
|
||||
expect(state.subscriptions['chain_newHead'].callbacks[id]).toEqual(cb);
|
||||
});
|
||||
@@ -36,7 +36,7 @@ describe('subscribe', () => {
|
||||
it('calls back with the last known value', (done) => {
|
||||
state.subscriptions['chain_newHead'].lastValue = 'testValue';
|
||||
|
||||
subscribe(state, 'chain_newHead', [(_, value) => {
|
||||
subscribe(state, 'chain_newHead', 'chain_newHead', [(_, value) => {
|
||||
expect(value).toEqual('testValue');
|
||||
done();
|
||||
}]);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { MockState, MockState$Subscription$Callback } from './types';
|
||||
|
||||
export default async function subscribe (self: MockState, method: string, params: Array<any>): Promise<number> {
|
||||
export default async function subscribe (self: MockState, type: string, method: string, params: Array<any>): Promise<number> {
|
||||
self.l.debug(() => ['subscribe', method, params]);
|
||||
|
||||
if (self.subscriptions[method]) {
|
||||
|
||||
@@ -13,23 +13,23 @@ describe('unsubscribe', () => {
|
||||
beforeEach(() => {
|
||||
state = createState();
|
||||
|
||||
return subscribe(state, 'chain_newHead', [() => void 0]).then((_id) => {
|
||||
return subscribe(state, 'chain_newHead', 'chain_newHead', [() => void 0]).then((_id) => {
|
||||
id = _id;
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on unknown ids', () => {
|
||||
return unsubscribe(state, 'chain_newHead', 5).catch((error) => {
|
||||
return unsubscribe(state, 'chain_newHead', 'chain_newHead', 5).catch((error) => {
|
||||
expect(error.message).toMatch(/Unable to find/);
|
||||
});
|
||||
});
|
||||
|
||||
it('unsubscribes successfully', () => {
|
||||
return unsubscribe(state, 'chain_newHead', id);
|
||||
return unsubscribe(state, 'chain_newHead', 'chain_newHead', id);
|
||||
});
|
||||
|
||||
it('fails on double unsubscribe', () => {
|
||||
return unsubscribe(state, 'chain_newHead', id)
|
||||
return unsubscribe(state, 'chain_newHead', 'chain_newHead', id)
|
||||
.then(() => unsubscribe(state, id))
|
||||
.catch((error) => {
|
||||
expect(error.message).toMatch(/Unable to find/);
|
||||
@@ -37,7 +37,7 @@ describe('unsubscribe', () => {
|
||||
});
|
||||
|
||||
it('clears the subscriptions', () => {
|
||||
return unsubscribe(state, 'chain_newHead', id).then(() => {
|
||||
return unsubscribe(state, 'chain_newHead', 'chain_newHead', id).then(() => {
|
||||
expect(state.subscriptionMap[id]).not.toBeDefined();
|
||||
expect(state.subscriptions['chain_newHead'].callbacks[id]).not.toBeDefined();
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { MockState } from './types';
|
||||
|
||||
export default async function unsubscribe (self: MockState, _: string, id: number): Promise<boolean> {
|
||||
export default async function unsubscribe (self: MockState, type: string, name: string, id: number): Promise<boolean> {
|
||||
const method = self.subscriptionMap[id];
|
||||
|
||||
self.l.debug(() => ['unsubscribe', id, method]);
|
||||
|
||||
Vendored
+2
-2
@@ -45,6 +45,6 @@ export interface ProviderInterface {
|
||||
isConnected (): boolean,
|
||||
on (type: ProviderInterface$Emitted, sub: ProviderInterface$EmitCb): void,
|
||||
send (method: string, params: Array<any>): Promise<any>,
|
||||
subscribe (method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number>,
|
||||
unsubscribe (method: string, id: number): Promise<boolean>
|
||||
subscribe (type: string, method: string, params: Array<any>, cb: ProviderInterface$Callback): Promise<number>,
|
||||
unsubscribe (type: string, method: string, id: number): Promise<boolean>
|
||||
}
|
||||
|
||||
@@ -16,15 +16,19 @@ import logger from '@polkadot/util/logger';
|
||||
|
||||
import coder from '../coder/json';
|
||||
|
||||
type SubscriptionHandler = {
|
||||
callback: ProviderInterface$Callback,
|
||||
type: string
|
||||
};
|
||||
|
||||
type WsState$Awaiting = {
|
||||
callback: ProviderInterface$Callback,
|
||||
method: string,
|
||||
params: Array<any>,
|
||||
subscription?: ProviderInterface$Callback
|
||||
subscription?: SubscriptionHandler
|
||||
};
|
||||
|
||||
type WsState$Subscription = {
|
||||
callback: ProviderInterface$Callback,
|
||||
type WsState$Subscription = SubscriptionHandler & {
|
||||
method: string,
|
||||
params: Array<any>
|
||||
};
|
||||
@@ -91,7 +95,7 @@ export default class WsProvider extends E3.EventEmitter implements WSProviderInt
|
||||
return super.on(type, sub);
|
||||
}
|
||||
|
||||
async send (method: string, params: Array<any>, subscription?: ProviderInterface$Callback): Promise<any> {
|
||||
async send (method: string, params: Array<any>, subscription?: SubscriptionHandler): Promise<any> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
try {
|
||||
const json = this.coder.encodeJson(method, params);
|
||||
@@ -124,16 +128,18 @@ export default class WsProvider extends E3.EventEmitter implements WSProviderInt
|
||||
});
|
||||
}
|
||||
|
||||
async subscribe (method: string, params: Array<any>, subscription: ProviderInterface$Callback): Promise<number> {
|
||||
const id = await this.send(method, params, subscription);
|
||||
async subscribe (type: string, method: string, params: Array<any>, callback: ProviderInterface$Callback): Promise<number> {
|
||||
const id = await this.send(method, params, { callback, type });
|
||||
|
||||
return id as number;
|
||||
}
|
||||
|
||||
async unsubscribe (method: string, id: number): Promise<boolean> {
|
||||
assert(!isUndefined(this.subscriptions[`${method}::${id}`]), `Unable to find active subscription=${id}`);
|
||||
async unsubscribe (type: string, method: string, id: number): Promise<boolean> {
|
||||
const subscription = `${type}::${id}`;
|
||||
|
||||
delete this.subscriptions[id];
|
||||
assert(!isUndefined(this.subscriptions[subscription]), `Unable to find active subscription=${subscription}`);
|
||||
|
||||
delete this.subscriptions[subscription];
|
||||
|
||||
const result = await this.send(method, [id]);
|
||||
|
||||
@@ -178,12 +184,12 @@ export default class WsProvider extends E3.EventEmitter implements WSProviderInt
|
||||
}
|
||||
|
||||
try {
|
||||
const { method, params, subscription } = this.handlers[response.id];
|
||||
const { method, params, subscription } = handler;
|
||||
const result = this.coder.decodeResponse(response);
|
||||
|
||||
if (subscription) {
|
||||
this.subscriptions[`${method}::${result}`] = {
|
||||
callback: subscription,
|
||||
this.subscriptions[`${subscription.type}::${result}`] = {
|
||||
...subscription,
|
||||
method,
|
||||
params
|
||||
};
|
||||
|
||||
@@ -29,9 +29,12 @@ describe('onMessageSubscribe', () => {
|
||||
ws.handlers[11] = {
|
||||
callback: (_, id) => {},
|
||||
method: 'test',
|
||||
subscription: (_, result) => {
|
||||
expect(result).toEqual('test');
|
||||
done();
|
||||
subscription: {
|
||||
callback: (_, result) => {
|
||||
expect(result).toEqual('test');
|
||||
done();
|
||||
},
|
||||
type: 'test'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -43,9 +46,12 @@ describe('onMessageSubscribe', () => {
|
||||
ws.handlers[11] = {
|
||||
callback: (_, id) => {},
|
||||
method: 'test',
|
||||
subscription: (error) => {
|
||||
expect(error.message).toMatch(/test/);
|
||||
done();
|
||||
subscription: {
|
||||
callback: (error) => {
|
||||
expect(error.message).toMatch(/test/);
|
||||
done();
|
||||
},
|
||||
type: 'test'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ describe('subscribe', () => {
|
||||
const ws = createWs();
|
||||
|
||||
return ws
|
||||
.subscribe('subscribe_test', [], () => {})
|
||||
.subscribe('test', 'subscribe_test', [], () => {})
|
||||
.then((id) => {
|
||||
return ws.unsubscribe('subscribe_test', id);
|
||||
return ws.unsubscribe('test', 'subscribe_test', id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,9 +74,9 @@ describe('subscribe', () => {
|
||||
const ws = createWs();
|
||||
|
||||
return ws
|
||||
.subscribe('subscribe_test', [], () => {})
|
||||
.subscribe('test', 'subscribe_test', [], () => {})
|
||||
.then((id) => {
|
||||
return ws.unsubscribe('subscribe_test', 111);
|
||||
return ws.unsubscribe('test', 'subscribe_test', 111);
|
||||
})
|
||||
.catch((error) => {
|
||||
expect(error.message).toMatch(/find active subscription/);
|
||||
|
||||
@@ -21,7 +21,7 @@ describe('formatResult', () => {
|
||||
send: jest.fn((method, params) =>
|
||||
Promise.resolve('0x0102')
|
||||
),
|
||||
subscribe: jest.fn((method, params, subscription) =>
|
||||
subscribe: jest.fn((type, method, params, subscription) =>
|
||||
subscription(null, {
|
||||
block: '0x1234',
|
||||
changes: [
|
||||
@@ -61,6 +61,7 @@ describe('formatResult', () => {
|
||||
expect(
|
||||
provider.subscribe
|
||||
).toHaveBeenCalledWith(
|
||||
'state_storage',
|
||||
'state_subscribeStorage',
|
||||
[[ENC_ONE, ENC_TWO]],
|
||||
expect.anything()
|
||||
|
||||
@@ -17,7 +17,7 @@ import formatResult from './formatResult';
|
||||
|
||||
export default function methodSubscribe (provider: ProviderInterface, rpcName: string, method: SectionItem<Interfaces>): ApiInterface$Section$Method {
|
||||
const unsubscribe = (subscriptionId: any): Promise<any> =>
|
||||
provider.send(method.subscribe[1], [subscriptionId]);
|
||||
provider.unsubscribe(rpcName, method.subscribe[1], subscriptionId);
|
||||
const _call = async (...values: Array<any>): Promise<any> => {
|
||||
try {
|
||||
const cb: ProviderInterface$Callback = values.pop();
|
||||
@@ -29,7 +29,7 @@ export default function methodSubscribe (provider: ProviderInterface, rpcName: s
|
||||
cb(error, formatResult(method, params, values, result));
|
||||
};
|
||||
|
||||
return provider.subscribe(method.subscribe[0], params, update);
|
||||
return provider.subscribe(rpcName, method.subscribe[0], params, update);
|
||||
} catch (error) {
|
||||
throw new ExtError(`${signature(method)}:: ${error.message}`, (error as ExtError).code, undefined);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user