@skipruntime/helpers 0.0.12 → 0.0.13

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.
@@ -1,46 +1,4 @@
1
1
  import type { Entry, ExternalService, Json } from "@skipruntime/core";
2
- /**
3
- * Interface required by `GenericExternalService` for external resources.
4
- */
5
- export interface ExternalResource {
6
- open(instance: string, params: Json, callbacks: {
7
- update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
8
- error: (error: Json) => void;
9
- loading: () => void;
10
- }): void;
11
- close(instance: string): void;
12
- }
13
- /**
14
- * A generic external service providing external resources.
15
- *
16
- * `GenericExternalService` provides an implementation of `ExternalService` for external resources by lifting the `open` and `close` operations from `ExternalResource` to the `subscribe` and `unsubscribe` operations required by `ExternalService`.
17
- */
18
- export declare class GenericExternalService implements ExternalService {
19
- private readonly resources;
20
- private readonly instances;
21
- /**
22
- * @param resources - Association of resource names to `ExternalResource`s.
23
- */
24
- constructor(resources: {
25
- [name: string]: ExternalResource;
26
- });
27
- subscribe(instance: string, resourceName: string, params: Json, callbacks: {
28
- update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
29
- error: (error: Json) => void;
30
- loading: () => void;
31
- }): void;
32
- unsubscribe(instance: string): void;
33
- shutdown(): Promise<void>;
34
- }
35
- export declare class TimerResource implements ExternalResource {
36
- private readonly intervals;
37
- open(instance: string, params: Json, callbacks: {
38
- update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
39
- error: (error: Json) => void;
40
- loading: () => void;
41
- }): void;
42
- close(instance: string): void;
43
- }
44
2
  /**
45
3
  * Encode params for external resource request.
46
4
  *
@@ -51,45 +9,62 @@ export declare class TimerResource implements ExternalResource {
51
9
  */
52
10
  export declare function defaultParamEncoder(params: Json): string;
53
11
  /**
54
- * An external resource that is refreshed at some polling interval.
12
+ * Description of an external HTTP endpoint and how to poll it.
13
+ *
14
+ * The URL of the external resource is formed by appending the given base `url` and the result of `encodeParams(params)` where `params` are the parameters provided to [`Context#useExternalResource`](api/core/interfaces/Context#useexternalresource)
55
15
  *
56
- * @typeParam S - Type of data received from external resource.
57
- * @typeParam K - Type of keys.
58
- * @typeParam V - Type of values.
59
16
  */
60
- export declare class Polled<S extends Json, K extends Json, V extends Json> implements ExternalResource {
61
- private readonly url;
62
- private readonly duration;
63
- private readonly conv;
64
- private readonly encodeParams;
65
- private readonly options?;
66
- private readonly intervals;
17
+ export interface PolledHTTPResource {
67
18
  /**
68
- * Construct a `Polled` external resource.
69
- *
70
- * The URL of the external resource is formed by appending the given base `url` and the result of `encodeParams(params)` where `params` are the parameters provided when instantiating the resource.
71
- *
72
- * Note that the result of `encodeParams` contains the `?` separator, but it need not be at the beginning of the returned string, so some parameters can be used in part of the URL preceding the `?`.
19
+ * Base URL of resource to poll.
20
+ */
21
+ url: string;
22
+ /**
23
+ * The interval of time to wait before refreshing the data, given in milliseconds
24
+ */
25
+ interval: number;
26
+ /**
27
+ * Function to convert data received from external resource to `key`-`value` entries.
28
+ */
29
+ conv: (data: Json) => Entry<Json, Json>[];
30
+ /**
31
+ * Function to use to encode params of type `Json` for external resource request.
73
32
  *
74
- * @param url - HTTP endpoint of external resource to poll.
75
- * @param duration - Refresh interval, in milliseconds.
76
- * @param conv - Function to convert data of type `S` received from external resource to `key`-`value` entries.
77
- * @param encodeParams - Function to use to encode params of type `Json` for external resource request.
78
- * @param options - Optional parameters.
79
- * @param options.headers - Additional headers to add to request.
80
- * @param options.timeout - Timeout for request, in milliseconds. Defaults to 1000ms.
33
+ * Note that the result of `encodeParams` may contain a `?` separator, but it need not be at the beginning of the returned string, so some parameters can be used in part of the URL preceding the `?`.
81
34
  */
82
- constructor(url: string, duration: number, conv: (data: S) => Entry<K, V>[], encodeParams?: (params: Json) => string, options?: {
35
+ encodeParams?: (params: Json) => string;
36
+ /**
37
+ * Optional parameters: additional `headers` to add to request, and `timeout` for request, in milliseconds. (default 1000ms)
38
+ */
39
+ options?: {
83
40
  headers?: {
84
41
  [header: string]: string;
85
42
  };
86
43
  timeout?: number;
87
- } | undefined);
88
- open(instance: string, params: Json, callbacks: {
44
+ };
45
+ }
46
+ /**
47
+ * An external HTTP service that is kept up-to-date by polling.
48
+ *
49
+ * A `PolledExternalService` may be composed of one or more [`PolledHTTPResource`](api/helpers/interfaces/PolledHTTPResource)s, each of which describes a single endpoint and how to poll it.
50
+ */
51
+ export declare class PolledExternalService implements ExternalService {
52
+ private readonly resources;
53
+ private readonly intervals;
54
+ /**
55
+ * Construct a polled external service.
56
+ *
57
+ * @param resources - Specification(s) of external resource(s) to poll
58
+ */
59
+ constructor(resources: {
60
+ [resource: string]: PolledHTTPResource;
61
+ });
62
+ subscribe(instance: string, resourceName: string, params: Json, callbacks: {
89
63
  update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
90
64
  error: (error: Json) => void;
91
65
  loading: () => void;
92
66
  }): void;
93
- close(instance: string): void;
67
+ unsubscribe(instance: string): void;
68
+ shutdown(): Promise<void>;
94
69
  }
95
70
  //# sourceMappingURL=external.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external.d.ts","sourceRoot":"","sources":["../../src/external.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"external.d.ts","sourceRoot":"","sources":["../../src/external.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAMtE;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,CASxD;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK,MAAM,CAAC;IACxC;;OAEG;IACH,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE;YAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IASzD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAR5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IAExD;;;;OAIG;gBAEgB,SAAS,EAAE;QAC1B,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAAC;KACxC;IAGH,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,IAAI,EACZ,SAAS,EAAE;QACT,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;QAChE,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;QAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB;IAwBH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQnC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAO1B"}
@@ -1,70 +1,5 @@
1
1
  import { SkipUnknownResourceError } from "@skipruntime/core";
2
2
  import { fetchJSON } from "./rest.js";
3
- /**
4
- * A generic external service providing external resources.
5
- *
6
- * `GenericExternalService` provides an implementation of `ExternalService` for external resources by lifting the `open` and `close` operations from `ExternalResource` to the `subscribe` and `unsubscribe` operations required by `ExternalService`.
7
- */
8
- export class GenericExternalService {
9
- /**
10
- * @param resources - Association of resource names to `ExternalResource`s.
11
- */
12
- constructor(resources) {
13
- this.resources = resources;
14
- this.instances = new Map();
15
- }
16
- subscribe(instance, resourceName, params, callbacks) {
17
- const resource = this.resources[resourceName];
18
- if (!resource) {
19
- throw new SkipUnknownResourceError(`Unknown resource named '${resourceName}'`);
20
- }
21
- this.instances.set(instance, resource);
22
- resource.open(instance, params, callbacks);
23
- }
24
- unsubscribe(instance) {
25
- const resource = this.instances.get(instance);
26
- if (resource) {
27
- resource.close(instance);
28
- this.instances.delete(instance);
29
- }
30
- }
31
- shutdown() {
32
- return Promise.resolve();
33
- }
34
- }
35
- export class TimerResource {
36
- constructor() {
37
- this.intervals = new Map();
38
- }
39
- open(instance, params, callbacks) {
40
- const time = new Date().getTime();
41
- const values = [];
42
- for (const name of Object.keys(params)) {
43
- values.push([name, [time]]);
44
- }
45
- callbacks.update(values, true);
46
- const intervals = {};
47
- for (const [name, duration] of Object.entries(params)) {
48
- const ms = Number(duration);
49
- if (ms > 0) {
50
- intervals[name] = setInterval(() => {
51
- const newvalue = [name, [new Date().getTime()]];
52
- callbacks.update([newvalue], true);
53
- }, ms);
54
- }
55
- }
56
- this.intervals.set(instance, intervals);
57
- }
58
- close(instance) {
59
- const intervals = this.intervals.get(instance);
60
- if (intervals != null) {
61
- for (const interval of Object.values(intervals)) {
62
- clearInterval(interval);
63
- }
64
- this.intervals.delete(instance);
65
- }
66
- }
67
- }
68
3
  /**
69
4
  * Encode params for external resource request.
70
5
  *
@@ -88,43 +23,30 @@ export function defaultParamEncoder(params) {
88
23
  return `?params=${JSON.stringify(params)}`;
89
24
  }
90
25
  /**
91
- * An external resource that is refreshed at some polling interval.
26
+ * An external HTTP service that is kept up-to-date by polling.
92
27
  *
93
- * @typeParam S - Type of data received from external resource.
94
- * @typeParam K - Type of keys.
95
- * @typeParam V - Type of values.
28
+ * A `PolledExternalService` may be composed of one or more [`PolledHTTPResource`](api/helpers/interfaces/PolledHTTPResource)s, each of which describes a single endpoint and how to poll it.
96
29
  */
97
- export class Polled {
30
+ export class PolledExternalService {
98
31
  /**
99
- * Construct a `Polled` external resource.
100
- *
101
- * The URL of the external resource is formed by appending the given base `url` and the result of `encodeParams(params)` where `params` are the parameters provided when instantiating the resource.
102
- *
103
- * Note that the result of `encodeParams` contains the `?` separator, but it need not be at the beginning of the returned string, so some parameters can be used in part of the URL preceding the `?`.
32
+ * Construct a polled external service.
104
33
  *
105
- * @param url - HTTP endpoint of external resource to poll.
106
- * @param duration - Refresh interval, in milliseconds.
107
- * @param conv - Function to convert data of type `S` received from external resource to `key`-`value` entries.
108
- * @param encodeParams - Function to use to encode params of type `Json` for external resource request.
109
- * @param options - Optional parameters.
110
- * @param options.headers - Additional headers to add to request.
111
- * @param options.timeout - Timeout for request, in milliseconds. Defaults to 1000ms.
34
+ * @param resources - Specification(s) of external resource(s) to poll
112
35
  */
113
- constructor(url, duration, conv, encodeParams = defaultParamEncoder, options) {
114
- this.url = url;
115
- this.duration = duration;
116
- this.conv = conv;
117
- this.encodeParams = encodeParams;
118
- this.options = options;
36
+ constructor(resources) {
37
+ this.resources = resources;
119
38
  this.intervals = new Map();
120
39
  }
121
- open(instance, params, callbacks) {
122
- const url = `${this.url}${this.encodeParams(params)}`;
40
+ subscribe(instance, resourceName, params, callbacks) {
41
+ const resource = this.resources[resourceName];
42
+ if (!resource)
43
+ throw new SkipUnknownResourceError(`Unknown resource named '${resourceName}'`);
44
+ const url = `${resource.url}${(resource.encodeParams ?? defaultParamEncoder)(params)}`;
123
45
  const call = () => {
124
46
  callbacks.loading();
125
- fetchJSON(url, "GET", this.options)
47
+ fetchJSON(url, "GET", resource.options ?? {})
126
48
  .then((r) => {
127
- callbacks.update(this.conv(r[0]), true);
49
+ callbacks.update(resource.conv(r[0] ?? []), true);
128
50
  })
129
51
  .catch((e) => {
130
52
  callbacks.error(e instanceof Error ? e.message : JSON.stringify(e));
@@ -132,14 +54,21 @@ export class Polled {
132
54
  });
133
55
  };
134
56
  call();
135
- this.intervals.set(instance, setInterval(call, this.duration));
57
+ this.intervals.set(instance, setInterval(call, resource.interval));
136
58
  }
137
- close(instance) {
59
+ unsubscribe(instance) {
138
60
  const interval = this.intervals.get(instance);
139
61
  if (interval) {
140
62
  clearInterval(interval);
141
63
  this.intervals.delete(instance);
142
64
  }
143
65
  }
66
+ shutdown() {
67
+ for (const [instance, interval] of Object.entries(this.intervals)) {
68
+ clearInterval(interval);
69
+ this.intervals.delete(instance);
70
+ }
71
+ return Promise.resolve();
72
+ }
144
73
  }
145
74
  //# sourceMappingURL=external.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/external.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"external.js","sourceRoot":"","sources":["../../src/external.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @packageDocumentation
5
5
  */
6
- export { defaultParamEncoder, type ExternalResource, GenericExternalService, Polled, TimerResource, } from "./external.js";
6
+ export { defaultParamEncoder, PolledExternalService } from "./external.js";
7
7
  export { SkipExternalService } from "./remote.js";
8
8
  export { SkipServiceBroker, fetchJSON, type Entrypoint } from "./rest.js";
9
9
  export { Count, Max, Min, Sum } from "./utils.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,sBAAsB,EACtB,MAAM,EACN,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC"}
package/dist/src/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @packageDocumentation
5
5
  */
6
- export { defaultParamEncoder, GenericExternalService, Polled, TimerResource, } from "./external.js";
6
+ export { defaultParamEncoder, PolledExternalService } from "./external.js";
7
7
  export { SkipExternalService } from "./remote.js";
8
8
  export { SkipServiceBroker, fetchJSON } from "./rest.js";
9
9
  export { Count, Max, Min, Sum } from "./utils.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,EAEnB,sBAAsB,EACtB,MAAM,EACN,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAmB,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAmB,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skipruntime/helpers",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dist/src/index.js"
@@ -19,7 +19,7 @@
19
19
  "dependencies": {
20
20
  "eventsource": "^2.0.2",
21
21
  "express": "^4.21.1",
22
- "@skipruntime/core": "0.0.12"
22
+ "@skipruntime/core": "0.0.13"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/eventsource": "^1.1.15"
package/src/external.ts CHANGED
@@ -2,117 +2,7 @@ import type { Entry, ExternalService, Json } from "@skipruntime/core";
2
2
  import { SkipUnknownResourceError } from "@skipruntime/core";
3
3
  import { fetchJSON } from "./rest.js";
4
4
 
5
- /**
6
- * Interface required by `GenericExternalService` for external resources.
7
- */
8
- export interface ExternalResource {
9
- open(
10
- instance: string,
11
- params: Json,
12
- callbacks: {
13
- update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
14
- error: (error: Json) => void;
15
- loading: () => void;
16
- },
17
- ): void;
18
-
19
- close(instance: string): void;
20
- }
21
-
22
- /**
23
- * A generic external service providing external resources.
24
- *
25
- * `GenericExternalService` provides an implementation of `ExternalService` for external resources by lifting the `open` and `close` operations from `ExternalResource` to the `subscribe` and `unsubscribe` operations required by `ExternalService`.
26
- */
27
- export class GenericExternalService implements ExternalService {
28
- private readonly instances = new Map<string, ExternalResource>();
29
-
30
- /**
31
- * @param resources - Association of resource names to `ExternalResource`s.
32
- */
33
- constructor(
34
- private readonly resources: { [name: string]: ExternalResource },
35
- ) {}
36
-
37
- subscribe(
38
- instance: string,
39
- resourceName: string,
40
- params: Json,
41
- callbacks: {
42
- update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
43
- error: (error: Json) => void;
44
- loading: () => void;
45
- },
46
- ) {
47
- const resource = this.resources[resourceName] as
48
- | ExternalResource
49
- | undefined;
50
- if (!resource) {
51
- throw new SkipUnknownResourceError(
52
- `Unknown resource named '${resourceName}'`,
53
- );
54
- }
55
- this.instances.set(instance, resource);
56
- resource.open(instance, params, callbacks);
57
- }
58
-
59
- unsubscribe(instance: string) {
60
- const resource = this.instances.get(instance);
61
- if (resource) {
62
- resource.close(instance);
63
- this.instances.delete(instance);
64
- }
65
- }
66
-
67
- shutdown(): Promise<void> {
68
- return Promise.resolve();
69
- }
70
- }
71
-
72
5
  type Timeout = ReturnType<typeof setInterval>;
73
- type Timeouts = { [name: string]: Timeout };
74
-
75
- export class TimerResource implements ExternalResource {
76
- private readonly intervals = new Map<string, { [name: string]: Timeout }>();
77
-
78
- open(
79
- instance: string,
80
- params: Json,
81
- callbacks: {
82
- update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
83
- error: (error: Json) => void;
84
- loading: () => void;
85
- },
86
- ) {
87
- const time = new Date().getTime();
88
- const values: Entry<string, number>[] = [];
89
- for (const name of Object.keys(params)) {
90
- values.push([name, [time]]);
91
- }
92
- callbacks.update(values, true);
93
- const intervals: Timeouts = {};
94
- for (const [name, duration] of Object.entries(params)) {
95
- const ms = Number(duration);
96
- if (ms > 0) {
97
- intervals[name] = setInterval(() => {
98
- const newvalue: Entry<Json, Json> = [name, [new Date().getTime()]];
99
- callbacks.update([newvalue], true);
100
- }, ms);
101
- }
102
- }
103
- this.intervals.set(instance, intervals);
104
- }
105
-
106
- close(instance: string): void {
107
- const intervals = this.intervals.get(instance);
108
- if (intervals != null) {
109
- for (const interval of Object.values(intervals)) {
110
- clearInterval(interval);
111
- }
112
- this.intervals.delete(instance);
113
- }
114
- }
115
- }
116
6
 
117
7
  /**
118
8
  * Encode params for external resource request.
@@ -134,47 +24,58 @@ export function defaultParamEncoder(params: Json): string {
134
24
  }
135
25
 
136
26
  /**
137
- * An external resource that is refreshed at some polling interval.
27
+ * Description of an external HTTP endpoint and how to poll it.
28
+ *
29
+ * The URL of the external resource is formed by appending the given base `url` and the result of `encodeParams(params)` where `params` are the parameters provided to [`Context#useExternalResource`](api/core/interfaces/Context#useexternalresource)
138
30
  *
139
- * @typeParam S - Type of data received from external resource.
140
- * @typeParam K - Type of keys.
141
- * @typeParam V - Type of values.
142
31
  */
143
- export class Polled<S extends Json, K extends Json, V extends Json>
144
- implements ExternalResource
145
- {
32
+ export interface PolledHTTPResource {
33
+ /**
34
+ * Base URL of resource to poll.
35
+ */
36
+ url: string;
37
+ /**
38
+ * The interval of time to wait before refreshing the data, given in milliseconds
39
+ */
40
+ interval: number;
41
+ /**
42
+ * Function to convert data received from external resource to `key`-`value` entries.
43
+ */
44
+ conv: (data: Json) => Entry<Json, Json>[];
45
+ /**
46
+ * Function to use to encode params of type `Json` for external resource request.
47
+ *
48
+ * Note that the result of `encodeParams` may contain a `?` separator, but it need not be at the beginning of the returned string, so some parameters can be used in part of the URL preceding the `?`.
49
+ */
50
+ encodeParams?: (params: Json) => string;
51
+ /**
52
+ * Optional parameters: additional `headers` to add to request, and `timeout` for request, in milliseconds. (default 1000ms)
53
+ */
54
+ options?: { headers?: { [header: string]: string }; timeout?: number };
55
+ }
56
+
57
+ /**
58
+ * An external HTTP service that is kept up-to-date by polling.
59
+ *
60
+ * A `PolledExternalService` may be composed of one or more [`PolledHTTPResource`](api/helpers/interfaces/PolledHTTPResource)s, each of which describes a single endpoint and how to poll it.
61
+ */
62
+ export class PolledExternalService implements ExternalService {
146
63
  private readonly intervals = new Map<string, Timeout>();
147
64
 
148
65
  /**
149
- * Construct a `Polled` external resource.
66
+ * Construct a polled external service.
150
67
  *
151
- * The URL of the external resource is formed by appending the given base `url` and the result of `encodeParams(params)` where `params` are the parameters provided when instantiating the resource.
152
- *
153
- * Note that the result of `encodeParams` contains the `?` separator, but it need not be at the beginning of the returned string, so some parameters can be used in part of the URL preceding the `?`.
154
- *
155
- * @param url - HTTP endpoint of external resource to poll.
156
- * @param duration - Refresh interval, in milliseconds.
157
- * @param conv - Function to convert data of type `S` received from external resource to `key`-`value` entries.
158
- * @param encodeParams - Function to use to encode params of type `Json` for external resource request.
159
- * @param options - Optional parameters.
160
- * @param options.headers - Additional headers to add to request.
161
- * @param options.timeout - Timeout for request, in milliseconds. Defaults to 1000ms.
68
+ * @param resources - Specification(s) of external resource(s) to poll
162
69
  */
163
70
  constructor(
164
- private readonly url: string,
165
- private readonly duration: number,
166
- private readonly conv: (data: S) => Entry<K, V>[],
167
- private readonly encodeParams: (
168
- params: Json,
169
- ) => string = defaultParamEncoder,
170
- private readonly options?: {
171
- headers?: { [header: string]: string };
172
- timeout?: number;
71
+ private readonly resources: {
72
+ [resource: string]: PolledHTTPResource;
173
73
  },
174
74
  ) {}
175
75
 
176
- open(
76
+ subscribe(
177
77
  instance: string,
78
+ resourceName: string,
178
79
  params: Json,
179
80
  callbacks: {
180
81
  update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
@@ -182,12 +83,18 @@ export class Polled<S extends Json, K extends Json, V extends Json>
182
83
  loading: () => void;
183
84
  },
184
85
  ) {
185
- const url = `${this.url}${this.encodeParams(params)}`;
86
+ const resource = this.resources[resourceName];
87
+ if (!resource)
88
+ throw new SkipUnknownResourceError(
89
+ `Unknown resource named '${resourceName}'`,
90
+ );
91
+
92
+ const url = `${resource.url}${(resource.encodeParams ?? defaultParamEncoder)(params)}`;
186
93
  const call = () => {
187
94
  callbacks.loading();
188
- fetchJSON(url, "GET", this.options)
95
+ fetchJSON(url, "GET", resource.options ?? {})
189
96
  .then((r) => {
190
- callbacks.update(this.conv(r[0] as S), true);
97
+ callbacks.update(resource.conv(r[0] ?? []), true);
191
98
  })
192
99
  .catch((e: unknown) => {
193
100
  callbacks.error(e instanceof Error ? e.message : JSON.stringify(e));
@@ -195,14 +102,22 @@ export class Polled<S extends Json, K extends Json, V extends Json>
195
102
  });
196
103
  };
197
104
  call();
198
- this.intervals.set(instance, setInterval(call, this.duration));
105
+ this.intervals.set(instance, setInterval(call, resource.interval));
199
106
  }
200
107
 
201
- close(instance: string): void {
108
+ unsubscribe(instance: string): void {
202
109
  const interval = this.intervals.get(instance);
203
110
  if (interval) {
204
111
  clearInterval(interval);
205
112
  this.intervals.delete(instance);
206
113
  }
207
114
  }
115
+
116
+ shutdown(): Promise<void> {
117
+ for (const [instance, interval] of Object.entries(this.intervals)) {
118
+ clearInterval(interval as Timeout);
119
+ this.intervals.delete(instance);
120
+ }
121
+ return Promise.resolve();
122
+ }
208
123
  }
package/src/index.ts CHANGED
@@ -4,13 +4,7 @@
4
4
  * @packageDocumentation
5
5
  */
6
6
 
7
- export {
8
- defaultParamEncoder,
9
- type ExternalResource,
10
- GenericExternalService,
11
- Polled,
12
- TimerResource,
13
- } from "./external.js";
7
+ export { defaultParamEncoder, PolledExternalService } from "./external.js";
14
8
  export { SkipExternalService } from "./remote.js";
15
9
  export { SkipServiceBroker, fetchJSON, type Entrypoint } from "./rest.js";
16
10
  export { Count, Max, Min, Sum } from "./utils.js";