@skipruntime/helpers 0.0.4 → 0.0.6

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/src/external.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import type { Entry, ExternalService, Json } from "@skipruntime/api";
2
2
  import { fetchJSON } from "./rest.js";
3
3
 
4
+ /**
5
+ * Interface required by `GenericExternalService` for external resources.
6
+ */
4
7
  export interface ExternalResource {
5
8
  open(
6
- params: { [param: string]: string | number },
9
+ params: Json,
7
10
  callbacks: {
8
11
  update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
9
12
  error: (error: Json) => void;
@@ -11,15 +14,25 @@ export interface ExternalResource {
11
14
  },
12
15
  ): void;
13
16
 
14
- close(params: { [param: string]: string | number }): void;
17
+ close(params: Json): void;
15
18
  }
16
19
 
20
+ /**
21
+ * A generic external service providing external resources.
22
+ *
23
+ * `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`.
24
+ */
17
25
  export class GenericExternalService implements ExternalService {
18
- constructor(private resources: { [name: string]: ExternalResource }) {}
26
+ /**
27
+ * @param resources - Association of resource names to `ExternalResource`s.
28
+ */
29
+ constructor(
30
+ private readonly resources: { [name: string]: ExternalResource },
31
+ ) {}
19
32
 
20
33
  subscribe(
21
34
  resourceName: string,
22
- params: { [param: string]: string | number },
35
+ params: Json,
23
36
  callbacks: {
24
37
  update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
25
38
  error: (error: Json) => void;
@@ -35,7 +48,7 @@ export class GenericExternalService implements ExternalService {
35
48
  resource.open(params, callbacks);
36
49
  }
37
50
 
38
- unsubscribe(resourceName: string, params: { [param: string]: string }) {
51
+ unsubscribe(resourceName: string, params: Json) {
39
52
  const resource = this.resources[resourceName] as
40
53
  | ExternalResource
41
54
  | undefined;
@@ -53,10 +66,10 @@ export class GenericExternalService implements ExternalService {
53
66
  type Timeout = ReturnType<typeof setInterval>;
54
67
 
55
68
  export class TimerResource implements ExternalResource {
56
- private intervals = new Map<string, { [name: string]: Timeout }>();
69
+ private readonly intervals = new Map<string, { [name: string]: Timeout }>();
57
70
 
58
71
  open(
59
- params: { [param: string]: string | number },
72
+ params: Json,
60
73
  callbacks: {
61
74
  update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
62
75
  error: (error: Json) => void;
@@ -83,7 +96,7 @@ export class TimerResource implements ExternalResource {
83
96
  this.intervals.set(id, intervals);
84
97
  }
85
98
 
86
- close(params: { [param: string]: string | number }): void {
99
+ close(params: Json): void {
87
100
  const intervals = this.intervals.get(toId(params));
88
101
  if (intervals != null) {
89
102
  for (const interval of Object.values(intervals)) {
@@ -93,19 +106,46 @@ export class TimerResource implements ExternalResource {
93
106
  }
94
107
  }
95
108
 
109
+ function defaultParamEncoder(params: Json): string {
110
+ if (typeof params == "object") {
111
+ const queryParams: { [param: string]: string } = {};
112
+ for (const [key, value] of Object.entries(params)) {
113
+ if (typeof value == "object") queryParams[key] = JSON.stringify(value);
114
+ else queryParams[key] = value.toString();
115
+ }
116
+ return new URLSearchParams(queryParams).toString();
117
+ } else return `params=${JSON.stringify(params)}`;
118
+ }
119
+
120
+ /**
121
+ * An external resource that is refreshed at some polling interval.
122
+ *
123
+ * @typeParam S - Type of data received from external resource.
124
+ * @typeParam K - Type of keys.
125
+ * @typeParam V - Type of values.
126
+ */
96
127
  export class Polled<S extends Json, K extends Json, V extends Json>
97
128
  implements ExternalResource
98
129
  {
99
- private intervals = new Map<string, Timeout>();
130
+ private readonly intervals = new Map<string, Timeout>();
100
131
 
132
+ /**
133
+ * @param url - HTTP endpoint of external resource to poll.
134
+ * @param duration - Refresh interval, in milliseconds.
135
+ * @param conv - Function to convert data of type `S` received from external resource to `key`-`value` entries.
136
+ * @param encodeParams - Function to use to encode params of type `Json` for external resource request.
137
+ */
101
138
  constructor(
102
- private url: string,
103
- private duration: number,
104
- private conv: (data: S) => Entry<K, V>[],
139
+ private readonly url: string,
140
+ private readonly duration: number,
141
+ private readonly conv: (data: S) => Entry<K, V>[],
142
+ private readonly encodeParams: (
143
+ params: Json,
144
+ ) => string = defaultParamEncoder,
105
145
  ) {}
106
146
 
107
147
  open(
108
- params: { [param: string]: string | number },
148
+ params: Json,
109
149
  callbacks: {
110
150
  update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
111
151
  error: (error: Json) => void;
@@ -113,12 +153,7 @@ export class Polled<S extends Json, K extends Json, V extends Json>
113
153
  },
114
154
  ): void {
115
155
  this.close(params);
116
- const queryParams: { [param: string]: string } = {};
117
- for (const [key, value] of Object.entries(params)) {
118
- queryParams[key] = value.toString();
119
- }
120
- const strParams = new URLSearchParams(queryParams).toString();
121
- const url = `${this.url}?${strParams}`;
156
+ const url = `${this.url}?${this.encodeParams(params)}`;
122
157
  const call = () => {
123
158
  callbacks.loading();
124
159
  fetchJSON(url, "GET", {})
@@ -134,7 +169,7 @@ export class Polled<S extends Json, K extends Json, V extends Json>
134
169
  this.intervals.set(toId(params), setInterval(call, this.duration));
135
170
  }
136
171
 
137
- close(params: { [param: string]: string | number }): void {
172
+ close(params: Json): void {
138
173
  const interval = this.intervals.get(toId(params));
139
174
  if (interval) {
140
175
  clearInterval(interval);
@@ -142,9 +177,11 @@ export class Polled<S extends Json, K extends Json, V extends Json>
142
177
  }
143
178
  }
144
179
 
145
- function toId(params: { [param: string]: string | number }): string {
146
- const strparams = Object.entries(params)
147
- .map(([key, value]) => `${key}:${value.toString()}`)
148
- .sort();
149
- return `[${strparams.join(",")}]`;
180
+ function toId(params: Json): string {
181
+ if (typeof params == "object") {
182
+ const strparams = Object.entries(params)
183
+ .map(([key, value]) => `${key}:${btoa(JSON.stringify(value))}`)
184
+ .sort();
185
+ return `[${strparams.join(",")}]`;
186
+ } else return btoa(JSON.stringify(params));
150
187
  }
package/src/index.ts CHANGED
@@ -1,8 +1,20 @@
1
- export { SkipExternalService } from "./remote.js";
1
+ /**
2
+ * This package contains items that may be useful for working with the Skip framework, but are not strictly necessary.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+
2
7
  export {
3
8
  type ExternalResource,
4
9
  GenericExternalService,
5
10
  Polled,
6
11
  } from "./external.js";
7
- export { Sum, Min, Max, CountMapper } from "./utils.js";
8
- export { fetchJSON, RESTWrapperOfSkipService } from "./rest.js";
12
+ export { SkipServiceBroker, fetchJSON, type Entrypoint } from "./rest.js";
13
+ export {
14
+ Count,
15
+ CountMapper,
16
+ Max,
17
+ Min,
18
+ SkipExternalService,
19
+ Sum,
20
+ } from "@skipruntime/core";
package/src/rest.ts CHANGED
@@ -1,11 +1,7 @@
1
1
  import type { Json, Entry } from "@skipruntime/api";
2
-
3
- export type Entrypoint = {
4
- host: string;
5
- streaming_port: number;
6
- control_port: number;
7
- secured?: boolean;
8
- };
2
+ import { NonUniqueValueException } from "@skipruntime/api";
3
+ import type { Entrypoint } from "@skipruntime/core";
4
+ export type { Entrypoint };
9
5
 
10
6
  function toHttp(entrypoint: Entrypoint) {
11
7
  if (entrypoint.secured)
@@ -13,7 +9,17 @@ function toHttp(entrypoint: Entrypoint) {
13
9
  return `http://${entrypoint.host}:${entrypoint.control_port}`;
14
10
  }
15
11
 
16
- export async function fetchJSON<V>(
12
+ /**
13
+ * Perform an HTTP fetch where input and output data is `Json`.
14
+ *
15
+ * @typeParam V - Type response is *assumed* to have.
16
+ * @param url - URL from which to fetch.
17
+ * @param method - HTTP method of request.
18
+ * @param headers - Additional headers to add to request.
19
+ * @param data - Data to convert to JSON and send in request body.
20
+ * @returns Response parsed as JSON, and headers.
21
+ */
22
+ export async function fetchJSON<V extends Json>(
17
23
  url: string,
18
24
  method: "POST" | "GET" | "PUT" | "PATCH" | "HEAD" | "DELETE" = "GET",
19
25
  headers: { [header: string]: string } = {},
@@ -41,9 +47,21 @@ export async function fetchJSON<V>(
41
47
  return [responseJSON, response.headers];
42
48
  }
43
49
 
44
- export class RESTWrapperOfSkipService {
45
- private entrypoint: string;
50
+ /**
51
+ * Wrapper providing a method-call interface to the Skip service HTTP APIs.
52
+ *
53
+ * Skip services, as started by `runService`, support an HTTP interface for reading from resources and writing to input collections.
54
+ * `SkipServiceBroker` provides a method-call interface to the backing HTTP interface.
55
+ */
56
+ export class SkipServiceBroker {
57
+ private readonly entrypoint: string;
46
58
 
59
+ /**
60
+ * Construct a broker for a Skip service at the given entry point.
61
+ *
62
+ * @param entrypoint - Entry point of backing service.
63
+ * @returns Method-call broker to service.
64
+ */
47
65
  constructor(
48
66
  entrypoint: Entrypoint = {
49
67
  host: "localhost",
@@ -54,64 +72,152 @@ export class RESTWrapperOfSkipService {
54
72
  this.entrypoint = toHttp(entrypoint);
55
73
  }
56
74
 
75
+ /**
76
+ * Read the entire contents of a resource.
77
+ *
78
+ * @typeParam K - Type of keys.
79
+ * @typeParam V - Type of values.
80
+ * @param resource - Name of resource, must be a key of the `resources` field of the `SkipService` running at `entrypoint`.
81
+ * @param params - Resource instance parameters.
82
+ * @returns All entries in resource.
83
+ */
57
84
  async getAll<K extends Json, V extends Json>(
58
85
  resource: string,
59
- params: { [param: string]: string },
86
+ params: Json,
60
87
  ): Promise<Entry<K, V>[]> {
61
- const qParams = new URLSearchParams(params).toString();
62
- const [optValues, _headers] = await fetchJSON<Entry<K, V>[]>(
63
- `${this.entrypoint}/v1/resources/${resource}?${qParams}`,
64
- "GET",
88
+ const [data, _headers] = await fetchJSON<Entry<K, V>[]>(
89
+ `${this.entrypoint}/v1/snapshot/${resource}`,
90
+ "POST",
91
+ {},
92
+ params,
65
93
  );
66
- const values = optValues ?? [];
67
- return values;
94
+ return data ?? [];
68
95
  }
69
96
 
70
- async getArray<V extends Json>(
97
+ /**
98
+ * Read the values a resource associates with a single key.
99
+ *
100
+ * @typeParam K - Type of keys.
101
+ * @typeParam V - Type of values.
102
+ * @param resource - Name of resource, must be a key of the `resources` field of the `SkipService` running at `entrypoint`.
103
+ * @param params - Resource instance parameters.
104
+ * @param key - Key to read.
105
+ * @returns The values associated to the key.
106
+ */
107
+ async getArray<K extends Json, V extends Json>(
71
108
  resource: string,
72
- params: { [param: string]: string },
73
- key: string,
109
+ params: Json,
110
+ key: K,
74
111
  ): Promise<V[]> {
75
- const qParams = new URLSearchParams(params).toString();
76
112
  const [data, _headers] = await fetchJSON<V[]>(
77
- `${this.entrypoint}/v1/resources/${resource}/${key}?${qParams}`,
78
- "GET",
113
+ `${this.entrypoint}/v1/snapshot/${resource}`,
114
+ "POST",
115
+ {},
116
+ { key, params },
79
117
  );
80
118
  return data ?? [];
81
119
  }
82
120
 
121
+ /**
122
+ * Read the single value a resource associates with a key.
123
+ *
124
+ * @typeParam K - Type of keys.
125
+ * @typeParam V - Type of values.
126
+ * @param resource - Name of resource, must be a key of the `resources` field of the `SkipService` running at `entrypoint`.
127
+ * @param params - Resource instance parameters.
128
+ * @param key - Key to read.
129
+ * @returns The value associated to the key.
130
+ * @throws `NonUniqueValueException` when the key is associated to either zero or multiple values.
131
+ */
132
+ async getUnique<K extends Json, V extends Json>(
133
+ resource: string,
134
+ params: Json,
135
+ key: K,
136
+ ): Promise<V> {
137
+ return this.getArray<K, V>(resource, params, key).then((values) => {
138
+ if (values.length !== 1 || values[0] === undefined)
139
+ throw new NonUniqueValueException();
140
+ return values[0];
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Write the values for a single key in a collection.
146
+ *
147
+ * @typeParam K - Type of keys.
148
+ * @typeParam V - Type of values.
149
+ * @param collection - Name of the input collection to update, must be a key of the `Inputs` type parameter of the `SkipService` running at `entrypoint`.
150
+ * @param key - Key of entry to write.
151
+ * @param values - Values of entry to write.
152
+ * @returns {void}
153
+ */
83
154
  async put<K extends Json, V extends Json>(
84
155
  collection: string,
85
156
  key: K,
86
- value: V[],
157
+ values: V[],
87
158
  ): Promise<void> {
88
- return await this.patch(collection, [[key, value]]);
159
+ return await this.patch(collection, [[key, values]]);
89
160
  }
90
161
 
162
+ /**
163
+ * Write multiple entries to a collection.
164
+ *
165
+ * @typeParam K - Type of keys.
166
+ * @typeParam V - Type of values.
167
+ * @param collection - Name of the input collection to update, must be a key of the `Inputs` type parameter of the `SkipService` running at `entrypoint`.
168
+ * @param entries - Entries to write.
169
+ * @returns {void}
170
+ */
91
171
  async patch<K extends Json, V extends Json>(
92
172
  collection: string,
93
- values: Entry<K, V>[],
173
+ entries: Entry<K, V>[],
94
174
  ): Promise<void> {
95
175
  await fetchJSON(
96
176
  `${this.entrypoint}/v1/inputs/${collection}`,
97
177
  "PATCH",
98
178
  {},
99
- values,
179
+ entries,
100
180
  );
101
181
  }
102
182
 
183
+ /**
184
+ * Remove all values associated with a key in a collection.
185
+ *
186
+ * @typeParam K - Type of keys.
187
+ * @param collection - Name of the input collection to update, must be a key of the `Inputs` type parameter of the `SkipService` running at `entrypoint`.
188
+ * @param key - Key of entry to delete.
189
+ * @returns {void}
190
+ */
103
191
  async deleteKey<K extends Json>(collection: string, key: K): Promise<void> {
104
192
  return await this.patch(collection, [[key, []]]);
105
193
  }
106
194
 
107
- async getStreamUUID(
108
- resource: string,
109
- params: { [param: string]: string } = {},
110
- ): Promise<string> {
111
- return fetch(`${this.entrypoint}/v1/streams`, {
195
+ /**
196
+ * Create a resource instance UUID.
197
+ *
198
+ * @typeParam K - Type of keys.
199
+ * @typeParam V - Type of values.
200
+ * @param resource - Name of resource, must be a key of the `resources` field of the `SkipService` running at `entrypoint`.
201
+ * @param params - Resource instance parameters.
202
+ * @returns UUID that can be used to subscribe to updates to resource instance.
203
+ */
204
+ async getStreamUUID(resource: string, params: Json = {}): Promise<string> {
205
+ return fetch(`${this.entrypoint}/v1/streams/${resource}`, {
112
206
  method: "POST",
113
207
  headers: { "Content-Type": "application/json" },
114
- body: JSON.stringify({ resource, params }),
208
+ body: JSON.stringify(params),
115
209
  }).then((res) => res.text());
116
210
  }
211
+
212
+ /**
213
+ * Destroy a resource instance.
214
+ *
215
+ * Under normal circumstances, resource instances are deleted automatically after some period of inactivity; this method enables immediately deleting live streams under exceptional circumstances.
216
+ *
217
+ * @param uuid - Resource instance UUID.
218
+ * @returns {void}
219
+ */
220
+ async deleteUUID(uuid: string): Promise<void> {
221
+ await fetchJSON(`${this.entrypoint}/v1/streams/${uuid}`, "DELETE");
222
+ }
117
223
  }
package/dist/errors.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare class UnknownCollectionError extends Error {
2
- }
3
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAuB,SAAQ,KAAK;CAAG"}
package/dist/errors.js DELETED
@@ -1,3 +0,0 @@
1
- export class UnknownCollectionError extends Error {
2
- }
3
- //# sourceMappingURL=errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,sBAAuB,SAAQ,KAAK;CAAG"}
package/dist/remote.d.ts DELETED
@@ -1,22 +0,0 @@
1
- import type { Entry, ExternalService, Json } from "@skipruntime/api";
2
- import type { Entrypoint } from "./rest.js";
3
- export declare class SkipExternalService implements ExternalService {
4
- private url;
5
- private control_url;
6
- private resources;
7
- constructor(url: string, control_url: string);
8
- static direct(entrypoint: Entrypoint): SkipExternalService;
9
- subscribe(resource: string, params: {
10
- [param: string]: string;
11
- }, callbacks: {
12
- update: (updates: Entry<Json, Json>[], isInitial: boolean) => void;
13
- error: (error: Json) => void;
14
- loading: () => void;
15
- }): void;
16
- unsubscribe(resource: string, params: {
17
- [param: string]: string;
18
- }): void;
19
- shutdown(): void;
20
- private toId;
21
- }
22
- //# sourceMappingURL=remote.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C,qBAAa,mBAAoB,YAAW,eAAe;IAIvD,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,WAAW;IAJrB,OAAO,CAAC,SAAS,CAA+B;gBAGtC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM;IAI7B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,mBAAmB;IAU1D,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,EACnC,SAAS,EAAE;QACT,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;QAEnE,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;QAE7B,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,GACA,IAAI;IAiCP,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE;IAKjE,QAAQ,IAAI,IAAI;IAMhB,OAAO,CAAC,IAAI;CAQb"}
package/dist/remote.js DELETED
@@ -1,71 +0,0 @@
1
- // TODO: Remove once global `EventSource` makes it out of experimental
2
- // in nodejs LTS.
3
- import EventSource from "eventsource";
4
- export class SkipExternalService {
5
- constructor(url, control_url) {
6
- this.url = url;
7
- this.control_url = control_url;
8
- this.resources = new Map();
9
- }
10
- // TODO: Support Skip external services going through a gateway.
11
- static direct(entrypoint) {
12
- let url = `http://${entrypoint.host}:${entrypoint.streaming_port.toString()}`;
13
- let control_url = `http://${entrypoint.host}:${entrypoint.control_port.toString()}`;
14
- if (entrypoint.secured) {
15
- url = `https://${entrypoint.host}:${entrypoint.streaming_port.toString()}`;
16
- control_url = `https://${entrypoint.host}:${entrypoint.control_port.toString()}`;
17
- }
18
- return new SkipExternalService(url, control_url);
19
- }
20
- subscribe(resource, params, callbacks) {
21
- // TODO Manage Status
22
- fetch(`${this.control_url}/v1/streams`, {
23
- method: "POST",
24
- headers: {
25
- "Content-Type": "application/json",
26
- },
27
- body: JSON.stringify({
28
- resource,
29
- params,
30
- }),
31
- })
32
- .then((resp) => resp.text())
33
- .then((uuid) => {
34
- const evSource = new EventSource(`${this.url}/v1/streams/${uuid}`);
35
- evSource.addEventListener("init", (e) => {
36
- const updates = JSON.parse(e.data);
37
- callbacks.update(updates, true);
38
- });
39
- evSource.addEventListener("update", (e) => {
40
- const updates = JSON.parse(e.data);
41
- callbacks.update(updates, false);
42
- });
43
- evSource.onerror = (e) => {
44
- console.log(e);
45
- };
46
- this.resources.set(this.toId(resource, params), evSource);
47
- })
48
- .catch((e) => {
49
- console.log(e);
50
- });
51
- }
52
- unsubscribe(resource, params) {
53
- const closable = this.resources.get(this.toId(resource, params));
54
- if (closable)
55
- closable.close();
56
- }
57
- shutdown() {
58
- for (const res of this.resources.values()) {
59
- res.close();
60
- }
61
- }
62
- toId(resource, params) {
63
- // TODO: This is equivalent to `querystring.encode(params, ',', ':')`.
64
- const strparams = [];
65
- for (const key of Object.keys(params).sort()) {
66
- strparams.push(`${key}:${params[key]}`);
67
- }
68
- return `${resource}[${strparams.join(",")}]`;
69
- }
70
- }
71
- //# sourceMappingURL=remote.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
package/dist/utils.d.ts DELETED
@@ -1,22 +0,0 @@
1
- import type { Nullable } from "@skip-wasm/std";
2
- import { ManyToOneMapper } from "@skipruntime/api";
3
- import type { Reducer, NonEmptyIterator, Json } from "@skipruntime/api";
4
- export declare class Sum implements Reducer<number, number> {
5
- default: number;
6
- add(acc: number, value: number): number;
7
- remove(acc: number, value: number): Nullable<number>;
8
- }
9
- export declare class Min implements Reducer<number, number> {
10
- default: null;
11
- add(acc: Nullable<number>, value: number): number;
12
- remove(acc: number, value: number): Nullable<number>;
13
- }
14
- export declare class Max implements Reducer<number, number> {
15
- default: null;
16
- add(acc: Nullable<number>, value: number): number;
17
- remove(acc: number, value: number): Nullable<number>;
18
- }
19
- export declare class CountMapper<K extends Json, V extends Json> extends ManyToOneMapper<K, V, number> {
20
- mapValues(values: NonEmptyIterator<V>): number;
21
- }
22
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExE,qBAAa,GAAI,YAAW,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;IACjD,OAAO,SAAK;IAEZ,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAIvC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;CAGrD;AAED,qBAAa,GAAI,YAAW,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;IACjD,OAAO,OAAQ;IAEf,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAIjD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;CAGrD;AAED,qBAAa,GAAI,YAAW,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;IACjD,OAAO,OAAQ;IAEf,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAIjD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;CAGrD;AAED,qBAAa,WAAW,CACtB,CAAC,SAAS,IAAI,EACd,CAAC,SAAS,IAAI,CACd,SAAQ,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,MAAM;CAG/C"}
package/dist/utils.js DELETED
@@ -1,40 +0,0 @@
1
- import { ManyToOneMapper } from "@skipruntime/api";
2
- export class Sum {
3
- constructor() {
4
- this.default = 0;
5
- }
6
- add(acc, value) {
7
- return acc + value;
8
- }
9
- remove(acc, value) {
10
- return acc - value;
11
- }
12
- }
13
- export class Min {
14
- constructor() {
15
- this.default = null;
16
- }
17
- add(acc, value) {
18
- return acc === null ? value : Math.min(acc, value);
19
- }
20
- remove(acc, value) {
21
- return value > acc ? acc : null;
22
- }
23
- }
24
- export class Max {
25
- constructor() {
26
- this.default = null;
27
- }
28
- add(acc, value) {
29
- return acc === null ? value : Math.max(acc, value);
30
- }
31
- remove(acc, value) {
32
- return value < acc ? acc : null;
33
- }
34
- }
35
- export class CountMapper extends ManyToOneMapper {
36
- mapValues(values) {
37
- return values.toArray().length;
38
- }
39
- }
40
- //# sourceMappingURL=utils.js.map
package/dist/utils.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnD,MAAM,OAAO,GAAG;IAAhB;QACE,YAAO,GAAG,CAAC,CAAC;IASd,CAAC;IAPC,GAAG,CAAC,GAAW,EAAE,KAAa;QAC5B,OAAO,GAAG,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,KAAa;QAC/B,OAAO,GAAG,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,MAAM,OAAO,GAAG;IAAhB;QACE,YAAO,GAAG,IAAI,CAAC;IASjB,CAAC;IAPC,GAAG,CAAC,GAAqB,EAAE,KAAa;QACtC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,KAAa;QAC/B,OAAO,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAClC,CAAC;CACF;AAED,MAAM,OAAO,GAAG;IAAhB;QACE,YAAO,GAAG,IAAI,CAAC;IASjB,CAAC;IAPC,GAAG,CAAC,GAAqB,EAAE,KAAa;QACtC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,KAAa;QAC/B,OAAO,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAClC,CAAC;CACF;AAED,MAAM,OAAO,WAGX,SAAQ,eAA6B;IACrC,SAAS,CAAC,MAA2B;QACnC,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC;IACjC,CAAC;CACF"}
package/src/errors.ts DELETED
@@ -1 +0,0 @@
1
- export class UnknownCollectionError extends Error {}