mobility-toolbox-js 2.0.0-beta.36 → 2.0.0-beta.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +14 -8
  2. package/api/RealtimeAPI.test.d.ts +2 -0
  3. package/api/RealtimeAPI.test.d.ts.map +1 -0
  4. package/api/RealtimeAPI.test.js +67 -0
  5. package/api/RoutingAPI.d.ts +6 -2
  6. package/api/RoutingAPI.d.ts.map +1 -1
  7. package/api/RoutingAPI.test.d.ts +2 -0
  8. package/api/RoutingAPI.test.d.ts.map +1 -0
  9. package/api/RoutingAPI.test.js +29 -0
  10. package/api/StopsAPI.test.d.ts +2 -0
  11. package/api/StopsAPI.test.d.ts.map +1 -0
  12. package/api/StopsAPI.test.js +26 -0
  13. package/common/api/HttpAPI.d.ts +4 -4
  14. package/common/api/HttpAPI.d.ts.map +1 -1
  15. package/common/api/HttpAPI.test.d.ts +2 -0
  16. package/common/api/HttpAPI.test.d.ts.map +1 -0
  17. package/common/api/HttpAPI.test.js +54 -0
  18. package/common/api/WebSocketAPI.d.ts +6 -2
  19. package/common/api/WebSocketAPI.d.ts.map +1 -1
  20. package/common/api/WebSocketAPI.js +57 -31
  21. package/common/api/WebSocketAPI.test.d.ts +2 -0
  22. package/common/api/WebSocketAPI.test.d.ts.map +1 -0
  23. package/common/api/WebSocketAPI.test.js +380 -0
  24. package/common/controls/Control.test.d.ts +2 -0
  25. package/common/controls/Control.test.d.ts.map +1 -0
  26. package/common/controls/Control.test.js +89 -0
  27. package/common/layers/Layer.test.d.ts +2 -0
  28. package/common/layers/Layer.test.d.ts.map +1 -0
  29. package/common/layers/Layer.test.js +137 -0
  30. package/common/mixins/UserInteractionsLayerMixin.test.d.ts +2 -0
  31. package/common/mixins/UserInteractionsLayerMixin.test.d.ts.map +1 -0
  32. package/common/mixins/UserInteractionsLayerMixin.test.js +214 -0
  33. package/common/styles/realtimeDefaultStyle.d.ts.map +1 -1
  34. package/common/styles/realtimeDefaultStyle.js +2 -4
  35. package/common/styles/realtimeSimpleStyle.js +1 -1
  36. package/common/utils/createTrackerFilters.test.d.ts +2 -0
  37. package/common/utils/createTrackerFilters.test.d.ts.map +1 -0
  38. package/common/utils/createTrackerFilters.test.js +79 -0
  39. package/common/utils/getMapboxMapCopyrights.test.d.ts +2 -0
  40. package/common/utils/getMapboxMapCopyrights.test.d.ts.map +1 -0
  41. package/common/utils/getMapboxMapCopyrights.test.js +40 -0
  42. package/common/utils/removeDuplicate.test.d.ts +2 -0
  43. package/common/utils/removeDuplicate.test.d.ts.map +1 -0
  44. package/common/utils/removeDuplicate.test.js +19 -0
  45. package/common/utils/timeUtils.test.d.ts +2 -0
  46. package/common/utils/timeUtils.test.d.ts.map +1 -0
  47. package/common/utils/timeUtils.test.js +10 -0
  48. package/common/utils/trackerConfig.test.d.ts +2 -0
  49. package/common/utils/trackerConfig.test.d.ts.map +1 -0
  50. package/common/utils/trackerConfig.test.js +23 -0
  51. package/mapbox/layers/Layer.test.d.ts +2 -0
  52. package/mapbox/layers/Layer.test.d.ts.map +1 -0
  53. package/mapbox/layers/Layer.test.js +204 -0
  54. package/mapbox/layers/RealtimeLayer.test.d.ts +2 -0
  55. package/mapbox/layers/RealtimeLayer.test.d.ts.map +1 -0
  56. package/mapbox/layers/RealtimeLayer.test.js +10 -0
  57. package/mbt.js +53 -32
  58. package/mbt.js.map +2 -2
  59. package/mbt.min.js +10 -10
  60. package/mbt.min.js.map +2 -2
  61. package/ol/controls/CopyrightControl.test.d.ts +2 -0
  62. package/ol/controls/CopyrightControl.test.d.ts.map +1 -0
  63. package/ol/controls/CopyrightControl.test.js +177 -0
  64. package/ol/controls/RoutingControl.test.d.ts +2 -0
  65. package/ol/controls/RoutingControl.test.d.ts.map +1 -0
  66. package/ol/controls/RoutingControl.test.js +150 -0
  67. package/ol/controls/StopFinderControl.test.d.ts +2 -0
  68. package/ol/controls/StopFinderControl.test.d.ts.map +1 -0
  69. package/ol/controls/StopFinderControl.test.js +49 -0
  70. package/ol/layers/Layer.test.d.ts +2 -0
  71. package/ol/layers/Layer.test.d.ts.map +1 -0
  72. package/ol/layers/Layer.test.js +196 -0
  73. package/ol/layers/MapboxLayer.test.d.ts +2 -0
  74. package/ol/layers/MapboxLayer.test.d.ts.map +1 -0
  75. package/ol/layers/MapboxLayer.test.js +164 -0
  76. package/ol/layers/MapboxStyleLayer.test.d.ts +2 -0
  77. package/ol/layers/MapboxStyleLayer.test.d.ts.map +1 -0
  78. package/ol/layers/MapboxStyleLayer.test.js +232 -0
  79. package/ol/layers/RealtimeLayer.test.d.ts +2 -0
  80. package/ol/layers/RealtimeLayer.test.d.ts.map +1 -0
  81. package/ol/layers/RealtimeLayer.test.js +71 -0
  82. package/ol/layers/RoutingLayer.test.d.ts +2 -0
  83. package/ol/layers/RoutingLayer.test.d.ts.map +1 -0
  84. package/ol/layers/RoutingLayer.test.js +39 -0
  85. package/ol/layers/VectorLayer.test.d.ts +2 -0
  86. package/ol/layers/VectorLayer.test.d.ts.map +1 -0
  87. package/ol/layers/VectorLayer.test.js +87 -0
  88. package/ol/layers/WMSLayer.test.d.ts +2 -0
  89. package/ol/layers/WMSLayer.test.d.ts.map +1 -0
  90. package/ol/layers/WMSLayer.test.js +66 -0
  91. package/package.json +4 -1
package/README.md CHANGED
@@ -5,19 +5,25 @@ The tools in this library have been inspired by many projects realized for publi
5
5
 
6
6
  [![npm](https://img.shields.io/npm/v/mobility-toolbox-js.svg?style=flat-square)](https://www.npmjs.com/package/mobility-toolbox-js)
7
7
  [![Build](https://github.com/geops/mobility-toolbox-js/workflows/Build/badge.svg)](https://github.com/geops/mobility-toolbox-js/actions?query=workflow%3ABuild)
8
- [![Netlify Status](https://api.netlify.com/api/v1/badges/b368ab18-9dbf-416c-91f6-a82076b02c10/deploy-status)](https://app.netlify.com/sites/mobility-toolbox-js/deploys)
8
+ ![Vercel](https://vercelbadge.vercel.app/api/geops/mobility-toolbox-js)
9
9
 
10
- ## Main Features
10
+ ## Documentation and examples
11
11
 
12
- * Display [real-time vehicle positions and prognosis data](http://tracker.geops.ch/) on a map.
13
- * Search for [stops and stations](https://maps2.trafimage.ch) all over the world.
14
- * Get [precise geographic courses](https://geops.github.io/geops-routing-demo/) for all modes of transport.
15
- * Generate beautiful maps for public transport, mobility and logistics
12
+ Visit https://mobility-toolbox-js.vercel.app/
16
13
 
17
- ## Documentation and examples
14
+ ## Demos
18
15
 
19
- Visit https://master--mobility-toolbox-js.netlify.app/
16
+ * Display [real-time vehicle positions and prognosis data](http://tracker.geops.ch/) on a map.
17
+ * Search for [stops and stations](https://maps.trafimage.ch) all over the world.
18
+ * Get [precise geographic courses](https://routing-demo.geops.io/) for all modes of transport.
19
+ * Generate beautiful [schematic](https://mobility.portal.geops.io/world.geops.networkplans) or [topographic](https://mobility.portal.geops.io) maps for public transport, mobility and logistics.
20
20
 
21
21
  ## Version 1.x.x
22
22
 
23
23
  The master branch is now open for the version 2 development. The version 1 is still available in [1.x.x](https://github.com/geops/mobility-toolbox-js/tree/1.x.x) branch.
24
+
25
+ ## Deploy
26
+
27
+ This library website is deployed automatically using [Vercel](https://vercel.com/geops).
28
+ For Vercel we have to add the nextjs and raw-loader modules in the dev dependencies of the main package.json.
29
+ But those 2 librairies are not need to build the library.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=RealtimeAPI.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RealtimeAPI.test.d.ts","sourceRoot":"","sources":["../../src/api/RealtimeAPI.test.js"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { RealtimeAPI, RealtimeModes } from '.';
2
+ describe('RealtimeAPI', () => {
3
+ let api;
4
+ let get;
5
+ beforeEach(() => {
6
+ get = jest.fn((params, cb) => {
7
+ cb({ content: 'content' });
8
+ });
9
+ api = new RealtimeAPI();
10
+ api.wsApi = {
11
+ get,
12
+ };
13
+ });
14
+ describe('#getFullTrajectory() calls fullTrajectory channel', () => {
15
+ test('without parameters', (done) => {
16
+ api.getFullTrajectory().then(() => {
17
+ expect(get.mock.calls.length).toBe(1);
18
+ expect(get.mock.calls[0][0]).toEqual({
19
+ channel: 'full_trajectory',
20
+ });
21
+ done();
22
+ });
23
+ });
24
+ [null, RealtimeModes.TOPOGRAPHIC].forEach((mode) => {
25
+ describe(`using mode ${mode}`, () => {
26
+ test('using id', (done) => {
27
+ api.getFullTrajectory('foo', mode).then(() => {
28
+ expect(get.mock.calls.length).toBe(1);
29
+ expect(get.mock.calls[0][0]).toEqual({
30
+ channel: 'full_trajectory_foo',
31
+ });
32
+ done();
33
+ });
34
+ });
35
+ test('using id and generalizationLevel param', (done) => {
36
+ api.getFullTrajectory('foo', mode, 5).then(() => {
37
+ expect(get.mock.calls.length).toBe(1);
38
+ expect(get.mock.calls[0][0]).toEqual({
39
+ channel: 'full_trajectory_foo_gen5',
40
+ });
41
+ done();
42
+ });
43
+ });
44
+ });
45
+ });
46
+ describe('using schematic mode ', () => {
47
+ test('using id', (done) => {
48
+ api.getFullTrajectory('foo', RealtimeModes.SCHEMATIC).then(() => {
49
+ expect(get.mock.calls.length).toBe(1);
50
+ expect(get.mock.calls[0][0]).toEqual({
51
+ channel: 'full_trajectory_schematic_foo',
52
+ });
53
+ done();
54
+ });
55
+ });
56
+ test("doesn't use generalizationLevel param", (done) => {
57
+ api.getFullTrajectory('foo', RealtimeModes.SCHEMATIC, 10).then(() => {
58
+ expect(get.mock.calls.length).toBe(1);
59
+ expect(get.mock.calls[0][0]).toEqual({
60
+ channel: 'full_trajectory_schematic_foo',
61
+ });
62
+ done();
63
+ });
64
+ });
65
+ });
66
+ });
67
+ });
@@ -1,5 +1,9 @@
1
- import HttpAPI, { HttpApiOptions } from '../common/api/HttpAPI';
1
+ import HttpAPI from '../common/api/HttpAPI';
2
2
  import { RoutingParameters, RoutingResponse } from '../../types';
3
+ export declare type RoutingAPIOptions = {
4
+ url?: string;
5
+ apiKey?: string;
6
+ };
3
7
  /**
4
8
  * Access to the [geOps Routing service](https://developer.geops.io/apis/routing).
5
9
  *
@@ -19,7 +23,7 @@ declare class RoutingAPI extends HttpAPI {
19
23
  * @param {string} [options.url='https://api.geops.io/routing/v1/'] Service url.
20
24
  * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).
21
25
  */
22
- constructor(options: HttpApiOptions);
26
+ constructor(options: RoutingAPIOptions);
23
27
  /**
24
28
  * Route.
25
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"RoutingAPI.d.ts","sourceRoot":"","sources":["../../src/api/RoutingAPI.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE;;;;;;;;;;GAUG;AACH,cAAM,UAAW,SAAQ,OAAO;IAC9B;;;;;;OAMG;gBACS,OAAO,EAAE,cAAc;IAInC;;;;;;OAMG;IACH,KAAK,CACH,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,CAAC;CAG5B;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"RoutingAPI.d.ts","sourceRoot":"","sources":["../../src/api/RoutingAPI.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,oBAAY,iBAAiB,GAAG;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,cAAM,UAAW,SAAQ,OAAO;IAC9B;;;;;;OAMG;gBACS,OAAO,EAAE,iBAAiB;IAItC;;;;;;OAMG;IACH,KAAK,CACH,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,CAAC;CAG5B;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=RoutingAPI.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoutingAPI.test.d.ts","sourceRoot":"","sources":["../../src/api/RoutingAPI.test.js"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import fetch from 'jest-fetch-mock';
2
+ import RoutingAPI from './RoutingAPI';
3
+ let api;
4
+ describe('RoutingAPI', () => {
5
+ beforeEach(() => {
6
+ global.fetch = fetch;
7
+ fetch.resetMocks();
8
+ api = new RoutingAPI({ apiKey: 'apiKey' });
9
+ });
10
+ describe('#route', () => {
11
+ test('should success', (done) => {
12
+ fetch.mockResponseOnce(JSON.stringify(global.fetchRouteResponse));
13
+ return api
14
+ .route({
15
+ mot: 'bus',
16
+ via: '47.3739194713294,8.538274823394632|47.37595378493421,8.537490375951839',
17
+ })
18
+ .then((featureCollection) => {
19
+ // Correct url
20
+ expect(fetch.mock.calls[0][0]).toEqual('https://api.geops.io/routing/v1/?key=apiKey&mot=bus&via=47.3739194713294%2C8.538274823394632%7C47.37595378493421%2C8.537490375951839');
21
+ // Correct search result (for bus mot)
22
+ expect(featureCollection.features[0].geometry.type).toEqual('LineString');
23
+ expect(featureCollection.features[0].properties.lines).toBeDefined();
24
+ expect(featureCollection.features[0].properties.station_to).toBeDefined();
25
+ done();
26
+ });
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=StopsAPI.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StopsAPI.test.d.ts","sourceRoot":"","sources":["../../src/api/StopsAPI.test.js"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import fetch from 'jest-fetch-mock';
2
+ import StopsAPI from './StopsAPI';
3
+ let api;
4
+ describe('StopsAPI', () => {
5
+ beforeEach(() => {
6
+ global.fetch = fetch;
7
+ fetch.resetMocks();
8
+ api = new StopsAPI({ apiKey: 'apiKey' });
9
+ });
10
+ describe('#search', () => {
11
+ test('should success', (done) => {
12
+ fetch.mockResponseOnce(JSON.stringify(global.stopsSearchResponse));
13
+ return api
14
+ .search({
15
+ q: 'Bern',
16
+ })
17
+ .then((featureCollection) => {
18
+ // Correct url
19
+ expect(fetch.mock.calls[0][0]).toEqual('https://api.geops.io/stops/v1/?key=apiKey&q=Bern');
20
+ // Correct search result
21
+ expect(featureCollection.features[0].properties.name).toEqual('Bern');
22
+ done();
23
+ });
24
+ });
25
+ });
26
+ });
@@ -1,6 +1,6 @@
1
1
  import BaseObject from 'ol/Object';
2
- export declare type HttpApiOptions = {
3
- url?: string;
2
+ export declare type HttpAPIOptions = {
3
+ url: string;
4
4
  apiKey?: string;
5
5
  };
6
6
  /**
@@ -18,9 +18,9 @@ export declare type HttpApiOptions = {
18
18
  * @classproperty {string} apiKey Api key to access the service.
19
19
  */
20
20
  declare class HttpAPI extends BaseObject {
21
- url?: string;
21
+ url: string;
22
22
  apiKey?: string;
23
- constructor(options: HttpApiOptions);
23
+ constructor(options: HttpAPIOptions);
24
24
  /**
25
25
  * Append the apiKey before sending the request.
26
26
  * @ignore
@@ -1 +1 @@
1
- {"version":3,"file":"HttpAPI.d.ts","sourceRoot":"","sources":["../../../src/common/api/HttpAPI.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,WAAW,CAAC;AAGnC,oBAAY,cAAc,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AACF;;;;;;;;;;;;;GAaG;AACH,cAAM,OAAQ,SAAQ,UAAU;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEJ,OAAO,EAAE,cAAc;IASnC;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAmCvE;AAED,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"HttpAPI.d.ts","sourceRoot":"","sources":["../../../src/common/api/HttpAPI.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,WAAW,CAAC;AAGnC,oBAAY,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AACF;;;;;;;;;;;;;GAaG;AACH,cAAM,OAAQ,SAAQ,UAAU;IAC9B,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEJ,OAAO,EAAE,cAAc;IASnC;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;CAmCvE;AAED,eAAe,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=HttpAPI.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpAPI.test.d.ts","sourceRoot":"","sources":["../../../src/common/api/HttpAPI.test.js"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import fetch from 'jest-fetch-mock';
2
+ import API from './HttpAPI';
3
+ let api;
4
+ describe('HttpAPI', () => {
5
+ beforeEach(() => {
6
+ global.fetch = fetch;
7
+ fetch.resetMocks();
8
+ api = new API({ url: 'https://foo.ch', apiKey: 'apiKey' });
9
+ });
10
+ describe('#fetch', () => {
11
+ test('should success', () => {
12
+ fetch.mockResponseOnce(JSON.stringify({ foo: 'bar' }));
13
+ return api
14
+ .fetch('/path', {
15
+ q: 'Bern',
16
+ fooUndefined: undefined,
17
+ fooNull: null,
18
+ fooEmpty: '',
19
+ })
20
+ .then((response) => {
21
+ // Correct url
22
+ expect(fetch.mock.calls[0][0]).toEqual('https://foo.ch/path?key=apiKey&q=Bern&fooEmpty=');
23
+ // Correct search result
24
+ expect(response).toEqual({ foo: 'bar' });
25
+ });
26
+ });
27
+ describe('should display error message', () => {
28
+ test('reject error', (done) => {
29
+ fetch.mockRejectOnce(new Error('Fake error message'));
30
+ return api.fetch().catch((err) => {
31
+ expect(err.name).toEqual('Error');
32
+ expect(err.message).toEqual('Fake error message');
33
+ done();
34
+ });
35
+ });
36
+ test('if the response is invalid json', (done) => {
37
+ fetch.mockResponseOnce('invalid json');
38
+ api.fetch().catch((err) => {
39
+ expect(err.name).toEqual('FetchError');
40
+ expect(err.message).toEqual('invalid json response body at reason: Unexpected token i in JSON at position 0');
41
+ done();
42
+ });
43
+ });
44
+ test('if the response contains an error message', (done) => {
45
+ fetch.mockResponseOnce('{"error":"foo2"}');
46
+ api.fetch().catch((err) => {
47
+ expect(err.name).toEqual('Error');
48
+ expect(err.message).toEqual('foo2');
49
+ done();
50
+ });
51
+ });
52
+ });
53
+ });
54
+ });
@@ -42,6 +42,8 @@ declare class WebSocketAPI {
42
42
  * @private
43
43
  */
44
44
  private send;
45
+ addEvents(onMessage: any, onError: any): void;
46
+ removeEvents(onMessage: any, onError: any): void;
45
47
  /**
46
48
  * Listen to websocket messages.
47
49
  *
@@ -62,13 +64,15 @@ declare class WebSocketAPI {
62
64
  private unlisten;
63
65
  /**
64
66
  * Sends a get request to the websocket.
67
+ * The callback is called only once, when the response is received or when the call returns an error.
65
68
  *
66
69
  * @param {Object} params Parameters for the websocket get request
67
- * @param {function} cb callback on listen
68
- * @param {function} errorCb Callback on error
70
+ * @param {function} onMessage callback on message event
71
+ * @param {function} onError Callback on error and close event
69
72
  * @private
70
73
  */
71
74
  private get;
75
+ requests: any[] | undefined;
72
76
  /**
73
77
  * Subscribe to a given channel.
74
78
  *
@@ -1 +1 @@
1
- {"version":3,"file":"WebSocketAPI.d.ts","sourceRoot":"","sources":["../../../src/common/api/WebSocketAPI.js"],"names":[],"mappings":";AAAA;;;;GAIG;AACH;IAiEE;;;;;;;;;;OAUG;IACH,gCAKC;IA5ED,yBA0DC;IAoBD;;;;;;OAMG;IACH,gBAiBC;IAZC,cAAc;IACd,wCAAmC;IAarC;;;;OAIG;IACH,cAOC;IAFG,kCAAwB;IAI5B;;;;;OAKG;IACH,aAsBC;IAED;;;;;;;;OAQG;IACH,eAsCC;IAED;;;;;;OAMG;IACH,iBAiBC;IAED;;;;;;;OAOG;IACH,YAIC;IAED;;;;;;;;OAQG;IACH,kBAqBC;IAED;;;;;OAKG;IACH,oBA8BC;IAfC,mBAEC;IAeH;;OAEG;IACH,uCAYC;CACF"}
1
+ {"version":3,"file":"WebSocketAPI.d.ts","sourceRoot":"","sources":["../../../src/common/api/WebSocketAPI.js"],"names":[],"mappings":";AAAA;;;;GAIG;AACH;IAiEE;;;;;;;;;;OAUG;IACH,gCAKC;IA5ED,yBA0DC;IAoBD;;;;;;OAMG;IACH,gBAiBC;IAZC,cAAc;IACd,wCAAmC;IAarC;;;;OAIG;IACH,cAOC;IAFG,kCAAwB;IAI5B;;;;;OAKG;IACH,aAsBC;IAED,8CASC;IAED,iDASC;IAED;;;;;;;;OAQG;IACH,eAgCC;IAED;;;;;;OAMG;IACH,iBAQC;IAED;;;;;;;;OAQG;IACH,YA4CC;IAlBG,4BAAkB;IAoBtB;;;;;;;;OAQG;IACH,kBAqBC;IAED;;;;;OAKG;IACH,oBAwBC;IAfC,mBAEC;IAeH;;OAEG;IACH,uCAYC;CACF"}
@@ -137,6 +137,24 @@ class WebSocketAPI {
137
137
  send();
138
138
  }
139
139
  }
140
+ addEvents(onMessage, onError) {
141
+ if (this.websocket) {
142
+ this.websocket.addEventListener('message', onMessage);
143
+ if (onError) {
144
+ this.websocket.addEventListener('error', onError);
145
+ this.websocket.addEventListener('close', onError);
146
+ }
147
+ }
148
+ }
149
+ removeEvents(onMessage, onError) {
150
+ if (this.websocket) {
151
+ this.websocket.removeEventListener('message', onMessage);
152
+ if (onError) {
153
+ this.websocket.removeEventListener('error', onError);
154
+ this.websocket.removeEventListener('close', onError);
155
+ }
156
+ }
157
+ }
140
158
  /**
141
159
  * Listen to websocket messages.
142
160
  *
@@ -148,7 +166,8 @@ class WebSocketAPI {
148
166
  */
149
167
  listen(params, cb, errorCb) {
150
168
  // Remove the previous identical callback
151
- this.unlisten(params, cb);
169
+ this.unlisten(params, cb, errorCb);
170
+ // We wrap the message callback to be sure we only propagate the message if it is for the right channel.
152
171
  const onMessage = (evt) => {
153
172
  let data = {};
154
173
  try {
@@ -170,13 +189,7 @@ class WebSocketAPI {
170
189
  }
171
190
  });
172
191
  };
173
- if (this.websocket) {
174
- this.websocket.addEventListener('message', onMessage);
175
- if (errorCb) {
176
- this.websocket.addEventListener('error', errorCb);
177
- this.websocket.addEventListener('close', errorCb);
178
- }
179
- }
192
+ this.addEvents(onMessage, errorCb);
180
193
  return { onMessageCb: onMessage, onErrorCb: errorCb };
181
194
  }
182
195
  /**
@@ -187,33 +200,52 @@ class WebSocketAPI {
187
200
  * @private
188
201
  */
189
202
  unlisten(params, cb) {
190
- if (!this.websocket) {
191
- return;
192
- }
193
- this.subscriptions
203
+ [...(this.subscriptions || []), ...(this.requests || [])]
194
204
  .filter((s) => s.params.channel === params.channel && (!cb || s.cb === cb))
195
205
  .forEach(({ onMessageCb, onErrorCb }) => {
196
- if (this.websocket) {
197
- this.websocket.removeEventListener('message', onMessageCb);
198
- if (onErrorCb) {
199
- this.websocket.removeEventListener('error', onErrorCb);
200
- this.websocket.removeEventListener('close', onErrorCb);
201
- }
202
- }
206
+ this.removeEvents(onMessageCb, onErrorCb);
203
207
  });
204
208
  }
205
209
  /**
206
210
  * Sends a get request to the websocket.
211
+ * The callback is called only once, when the response is received or when the call returns an error.
207
212
  *
208
213
  * @param {Object} params Parameters for the websocket get request
209
- * @param {function} cb callback on listen
210
- * @param {function} errorCb Callback on error
214
+ * @param {function} onMessage callback on message event
215
+ * @param {function} onError Callback on error and close event
211
216
  * @private
212
217
  */
213
218
  get(params, cb, errorCb) {
214
- const reqStr = WebSocketAPI.getRequestString('GET', params);
215
- this.send(reqStr);
216
- this.listen(params, cb, errorCb);
219
+ const requestString = WebSocketAPI.getRequestString('GET', params);
220
+ this.send(requestString);
221
+ // We wrap the callbacks to make sure they are called only once.
222
+ const once = (callback) => (...args) => {
223
+ callback(...args);
224
+ const index = this.requests.findIndex((request) => requestString === request.requestString && cb === request.cb);
225
+ const { onMessageCb, onErrorCb } = this.requests[index];
226
+ this.removeEvents(onMessageCb, onErrorCb);
227
+ this.requests.splice(index, 1);
228
+ };
229
+ const { onMessageCb, onErrorCb } = this.listen(params, once(cb), once(errorCb));
230
+ // Store requests and callbacks to be able to remove them.
231
+ if (!this.requests) {
232
+ this.requests = [];
233
+ }
234
+ const index = this.requests.findIndex((request) => requestString === request.requestString && cb === request.cb);
235
+ const newReq = {
236
+ params,
237
+ requestString,
238
+ cb,
239
+ errorCb,
240
+ onMessageCb,
241
+ onErrorCb,
242
+ };
243
+ if (index > -1) {
244
+ this.requests[index] = newReq;
245
+ }
246
+ else {
247
+ this.requests.push(newReq);
248
+ }
217
249
  }
218
250
  /**
219
251
  * Subscribe to a given channel.
@@ -252,13 +284,7 @@ class WebSocketAPI {
252
284
  unsubscribe(source, cb) {
253
285
  const toRemove = this.subscriptions.filter((s) => s.params.channel === source && (!cb || s.cb === cb));
254
286
  toRemove.forEach(({ onMessageCb, onErrorCb }) => {
255
- if (this.websocket) {
256
- this.websocket.removeEventListener('message', onMessageCb);
257
- if (onErrorCb) {
258
- this.websocket.removeEventListener('error', onErrorCb);
259
- this.websocket.removeEventListener('close', onErrorCb);
260
- }
261
- }
287
+ this.removeEvents(onMessageCb, onErrorCb);
262
288
  });
263
289
  this.subscriptions = this.subscriptions.filter((s) => s.params.channel !== source || (cb && s.cb !== cb));
264
290
  // If there is no more subscriptions to this channel, and the removed subscriptions didn't register quietly,
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=WebSocketAPI.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketAPI.test.d.ts","sourceRoot":"","sources":["../../../src/common/api/WebSocketAPI.test.js"],"names":[],"mappings":""}