rocket-launch-live-client 0.2.0 → 0.3.0
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.
- package/README.md +182 -1
- package/lib/cjs/Client.js +36 -16
- package/lib/cjs/Watcher.js +171 -0
- package/lib/cjs/fetcher.js +18 -10
- package/lib/cjs/index.js +3 -1
- package/lib/cjs/types/Client.d.ts +19 -7
- package/lib/cjs/types/Client.d.ts.map +1 -1
- package/lib/cjs/types/Watcher.d.ts +92 -0
- package/lib/cjs/types/Watcher.d.ts.map +1 -0
- package/lib/cjs/types/fetcher.d.ts.map +1 -1
- package/lib/cjs/types/index.d.ts +2 -1
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/types/application.d.ts +33 -14
- package/lib/cjs/types/types/application.d.ts.map +1 -1
- package/lib/cjs/types/utils.d.ts +3 -2
- package/lib/cjs/types/utils.d.ts.map +1 -1
- package/lib/cjs/utils.js +101 -103
- package/lib/esm/Client.js +36 -16
- package/lib/esm/Watcher.js +169 -0
- package/lib/esm/fetcher.js +17 -10
- package/lib/esm/index.mjs +1 -0
- package/lib/esm/types/Client.d.ts +19 -7
- package/lib/esm/types/Client.d.ts.map +1 -1
- package/lib/esm/types/Watcher.d.ts +92 -0
- package/lib/esm/types/Watcher.d.ts.map +1 -0
- package/lib/esm/types/fetcher.d.ts.map +1 -1
- package/lib/esm/types/index.d.ts +2 -1
- package/lib/esm/types/index.d.ts.map +1 -1
- package/lib/esm/types/types/application.d.ts +33 -14
- package/lib/esm/types/types/application.d.ts.map +1 -1
- package/lib/esm/types/utils.d.ts +3 -2
- package/lib/esm/types/utils.d.ts.map +1 -1
- package/lib/esm/utils.js +99 -102
- package/package.json +1 -4
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
- [Pads](#pads)
|
|
14
14
|
- [Tags](#tags)
|
|
15
15
|
- [Vehicles](#vehicles)
|
|
16
|
+
- [Watcher](#watcher)
|
|
17
|
+
- [Methods and Properties](#watcher_props)
|
|
18
|
+
- [Options](#watcher_options)
|
|
19
|
+
- [Events](#watcher_events)
|
|
16
20
|
|
|
17
21
|
This package is a fully-typed, promise-based, zero-dependency Node.JS JavaScript/TypeScript library for interacting with the [RocketLaunch.Live](https://www.rocketlaunch.live) API.
|
|
18
22
|
|
|
@@ -24,7 +28,7 @@ This package is a fully-typed, promise-based, zero-dependency Node.JS JavaScript
|
|
|
24
28
|
// Import package
|
|
25
29
|
import { rllc } from "rocket-launch-live-client";
|
|
26
30
|
|
|
27
|
-
// Get API Key
|
|
31
|
+
// Get API Your Key
|
|
28
32
|
const RLL_API_KEY = process.env.RLL_API_KEY;
|
|
29
33
|
|
|
30
34
|
// Create client
|
|
@@ -307,3 +311,180 @@ const options = {
|
|
|
307
311
|
name: "Atlas V",
|
|
308
312
|
};
|
|
309
313
|
```
|
|
314
|
+
|
|
315
|
+
<a name="watcher"></a>
|
|
316
|
+
|
|
317
|
+
## Watcher
|
|
318
|
+
|
|
319
|
+
The `rocket-launch-live-client` has the ability to monitor the `launches` endpoint on a regular basis and return changes as they happen live.
|
|
320
|
+
|
|
321
|
+
```js
|
|
322
|
+
// Instantiate a new watcher
|
|
323
|
+
// See below for options
|
|
324
|
+
const watcher = client.watch(5, options);
|
|
325
|
+
|
|
326
|
+
// Define event handlers
|
|
327
|
+
watcher.on("new", (newLaunch) => {
|
|
328
|
+
// handle new launch
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Start monitoring
|
|
332
|
+
watcher.start();
|
|
333
|
+
|
|
334
|
+
// Stop monitoring
|
|
335
|
+
watcher.stop();
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
<a name="watcher_props"></a>
|
|
339
|
+
|
|
340
|
+
<a name="watcher_options"></a>
|
|
341
|
+
|
|
342
|
+
### Watcher Options
|
|
343
|
+
|
|
344
|
+
A new watcher takes up to two arguments:
|
|
345
|
+
|
|
346
|
+
1. Interval - (optional) (default: 5) - a duration, in minutes, between calls to the API. Adjust this based on the frequency you wish to stay up to date. To avoid needlessly querying the API, this client will now allow any option less than 1 minute.
|
|
347
|
+
2. Query Options - (optional) - The exact same query options that can be submitted to the [`launches`](#launches) endpoint.
|
|
348
|
+
|
|
349
|
+
Query options cannot be altered on a running watcher. In order to change your search conditions, you'll need to stop the watcher and start a new one.
|
|
350
|
+
|
|
351
|
+
### Watcher Methods and Properties
|
|
352
|
+
|
|
353
|
+
#### Start
|
|
354
|
+
|
|
355
|
+
Begin watching the `launches` endpoint using the interval and query options provided during watcher instantiation.
|
|
356
|
+
|
|
357
|
+
```js
|
|
358
|
+
watcher.start();
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
#### End
|
|
362
|
+
|
|
363
|
+
Stop watching the `launches` endpoint.
|
|
364
|
+
|
|
365
|
+
```js
|
|
366
|
+
watcher.stop();
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### On
|
|
370
|
+
|
|
371
|
+
Set an event handler for a Watcher event. Extends the Node Event Emitter `on` method. Takes an event name (see below) and a callback.
|
|
372
|
+
|
|
373
|
+
```js
|
|
374
|
+
watcher.on("ready", (launches) => {
|
|
375
|
+
// handle event
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
#### Launches Data
|
|
380
|
+
|
|
381
|
+
Access the launches data cache. The data is stored in a [JavaScript Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and has all the methods associated with Maps.
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
watcher.launches; // Map of all launches in cache
|
|
385
|
+
watcher.launches.size // Count of launches in cache
|
|
386
|
+
watcher.launches.get(1) // Get launch with launch_id of 1
|
|
387
|
+
watcher.launches.forEach((launch, launchId) => /* Do something to each launch */ )
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Note: We recommend not altering the `launches` cache directly (such as by using Map's `set` or `delete` methods). The watcher will notice the discrepancy on the next API call and trigger appropriate `new` or `change` events to set it back. This may not be the behaviour you expect.
|
|
391
|
+
|
|
392
|
+
<a name="watcher_events"></a>
|
|
393
|
+
|
|
394
|
+
### Watcher Events
|
|
395
|
+
|
|
396
|
+
Watcher events are triggered when the client recieves a response to a query to `launches` using the `modified_since` parameter. The client will compare the changes to a cached version of the launch and trigger the appropriate event.
|
|
397
|
+
|
|
398
|
+
If there are multiple changes on a single API call, the appropriate events will be triggered more than once, so have your callbacks handle a single event.
|
|
399
|
+
|
|
400
|
+
<a name="watcher_events_new"></a>
|
|
401
|
+
|
|
402
|
+
#### New
|
|
403
|
+
|
|
404
|
+
A new launch has been added! The Watcher will provide the new launch data as the first argument to your callback.
|
|
405
|
+
|
|
406
|
+
```js
|
|
407
|
+
watcher.on("new", (newLaunch) => {
|
|
408
|
+
// Handle the new addition here
|
|
409
|
+
});
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
The `newLaunch` argument will be an `RLLEntity.Launch` object, the same shape as what is received from the `launches` endpoint (but not wrapped in the standard response).
|
|
413
|
+
|
|
414
|
+
<a name="watcher_events_change"></a>
|
|
415
|
+
|
|
416
|
+
#### Change
|
|
417
|
+
|
|
418
|
+
An existing launch has had information change. The Watcher will provide the old and new versions of the launch object to do your own comparisons.
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
watcher.on("change", (oldLaunch, newLaunch) => {
|
|
422
|
+
// Handle changes here
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
The `oldLaunch` and `newLaunch` will be the cached version and the new version of an `RLLEntity.Launch` object, the same shape as what is received from the `launches` endpoint (but not wrapped in the standard response).
|
|
427
|
+
|
|
428
|
+
<a name="watcher_events_error"></a>
|
|
429
|
+
|
|
430
|
+
#### Error
|
|
431
|
+
|
|
432
|
+
There was an error on an API call. The error will be passed as the first argument of the callback.
|
|
433
|
+
|
|
434
|
+
```js
|
|
435
|
+
watcher.on("error", (err) => {
|
|
436
|
+
// Handle error here
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
The `err` object will have the following shape, and is accessible via TypeScript as `RLLError`:
|
|
441
|
+
|
|
442
|
+
```js
|
|
443
|
+
const err = {
|
|
444
|
+
error: "Error title";
|
|
445
|
+
statusCode: 404; // HTTP status code or null if no response
|
|
446
|
+
message: "Could not find this resource"; // Custom error string from RLLC
|
|
447
|
+
server_response: { } // error passed through from server, can be null if no response
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### Ready
|
|
452
|
+
|
|
453
|
+
The watcher has completed its initial API calls and built a cache of launches. The initial cache of launches is passed as the first argument. The client is now monitoring the API.
|
|
454
|
+
|
|
455
|
+
```js
|
|
456
|
+
watcher.on("ready", (launches) => {
|
|
457
|
+
// Handle ready here
|
|
458
|
+
});
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### Initialization Errors
|
|
462
|
+
|
|
463
|
+
The watcher has experienced a problem setting up its initial cache and is has not started monitoring.
|
|
464
|
+
|
|
465
|
+
```js
|
|
466
|
+
watcher.on("init_error", (err) => {
|
|
467
|
+
// Handle error here
|
|
468
|
+
});
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
The `err` object will have the following shape, and is accessible via TypeScript as `RLLError`:
|
|
472
|
+
|
|
473
|
+
```js
|
|
474
|
+
const err = {
|
|
475
|
+
error: "Error title";
|
|
476
|
+
statusCode: 404; // HTTP status code or null if no response
|
|
477
|
+
message: "Could not find this resource"; // Custom error string from RLLC
|
|
478
|
+
server_response: { } // error passed through from server, can be null if no response
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
#### Call
|
|
483
|
+
|
|
484
|
+
The watcher also emits a `call` event every time it makes a request, passing in the query parameters it used in the Node URLSearchParams format. Use this to monitor or diagnose how often the API is being queried.
|
|
485
|
+
|
|
486
|
+
```js
|
|
487
|
+
watcher.on("call", (params) => {
|
|
488
|
+
// Handle call here
|
|
489
|
+
});
|
|
490
|
+
```
|
package/lib/cjs/Client.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.RLLClient = void 0;
|
|
|
4
4
|
const application_1 = require("./types/application");
|
|
5
5
|
const fetcher_1 = require("./fetcher");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
|
+
const Watcher_1 = require("./Watcher");
|
|
7
8
|
/**
|
|
8
9
|
* Class representing a RocketLaunch.Live client
|
|
9
10
|
* @class
|
|
@@ -23,8 +24,7 @@ class RLLClient {
|
|
|
23
24
|
};
|
|
24
25
|
// Validate API Key is a valid UUID format
|
|
25
26
|
// Constructor throws if not
|
|
26
|
-
(0, utils_1.apiKeyValidator)(apiKey);
|
|
27
|
-
this.apiKey = apiKey;
|
|
27
|
+
this.apiKey = (0, utils_1.apiKeyValidator)(apiKey);
|
|
28
28
|
if (!options) {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
@@ -49,6 +49,19 @@ class RLLClient {
|
|
|
49
49
|
query(endpoint, params) {
|
|
50
50
|
return (0, fetcher_1.fetcher)(this.apiKey, endpoint, params, this.config.keyInQueryParams);
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Instantiate a new RLL Watcher which will continually query the API for changes to the launches endpoint
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*
|
|
57
|
+
* @param {number} interval - Interval in minutes to query the API for changes. Defaults to 5 minutes, cannot be less than 1 minute
|
|
58
|
+
* @param {RLLQueryConfig.Launches} options - Query options, same as calling the launches method
|
|
59
|
+
*
|
|
60
|
+
* @returns {RLLWatcher}
|
|
61
|
+
*/
|
|
62
|
+
watch(interval, options) {
|
|
63
|
+
return new Watcher_1.RLLWatcher((params) => this.query(application_1.RLLEndPoint.LAUNCHES, params), interval, options);
|
|
64
|
+
}
|
|
52
65
|
/**
|
|
53
66
|
* Fetch launch companies
|
|
54
67
|
*
|
|
@@ -66,10 +79,11 @@ class RLLClient {
|
|
|
66
79
|
*
|
|
67
80
|
* @example
|
|
68
81
|
*
|
|
69
|
-
* const response = client.companies({ country_code: "US" })
|
|
82
|
+
* const response = await client.companies({ country_code: "US" })
|
|
70
83
|
*/
|
|
71
84
|
companies(options) {
|
|
72
|
-
|
|
85
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.COMPANIES, options);
|
|
86
|
+
return this.query(application_1.RLLEndPoint.COMPANIES, params);
|
|
73
87
|
}
|
|
74
88
|
/**
|
|
75
89
|
* Fetch launches
|
|
@@ -98,10 +112,11 @@ class RLLClient {
|
|
|
98
112
|
*
|
|
99
113
|
* @example
|
|
100
114
|
*
|
|
101
|
-
* const response = client.launches({ after_date: new Date("2022-10-10") })
|
|
115
|
+
* const response = await client.launches({ after_date: new Date("2022-10-10") })
|
|
102
116
|
*/
|
|
103
117
|
launches(options) {
|
|
104
|
-
|
|
118
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.LAUNCHES, options);
|
|
119
|
+
return this.query(application_1.RLLEndPoint.LAUNCHES, params);
|
|
105
120
|
}
|
|
106
121
|
/**
|
|
107
122
|
* Fetch launch locations
|
|
@@ -120,10 +135,11 @@ class RLLClient {
|
|
|
120
135
|
*
|
|
121
136
|
* @example
|
|
122
137
|
*
|
|
123
|
-
* const response = client.locations({ country_code: "US" })
|
|
138
|
+
* const response = await client.locations({ country_code: "US" })
|
|
124
139
|
*/
|
|
125
140
|
locations(options) {
|
|
126
|
-
|
|
141
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.LOCATIONS, options);
|
|
142
|
+
return this.query(application_1.RLLEndPoint.LOCATIONS, params);
|
|
127
143
|
}
|
|
128
144
|
/**
|
|
129
145
|
* Fetch launch Missions
|
|
@@ -140,10 +156,11 @@ class RLLClient {
|
|
|
140
156
|
*
|
|
141
157
|
* @example
|
|
142
158
|
*
|
|
143
|
-
* const response = client.missions({ name: "Mars 2020" })
|
|
159
|
+
* const response = await client.missions({ name: "Mars 2020" })
|
|
144
160
|
*/
|
|
145
161
|
missions(options) {
|
|
146
|
-
|
|
162
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.MISSIONS, options);
|
|
163
|
+
return this.query(application_1.RLLEndPoint.MISSIONS, params);
|
|
147
164
|
}
|
|
148
165
|
/**
|
|
149
166
|
* Fetch launch pads
|
|
@@ -162,10 +179,11 @@ class RLLClient {
|
|
|
162
179
|
*
|
|
163
180
|
* @example
|
|
164
181
|
*
|
|
165
|
-
* const response = client.pads({ country_code: "US" })
|
|
182
|
+
* const response = await client.pads({ country_code: "US" })
|
|
166
183
|
*/
|
|
167
184
|
pads(options) {
|
|
168
|
-
|
|
185
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.PADS, options);
|
|
186
|
+
return this.query(application_1.RLLEndPoint.PADS, params);
|
|
169
187
|
}
|
|
170
188
|
/**
|
|
171
189
|
* Fetch launch tags
|
|
@@ -182,10 +200,11 @@ class RLLClient {
|
|
|
182
200
|
*
|
|
183
201
|
* @example
|
|
184
202
|
*
|
|
185
|
-
* const response = client.tags({ text: "Crewed" })
|
|
203
|
+
* const response = await client.tags({ text: "Crewed" })
|
|
186
204
|
*/
|
|
187
205
|
tags(options) {
|
|
188
|
-
|
|
206
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.TAGS, options);
|
|
207
|
+
return this.query(application_1.RLLEndPoint.TAGS, params);
|
|
189
208
|
}
|
|
190
209
|
/**
|
|
191
210
|
* Fetch launch Vehicles
|
|
@@ -202,10 +221,11 @@ class RLLClient {
|
|
|
202
221
|
*
|
|
203
222
|
* @example
|
|
204
223
|
*
|
|
205
|
-
* const response = client.vehicles({ name: "Falcon 9" })
|
|
224
|
+
* const response = await client.vehicles({ name: "Falcon 9" })
|
|
206
225
|
*/
|
|
207
226
|
vehicles(options) {
|
|
208
|
-
|
|
227
|
+
const params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.VEHICLES, options);
|
|
228
|
+
return this.query(application_1.RLLEndPoint.VEHICLES, params);
|
|
209
229
|
}
|
|
210
230
|
}
|
|
211
231
|
exports.RLLClient = RLLClient;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RLLWatcher = void 0;
|
|
7
|
+
const events_1 = __importDefault(require("events"));
|
|
8
|
+
const application_1 = require("./types/application");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
const DEFAULT_INTERVAL_IN_MINS = 5;
|
|
11
|
+
const MS_IN_MIN = 60000;
|
|
12
|
+
const intervalValidator = (interval) => {
|
|
13
|
+
if (typeof interval !== "number" && typeof interval !== "string") {
|
|
14
|
+
(0, utils_1.error)("RLLWatcher interval must be a number.");
|
|
15
|
+
return DEFAULT_INTERVAL_IN_MINS;
|
|
16
|
+
}
|
|
17
|
+
if (typeof interval === "string" &&
|
|
18
|
+
(isNaN(Number(interval)) || interval === "")) {
|
|
19
|
+
(0, utils_1.error)("RLLWatcher interval must be a number.", "type");
|
|
20
|
+
return DEFAULT_INTERVAL_IN_MINS;
|
|
21
|
+
}
|
|
22
|
+
const typedInterval = Number(interval);
|
|
23
|
+
if (typedInterval <= 0) {
|
|
24
|
+
(0, utils_1.error)("RLLWatcher interval cannot be a negative number or zero. Watcher intervals should be greater than or equal to 1 minute.");
|
|
25
|
+
return DEFAULT_INTERVAL_IN_MINS;
|
|
26
|
+
}
|
|
27
|
+
if (typedInterval < 1) {
|
|
28
|
+
(0, utils_1.warn)("RLLWatcher does not accept intervals less than 1. Your watcher will default to 5 minute intervals unless corrected.");
|
|
29
|
+
return DEFAULT_INTERVAL_IN_MINS;
|
|
30
|
+
}
|
|
31
|
+
return typedInterval;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Class representing a RocketLaunch.Live Client Watcher
|
|
35
|
+
* @class
|
|
36
|
+
*/
|
|
37
|
+
class RLLWatcher extends events_1.default {
|
|
38
|
+
/**
|
|
39
|
+
* Create a new RocketLaunch.live Client Watcher
|
|
40
|
+
*
|
|
41
|
+
* @param {function(params: URLSearchParams): Promise<RLLResponse<RLLEntity.Launch[]>>} fetcher - fetcher function to make API calls
|
|
42
|
+
* @param {number | string} [interval] - Optional Client Configuration options
|
|
43
|
+
* @param {Object} [options] - Launch Search Options
|
|
44
|
+
* @param {number | string} options.id - Launch id
|
|
45
|
+
* @param {number | string} options.page - Page number of results
|
|
46
|
+
* @param {string} options.cospar_id - Launch COSPAR ID (ie. 2022-123)
|
|
47
|
+
* @param {Date | string} options.before_date - Only return launches before this date
|
|
48
|
+
* @param {Date | string} options.after_date - Only return launches after this date
|
|
49
|
+
* @param {Date | string} options.modified_since - Only return launches with API changes after this date
|
|
50
|
+
* @param {number | string} options.location_id - Launches from this Location
|
|
51
|
+
* @param {number | string} options.pad_id - Launches from this Pad
|
|
52
|
+
* @param {number | string} options.provider_id - Launches from this Company
|
|
53
|
+
* @param {number | string} options.tag_id - Launches with this Tag
|
|
54
|
+
* @param {number | string} options.vehicle_id - Launches on this Vehicle
|
|
55
|
+
* @param {ISO3166Alpha2.StateCodeUS} options.state_abbr - ISO 3166 Alpha 2 US State Code
|
|
56
|
+
* @param {ISO3166Alpha2.CountryCode} options.country_code - ISO 3166 Alpha 2 Country Code
|
|
57
|
+
* @param {number | string} options.search - Launches matching this search string
|
|
58
|
+
* @param {number | string} options.slug - Launches matching this unique slug
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
constructor(fetcher, interval = DEFAULT_INTERVAL_IN_MINS, options) {
|
|
62
|
+
super();
|
|
63
|
+
this._untypedOn = this.on;
|
|
64
|
+
this._untypedEmit = this.emit;
|
|
65
|
+
this.on = (event, listener) => this._untypedOn(event, listener);
|
|
66
|
+
this.emit = (event, ...args) => this._untypedEmit(event, ...args);
|
|
67
|
+
this.launches = new Map();
|
|
68
|
+
/**
|
|
69
|
+
* Recursive API Caller to iterate through pages
|
|
70
|
+
*
|
|
71
|
+
* @private
|
|
72
|
+
* @function
|
|
73
|
+
*
|
|
74
|
+
* @param {URLSearchParams} params - Search parameters
|
|
75
|
+
* @param {function(results: RLLResponse<RLLEntity.Launch[]>)} callback - To execute on each page
|
|
76
|
+
*
|
|
77
|
+
* @returns {Promise<void>}
|
|
78
|
+
*/
|
|
79
|
+
this.recursivelyFetch = (params, callback) => {
|
|
80
|
+
let page = 1;
|
|
81
|
+
const recursiveFetcher = () => {
|
|
82
|
+
this.emit("call", params);
|
|
83
|
+
return this.fetcher(params).then((results) => {
|
|
84
|
+
callback(results);
|
|
85
|
+
if (results.last_page > page) {
|
|
86
|
+
page++;
|
|
87
|
+
params.set("page", page.toString());
|
|
88
|
+
return recursiveFetcher();
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
return recursiveFetcher();
|
|
94
|
+
};
|
|
95
|
+
this.last_call = new Date();
|
|
96
|
+
this.fetcher = fetcher;
|
|
97
|
+
this.interval = intervalValidator(interval);
|
|
98
|
+
this.params = (0, utils_1.queryOptionsValidator)(application_1.RLLEndPoint.LAUNCHES, options);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Query wrapper to trigger events
|
|
102
|
+
*
|
|
103
|
+
* @private
|
|
104
|
+
* @function
|
|
105
|
+
*
|
|
106
|
+
* @returns {void}
|
|
107
|
+
*/
|
|
108
|
+
query() {
|
|
109
|
+
const notify = (response) => {
|
|
110
|
+
for (const changedLaunch of response.result) {
|
|
111
|
+
const { id } = changedLaunch;
|
|
112
|
+
const oldLaunch = this.launches.get(id);
|
|
113
|
+
if (oldLaunch) {
|
|
114
|
+
this.emit("change", oldLaunch, changedLaunch);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.emit("new", changedLaunch);
|
|
118
|
+
}
|
|
119
|
+
this.launches.set(changedLaunch.id, changedLaunch);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
this.params.set("modified_since", (0, utils_1.formatToRLLISODate)(this.last_call));
|
|
123
|
+
this.recursivelyFetch(new URLSearchParams(this.params), notify)
|
|
124
|
+
.then(() => {
|
|
125
|
+
this.last_call = new Date();
|
|
126
|
+
})
|
|
127
|
+
.catch((err) => {
|
|
128
|
+
this.emit("error", err);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Begin monitoring API using the configured query parameters.
|
|
133
|
+
*
|
|
134
|
+
* @public
|
|
135
|
+
* @function
|
|
136
|
+
*
|
|
137
|
+
* @returns {void}
|
|
138
|
+
*/
|
|
139
|
+
start() {
|
|
140
|
+
const buildCache = (response) => {
|
|
141
|
+
for (const launch of response.result) {
|
|
142
|
+
this.launches.set(launch.id, launch);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
this.recursivelyFetch(new URLSearchParams(this.params), buildCache)
|
|
146
|
+
.then(() => {
|
|
147
|
+
this.emit("ready", this.launches);
|
|
148
|
+
this.last_call = new Date();
|
|
149
|
+
this.timer = setInterval(() => {
|
|
150
|
+
this.query();
|
|
151
|
+
}, this.interval * MS_IN_MIN);
|
|
152
|
+
})
|
|
153
|
+
.catch((err) => {
|
|
154
|
+
this.emit("init_error", err);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Stop monitoring API
|
|
159
|
+
*
|
|
160
|
+
* @public
|
|
161
|
+
* @function
|
|
162
|
+
*
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
165
|
+
stop() {
|
|
166
|
+
if (this.timer) {
|
|
167
|
+
clearInterval(this.timer);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.RLLWatcher = RLLWatcher;
|
package/lib/cjs/fetcher.js
CHANGED
|
@@ -25,22 +25,30 @@ const query = (url, headers) => {
|
|
|
25
25
|
let data = [];
|
|
26
26
|
res.on("data", (chunk) => data.push(chunk));
|
|
27
27
|
res.on("end", () => {
|
|
28
|
+
var _a;
|
|
29
|
+
const response = Buffer.concat(data).toString();
|
|
28
30
|
if (res.statusCode === 200) {
|
|
29
|
-
const response = Buffer.concat(data).toString();
|
|
30
31
|
resolve(JSON.parse(response));
|
|
31
32
|
}
|
|
32
|
-
else if (res.statusCode === 404) {
|
|
33
|
-
reject({
|
|
34
|
-
error: "Resource not found",
|
|
35
|
-
statusCode: 404,
|
|
36
|
-
message: "The server returned a 404 Not Found response. Check that your API key is valid, and that you are not requesting a page number beyond the available results.",
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
33
|
else {
|
|
40
|
-
|
|
34
|
+
const error = {
|
|
35
|
+
error: "API Call Failed",
|
|
36
|
+
statusCode: (_a = res.statusCode) !== null && _a !== void 0 ? _a : null,
|
|
37
|
+
message: "RLLC recieved a response from the server but it did not complete as expected.",
|
|
38
|
+
server_response: JSON.parse(response),
|
|
39
|
+
};
|
|
40
|
+
reject(error);
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
|
-
req.on("error",
|
|
44
|
+
req.on("error", () => {
|
|
45
|
+
const error = {
|
|
46
|
+
error: "Unknown error",
|
|
47
|
+
statusCode: null,
|
|
48
|
+
message: "RLLC recieved an unknown error. This usually means that the HTTP request did not complete",
|
|
49
|
+
server_response: null,
|
|
50
|
+
};
|
|
51
|
+
reject(error);
|
|
52
|
+
});
|
|
45
53
|
});
|
|
46
54
|
};
|
package/lib/cjs/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rllc = exports.RLLClient = exports.RLLEntity = exports.RLLEndPoint = void 0;
|
|
3
|
+
exports.rllc = exports.RLLWatcher = exports.RLLClient = exports.RLLEntity = exports.RLLEndPoint = void 0;
|
|
4
4
|
const Client_1 = require("./Client");
|
|
5
5
|
var application_1 = require("./types/application");
|
|
6
6
|
Object.defineProperty(exports, "RLLEndPoint", { enumerable: true, get: function () { return application_1.RLLEndPoint; } });
|
|
7
7
|
Object.defineProperty(exports, "RLLEntity", { enumerable: true, get: function () { return application_1.RLLEntity; } });
|
|
8
8
|
var Client_2 = require("./Client");
|
|
9
9
|
Object.defineProperty(exports, "RLLClient", { enumerable: true, get: function () { return Client_2.RLLClient; } });
|
|
10
|
+
var Watcher_1 = require("./Watcher");
|
|
11
|
+
Object.defineProperty(exports, "RLLWatcher", { enumerable: true, get: function () { return Watcher_1.RLLWatcher; } });
|
|
10
12
|
/**
|
|
11
13
|
* Generate a RocketLaunch.Live client
|
|
12
14
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RLLClientOptions, RLLEntity, RLLQueryConfig, RLLResponse } from "./types/application";
|
|
2
|
+
import { RLLWatcher } from "./Watcher";
|
|
2
3
|
/**
|
|
3
4
|
* Class representing a RocketLaunch.Live client
|
|
4
5
|
* @class
|
|
@@ -28,6 +29,17 @@ export declare class RLLClient {
|
|
|
28
29
|
* @returns {Promise<T>}
|
|
29
30
|
*/
|
|
30
31
|
private query;
|
|
32
|
+
/**
|
|
33
|
+
* Instantiate a new RLL Watcher which will continually query the API for changes to the launches endpoint
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*
|
|
37
|
+
* @param {number} interval - Interval in minutes to query the API for changes. Defaults to 5 minutes, cannot be less than 1 minute
|
|
38
|
+
* @param {RLLQueryConfig.Launches} options - Query options, same as calling the launches method
|
|
39
|
+
*
|
|
40
|
+
* @returns {RLLWatcher}
|
|
41
|
+
*/
|
|
42
|
+
watch(interval?: number | string, options?: RLLQueryConfig.Launches): RLLWatcher;
|
|
31
43
|
/**
|
|
32
44
|
* Fetch launch companies
|
|
33
45
|
*
|
|
@@ -45,7 +57,7 @@ export declare class RLLClient {
|
|
|
45
57
|
*
|
|
46
58
|
* @example
|
|
47
59
|
*
|
|
48
|
-
* const response = client.companies({ country_code: "US" })
|
|
60
|
+
* const response = await client.companies({ country_code: "US" })
|
|
49
61
|
*/
|
|
50
62
|
companies(options?: RLLQueryConfig.Companies): Promise<RLLResponse<RLLEntity.Company[]>>;
|
|
51
63
|
/**
|
|
@@ -75,7 +87,7 @@ export declare class RLLClient {
|
|
|
75
87
|
*
|
|
76
88
|
* @example
|
|
77
89
|
*
|
|
78
|
-
* const response = client.launches({ after_date: new Date("2022-10-10") })
|
|
90
|
+
* const response = await client.launches({ after_date: new Date("2022-10-10") })
|
|
79
91
|
*/
|
|
80
92
|
launches(options?: RLLQueryConfig.Launches): Promise<RLLResponse<RLLEntity.Launch[]>>;
|
|
81
93
|
/**
|
|
@@ -95,7 +107,7 @@ export declare class RLLClient {
|
|
|
95
107
|
*
|
|
96
108
|
* @example
|
|
97
109
|
*
|
|
98
|
-
* const response = client.locations({ country_code: "US" })
|
|
110
|
+
* const response = await client.locations({ country_code: "US" })
|
|
99
111
|
*/
|
|
100
112
|
locations(options?: RLLQueryConfig.Locations): Promise<RLLResponse<RLLEntity.Location[]>>;
|
|
101
113
|
/**
|
|
@@ -113,7 +125,7 @@ export declare class RLLClient {
|
|
|
113
125
|
*
|
|
114
126
|
* @example
|
|
115
127
|
*
|
|
116
|
-
* const response = client.missions({ name: "Mars 2020" })
|
|
128
|
+
* const response = await client.missions({ name: "Mars 2020" })
|
|
117
129
|
*/
|
|
118
130
|
missions(options?: RLLQueryConfig.Missions): Promise<RLLResponse<RLLEntity.Mission[]>>;
|
|
119
131
|
/**
|
|
@@ -133,7 +145,7 @@ export declare class RLLClient {
|
|
|
133
145
|
*
|
|
134
146
|
* @example
|
|
135
147
|
*
|
|
136
|
-
* const response = client.pads({ country_code: "US" })
|
|
148
|
+
* const response = await client.pads({ country_code: "US" })
|
|
137
149
|
*/
|
|
138
150
|
pads(options?: RLLQueryConfig.Pads): Promise<RLLResponse<RLLEntity.Pad[]>>;
|
|
139
151
|
/**
|
|
@@ -151,7 +163,7 @@ export declare class RLLClient {
|
|
|
151
163
|
*
|
|
152
164
|
* @example
|
|
153
165
|
*
|
|
154
|
-
* const response = client.tags({ text: "Crewed" })
|
|
166
|
+
* const response = await client.tags({ text: "Crewed" })
|
|
155
167
|
*/
|
|
156
168
|
tags(options?: RLLQueryConfig.Tags): Promise<RLLResponse<RLLEntity.Tag[]>>;
|
|
157
169
|
/**
|
|
@@ -169,7 +181,7 @@ export declare class RLLClient {
|
|
|
169
181
|
*
|
|
170
182
|
* @example
|
|
171
183
|
*
|
|
172
|
-
* const response = client.vehicles({ name: "Falcon 9" })
|
|
184
|
+
* const response = await client.vehicles({ name: "Falcon 9" })
|
|
173
185
|
*/
|
|
174
186
|
vehicles(options?: RLLQueryConfig.Vehicles): Promise<RLLResponse<RLLEntity.Vehicle[]>>;
|
|
175
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../../../src/Client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,SAAS,EACT,cAAc,EACd,WAAW,EACZ,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../../../src/Client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,SAAS,EACT,cAAc,EACd,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAEZ;IAEF;;;;;;;OAOG;gBACS,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAiBtD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,KAAK;IASb;;;;;;;;;OASG;IACI,KAAK,CACV,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAC1B,OAAO,CAAC,EAAE,cAAc,CAAC,QAAQ,GAChC,UAAU;IAYb;;;;;;;;;;;;;;;;;;OAkBG;IACI,SAAS,CACd,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,GACjC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IAQ5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACI,QAAQ,CACb,OAAO,CAAC,EAAE,cAAc,CAAC,QAAQ,GAChC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAQ3C;;;;;;;;;;;;;;;;;;OAkBG;IACI,SAAS,CACd,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,GACjC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IAQ7C;;;;;;;;;;;;;;;;OAgBG;IACI,QAAQ,CACb,OAAO,CAAC,EAAE,cAAc,CAAC,QAAQ,GAChC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IAQ5C;;;;;;;;;;;;;;;;;;OAkBG;IACI,IAAI,CACT,OAAO,CAAC,EAAE,cAAc,CAAC,IAAI,GAC5B,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;IAKxC;;;;;;;;;;;;;;;;OAgBG;IACI,IAAI,CACT,OAAO,CAAC,EAAE,cAAc,CAAC,IAAI,GAC5B,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;IAKxC;;;;;;;;;;;;;;;;OAgBG;IACI,QAAQ,CACb,OAAO,CAAC,EAAE,cAAc,CAAC,QAAQ,GAChC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;CAO7C"}
|