@skipruntime/helpers 0.0.1 → 0.0.3
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/dist/external.d.ts +41 -23
- package/dist/external.d.ts.map +1 -1
- package/dist/external.js +18 -19
- package/dist/external.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/remote.d.ts +14 -15
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +50 -62
- package/dist/remote.js.map +1 -1
- package/dist/rest.d.ts +16 -14
- package/dist/rest.d.ts.map +1 -1
- package/dist/rest.js +13 -54
- package/dist/rest.js.map +1 -1
- package/dist/utils.d.ts +12 -14
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +6 -24
- package/dist/utils.js.map +1 -1
- package/package.json +6 -3
- package/src/external.ts +34 -58
- package/src/index.ts +2 -8
- package/src/remote.ts +56 -120
- package/src/rest.ts +31 -87
- package/src/utils.ts +13 -43
package/dist/rest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../src/rest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../src/rest.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Nullable } from "@skip-wasm/std";
|
|
2
2
|
import { ManyToOneMapper } from "@skipruntime/api";
|
|
3
|
-
import type {
|
|
4
|
-
export declare class Sum implements
|
|
3
|
+
import type { Reducer, NonEmptyIterator, Json } from "@skipruntime/api";
|
|
4
|
+
export declare class Sum implements Reducer<number, number> {
|
|
5
5
|
default: number;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
add(acc: number, value: number): number;
|
|
7
|
+
remove(acc: number, value: number): Nullable<number>;
|
|
8
8
|
}
|
|
9
|
-
export declare class Min implements
|
|
9
|
+
export declare class Min implements Reducer<number, number> {
|
|
10
10
|
default: null;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
add(acc: Nullable<number>, value: number): number;
|
|
12
|
+
remove(acc: number, value: number): Nullable<number>;
|
|
13
13
|
}
|
|
14
|
-
export declare class Max implements
|
|
14
|
+
export declare class Max implements Reducer<number, number> {
|
|
15
15
|
default: null;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
add(acc: Nullable<number>, value: number): number;
|
|
17
|
+
remove(acc: number, value: number): Nullable<number>;
|
|
18
18
|
}
|
|
19
|
-
export declare class CountMapper<K extends
|
|
19
|
+
export declare class CountMapper<K extends Json, V extends Json> extends ManyToOneMapper<K, V, number> {
|
|
20
20
|
mapValues(values: NonEmptyIterator<V>): number;
|
|
21
21
|
}
|
|
22
|
-
export declare function parseReactiveResponse(header: Headers | string): ReactiveResponse | undefined;
|
|
23
|
-
export declare function reactiveResponseHeader(reactiveResponse: ReactiveResponse): [string, string];
|
|
24
22
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
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
CHANGED
|
@@ -3,10 +3,10 @@ export class Sum {
|
|
|
3
3
|
constructor() {
|
|
4
4
|
this.default = 0;
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
add(acc, value) {
|
|
7
7
|
return acc + value;
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
remove(acc, value) {
|
|
10
10
|
return acc - value;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -14,10 +14,10 @@ export class Min {
|
|
|
14
14
|
constructor() {
|
|
15
15
|
this.default = null;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
add(acc, value) {
|
|
18
18
|
return acc === null ? value : Math.min(acc, value);
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
remove(acc, value) {
|
|
21
21
|
return value > acc ? acc : null;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -25,10 +25,10 @@ export class Max {
|
|
|
25
25
|
constructor() {
|
|
26
26
|
this.default = null;
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
add(acc, value) {
|
|
29
29
|
return acc === null ? value : Math.max(acc, value);
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
remove(acc, value) {
|
|
32
32
|
return value < acc ? acc : null;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -37,22 +37,4 @@ export class CountMapper extends ManyToOneMapper {
|
|
|
37
37
|
return values.toArray().length;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
export function parseReactiveResponse(header) {
|
|
41
|
-
const strReactiveResponse = typeof header == "string"
|
|
42
|
-
? header
|
|
43
|
-
: header.get("Skip-Reactive-Response-Token");
|
|
44
|
-
if (!strReactiveResponse)
|
|
45
|
-
return undefined;
|
|
46
|
-
return JSON.parse(strReactiveResponse, (key, value) => {
|
|
47
|
-
if (key == "watermark")
|
|
48
|
-
return BigInt(value);
|
|
49
|
-
return value;
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
export function reactiveResponseHeader(reactiveResponse) {
|
|
53
|
-
return [
|
|
54
|
-
"Skip-Reactive-Response-Token",
|
|
55
|
-
JSON.stringify(reactiveResponse, (_key, value) => typeof value === "bigint" ? value.toString() : value),
|
|
56
|
-
];
|
|
57
|
-
}
|
|
58
40
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skipruntime/helpers",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
@@ -20,8 +20,11 @@
|
|
|
20
20
|
"node": ">=22.6.0 <23.0.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
+
"eventsource": "^2.0.2",
|
|
23
24
|
"express": "^4.21.0",
|
|
24
|
-
"@skipruntime/
|
|
25
|
-
|
|
25
|
+
"@skipruntime/api": "^0.0.3"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/eventsource": "^1.1.15"
|
|
26
29
|
}
|
|
27
30
|
}
|
package/src/external.ts
CHANGED
|
@@ -1,35 +1,30 @@
|
|
|
1
|
-
import type { Entry, ExternalService,
|
|
1
|
+
import type { Entry, ExternalService, Json } from "@skipruntime/api";
|
|
2
2
|
import { fetchJSON } from "./rest.js";
|
|
3
3
|
|
|
4
4
|
export interface ExternalResource {
|
|
5
5
|
open(
|
|
6
|
-
params:
|
|
6
|
+
params: { [param: string]: string | number },
|
|
7
7
|
callbacks: {
|
|
8
|
-
update: (updates: Entry<
|
|
9
|
-
error: (error:
|
|
8
|
+
update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
|
|
9
|
+
error: (error: Json) => void;
|
|
10
10
|
loading: () => void;
|
|
11
11
|
},
|
|
12
|
-
reactiveAuth?: Uint8Array,
|
|
13
12
|
): void;
|
|
14
13
|
|
|
15
|
-
close(
|
|
16
|
-
params: Record<string, string | number>,
|
|
17
|
-
reactiveAuth?: Uint8Array,
|
|
18
|
-
): void;
|
|
14
|
+
close(params: { [param: string]: string | number }): void;
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
export class GenericExternalService implements ExternalService {
|
|
22
|
-
constructor(private resources:
|
|
18
|
+
constructor(private resources: { [name: string]: ExternalResource }) {}
|
|
23
19
|
|
|
24
20
|
subscribe(
|
|
25
21
|
resourceName: string,
|
|
26
|
-
params:
|
|
22
|
+
params: { [param: string]: string | number },
|
|
27
23
|
callbacks: {
|
|
28
|
-
update: (updates: Entry<
|
|
29
|
-
error: (error:
|
|
24
|
+
update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
|
|
25
|
+
error: (error: Json) => void;
|
|
30
26
|
loading: () => void;
|
|
31
27
|
},
|
|
32
|
-
reactiveAuth?: Uint8Array,
|
|
33
28
|
): void {
|
|
34
29
|
const resource = this.resources[resourceName] as
|
|
35
30
|
| ExternalResource
|
|
@@ -37,21 +32,17 @@ export class GenericExternalService implements ExternalService {
|
|
|
37
32
|
if (!resource) {
|
|
38
33
|
throw new Error(`Unkonwn resource named '${resourceName}'`);
|
|
39
34
|
}
|
|
40
|
-
resource.open(params, callbacks
|
|
35
|
+
resource.open(params, callbacks);
|
|
41
36
|
}
|
|
42
37
|
|
|
43
|
-
unsubscribe(
|
|
44
|
-
resourceName: string,
|
|
45
|
-
params: Record<string, string>,
|
|
46
|
-
reactiveAuth?: Uint8Array,
|
|
47
|
-
) {
|
|
38
|
+
unsubscribe(resourceName: string, params: { [param: string]: string }) {
|
|
48
39
|
const resource = this.resources[resourceName] as
|
|
49
40
|
| ExternalResource
|
|
50
41
|
| undefined;
|
|
51
42
|
if (!resource) {
|
|
52
43
|
throw new Error(`Unkonwn resource named '${resourceName}'`);
|
|
53
44
|
}
|
|
54
|
-
resource.close(params
|
|
45
|
+
resource.close(params);
|
|
55
46
|
}
|
|
56
47
|
|
|
57
48
|
shutdown(): void {
|
|
@@ -62,16 +53,15 @@ export class GenericExternalService implements ExternalService {
|
|
|
62
53
|
type Timeout = ReturnType<typeof setInterval>;
|
|
63
54
|
|
|
64
55
|
export class TimerResource implements ExternalResource {
|
|
65
|
-
private intervals = new Map<string,
|
|
56
|
+
private intervals = new Map<string, { [name: string]: Timeout }>();
|
|
66
57
|
|
|
67
58
|
open(
|
|
68
|
-
params:
|
|
59
|
+
params: { [param: string]: string | number },
|
|
69
60
|
callbacks: {
|
|
70
|
-
update: (updates: Entry<
|
|
71
|
-
error: (error:
|
|
61
|
+
update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
|
|
62
|
+
error: (error: Json) => void;
|
|
72
63
|
loading: () => void;
|
|
73
64
|
},
|
|
74
|
-
reactiveAuth?: Uint8Array,
|
|
75
65
|
) {
|
|
76
66
|
const time = new Date().getTime();
|
|
77
67
|
const values: Entry<string, number>[] = [];
|
|
@@ -79,13 +69,13 @@ export class TimerResource implements ExternalResource {
|
|
|
79
69
|
values.push([name, [time]]);
|
|
80
70
|
}
|
|
81
71
|
callbacks.update(values, true);
|
|
82
|
-
const id = toId(params
|
|
83
|
-
const intervals:
|
|
72
|
+
const id = toId(params);
|
|
73
|
+
const intervals: { [name: string]: Timeout } = {};
|
|
84
74
|
for (const [name, duration] of Object.entries(params)) {
|
|
85
75
|
const ms = Number(duration);
|
|
86
76
|
if (ms > 0) {
|
|
87
77
|
intervals[name] = setInterval(() => {
|
|
88
|
-
const newvalue: Entry<
|
|
78
|
+
const newvalue: Entry<Json, Json> = [name, [new Date().getTime()]];
|
|
89
79
|
callbacks.update([newvalue], true);
|
|
90
80
|
}, ms);
|
|
91
81
|
}
|
|
@@ -93,11 +83,8 @@ export class TimerResource implements ExternalResource {
|
|
|
93
83
|
this.intervals.set(id, intervals);
|
|
94
84
|
}
|
|
95
85
|
|
|
96
|
-
close(
|
|
97
|
-
|
|
98
|
-
reactiveAuth?: Uint8Array,
|
|
99
|
-
): void {
|
|
100
|
-
const intervals = this.intervals.get(toId(params, reactiveAuth));
|
|
86
|
+
close(params: { [param: string]: string | number }): void {
|
|
87
|
+
const intervals = this.intervals.get(toId(params));
|
|
101
88
|
if (intervals != null) {
|
|
102
89
|
for (const interval of Object.values(intervals)) {
|
|
103
90
|
clearInterval(interval);
|
|
@@ -106,7 +93,7 @@ export class TimerResource implements ExternalResource {
|
|
|
106
93
|
}
|
|
107
94
|
}
|
|
108
95
|
|
|
109
|
-
export class Polled<S extends
|
|
96
|
+
export class Polled<S extends Json, K extends Json, V extends Json>
|
|
110
97
|
implements ExternalResource
|
|
111
98
|
{
|
|
112
99
|
private intervals = new Map<string, Timeout>();
|
|
@@ -118,20 +105,19 @@ export class Polled<S extends TJSON, K extends TJSON, V extends TJSON>
|
|
|
118
105
|
) {}
|
|
119
106
|
|
|
120
107
|
open(
|
|
121
|
-
params:
|
|
108
|
+
params: { [param: string]: string | number },
|
|
122
109
|
callbacks: {
|
|
123
|
-
update: (updates: Entry<
|
|
124
|
-
error: (error:
|
|
110
|
+
update: (updates: Entry<Json, Json>[], isInit: boolean) => void;
|
|
111
|
+
error: (error: Json) => void;
|
|
125
112
|
loading: () => void;
|
|
126
113
|
},
|
|
127
|
-
reactiveAuth?: Uint8Array,
|
|
128
114
|
): void {
|
|
129
|
-
this.close(params
|
|
130
|
-
const
|
|
115
|
+
this.close(params);
|
|
116
|
+
const queryParams: { [param: string]: string } = {};
|
|
131
117
|
for (const [key, value] of Object.entries(params)) {
|
|
132
|
-
|
|
118
|
+
queryParams[key] = value.toString();
|
|
133
119
|
}
|
|
134
|
-
const strParams = new URLSearchParams(
|
|
120
|
+
const strParams = new URLSearchParams(queryParams).toString();
|
|
135
121
|
const url = `${this.url}?${strParams}`;
|
|
136
122
|
const call = () => {
|
|
137
123
|
callbacks.loading();
|
|
@@ -145,30 +131,20 @@ export class Polled<S extends TJSON, K extends TJSON, V extends TJSON>
|
|
|
145
131
|
});
|
|
146
132
|
};
|
|
147
133
|
call();
|
|
148
|
-
this.intervals.set(
|
|
149
|
-
toId(params, reactiveAuth),
|
|
150
|
-
setInterval(call, this.duration),
|
|
151
|
-
);
|
|
134
|
+
this.intervals.set(toId(params), setInterval(call, this.duration));
|
|
152
135
|
}
|
|
153
136
|
|
|
154
|
-
close(
|
|
155
|
-
|
|
156
|
-
reactiveAuth?: Uint8Array,
|
|
157
|
-
): void {
|
|
158
|
-
const interval = this.intervals.get(toId(params, reactiveAuth));
|
|
137
|
+
close(params: { [param: string]: string | number }): void {
|
|
138
|
+
const interval = this.intervals.get(toId(params));
|
|
159
139
|
if (interval) {
|
|
160
140
|
clearInterval(interval);
|
|
161
141
|
}
|
|
162
142
|
}
|
|
163
143
|
}
|
|
164
144
|
|
|
165
|
-
function toId(
|
|
166
|
-
params: Record<string, string | number>,
|
|
167
|
-
reactiveAuth?: Uint8Array,
|
|
168
|
-
): string {
|
|
145
|
+
function toId(params: { [param: string]: string | number }): string {
|
|
169
146
|
const strparams = Object.entries(params)
|
|
170
147
|
.map(([key, value]) => `${key}:${value.toString()}`)
|
|
171
148
|
.sort();
|
|
172
|
-
|
|
173
|
-
return `[${strparams.join(",")}]${hex}`;
|
|
149
|
+
return `[${strparams.join(",")}]`;
|
|
174
150
|
}
|
package/src/index.ts
CHANGED
|
@@ -4,11 +4,5 @@ export {
|
|
|
4
4
|
GenericExternalService,
|
|
5
5
|
Polled,
|
|
6
6
|
} from "./external.js";
|
|
7
|
-
export {
|
|
8
|
-
|
|
9
|
-
Min,
|
|
10
|
-
Max,
|
|
11
|
-
CountMapper,
|
|
12
|
-
parseReactiveResponse,
|
|
13
|
-
reactiveResponseHeader,
|
|
14
|
-
} from "./utils.js";
|
|
7
|
+
export { Sum, Min, Max, CountMapper } from "./utils.js";
|
|
8
|
+
export { RESTWrapperOfSkipService } from "./rest.js";
|
package/src/remote.ts
CHANGED
|
@@ -1,158 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
ReactiveResponse,
|
|
5
|
-
TJSON,
|
|
6
|
-
} from "@skipruntime/api";
|
|
7
|
-
import { parseReactiveResponse } from "./utils.js";
|
|
1
|
+
// TODO: Remove once global `EventSource` makes it out of experimental
|
|
2
|
+
// in nodejs LTS.
|
|
3
|
+
import EventSource from "eventsource";
|
|
8
4
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
5
|
+
import type { Entry, ExternalService, Json } from "@skipruntime/api";
|
|
6
|
+
|
|
7
|
+
import type { Entrypoint } from "./rest.js";
|
|
11
8
|
|
|
12
9
|
interface Closable {
|
|
13
10
|
close(): void;
|
|
14
11
|
}
|
|
15
12
|
|
|
16
13
|
export class SkipExternalService implements ExternalService {
|
|
17
|
-
private client?: Promise<[Client, Protocol.Creds]>;
|
|
18
14
|
private resources = new Map<string, Closable>();
|
|
19
15
|
|
|
20
16
|
constructor(
|
|
21
17
|
private url: string,
|
|
22
|
-
private
|
|
23
|
-
resource: string,
|
|
24
|
-
params: Record<string, string>,
|
|
25
|
-
reactiveAuth: Uint8Array,
|
|
26
|
-
) => Promise<ReactiveResponse>,
|
|
27
|
-
private creds?: Protocol.Creds,
|
|
18
|
+
private control_url: string,
|
|
28
19
|
) {}
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
let url = `ws://${entrypoint.host}:${entrypoint.port.toString()}`;
|
|
40
|
-
if (entrypoint.secured)
|
|
41
|
-
url = `wss://${entrypoint.host}:${entrypoint.port.toString()}`;
|
|
42
|
-
return new SkipExternalService(url, auth, creds);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
static direct(
|
|
46
|
-
entrypoint: Entrypoint,
|
|
47
|
-
creds?: Protocol.Creds,
|
|
48
|
-
): SkipExternalService {
|
|
49
|
-
let url = `http://${entrypoint.host}:${entrypoint.port.toString()}`;
|
|
50
|
-
if (entrypoint.secured)
|
|
51
|
-
url = `https://${entrypoint.host}:${entrypoint.port.toString()}`;
|
|
52
|
-
const auth = async (
|
|
53
|
-
resource: string,
|
|
54
|
-
params: Record<string, string>,
|
|
55
|
-
reactiveAuth: Uint8Array,
|
|
56
|
-
) => {
|
|
57
|
-
const qParams = new URLSearchParams(params).toString();
|
|
58
|
-
const header = {
|
|
59
|
-
"X-Reactive-Auth": Buffer.from(reactiveAuth).toString("base64"),
|
|
60
|
-
};
|
|
61
|
-
const [_data, headers] = await fetchJSON(
|
|
62
|
-
`${url}/v1/${resource}?${qParams}`,
|
|
63
|
-
"HEAD",
|
|
64
|
-
header,
|
|
65
|
-
);
|
|
66
|
-
const reactiveResponse = parseReactiveResponse(headers);
|
|
67
|
-
if (!reactiveResponse)
|
|
68
|
-
throw new Error("Reactive response must be suplied.");
|
|
69
|
-
return reactiveResponse;
|
|
70
|
-
};
|
|
71
|
-
return new SkipExternalService(url, auth, creds);
|
|
21
|
+
// TODO: Support Skip external services going through a gateway.
|
|
22
|
+
static direct(entrypoint: Entrypoint): SkipExternalService {
|
|
23
|
+
let url = `http://${entrypoint.host}:${entrypoint.streaming_port.toString()}`;
|
|
24
|
+
let control_url = `http://${entrypoint.host}:${entrypoint.control_port.toString()}`;
|
|
25
|
+
if (entrypoint.secured) {
|
|
26
|
+
url = `https://${entrypoint.host}:${entrypoint.streaming_port.toString()}`;
|
|
27
|
+
control_url = `https://${entrypoint.host}:${entrypoint.control_port.toString()}`;
|
|
28
|
+
}
|
|
29
|
+
return new SkipExternalService(url, control_url);
|
|
72
30
|
}
|
|
73
31
|
|
|
74
32
|
subscribe(
|
|
75
33
|
resource: string,
|
|
76
|
-
params:
|
|
34
|
+
params: { [param: string]: string },
|
|
77
35
|
callbacks: {
|
|
78
|
-
update: (updates: Entry<
|
|
79
|
-
|
|
36
|
+
update: (updates: Entry<Json, Json>[], isInitial: boolean) => void;
|
|
37
|
+
// FIXME: What is `error()` used for?
|
|
38
|
+
error: (error: Json) => void;
|
|
39
|
+
// FIXME: What is `loading()` used for?
|
|
80
40
|
loading: () => void;
|
|
81
41
|
},
|
|
82
|
-
reactiveAuth?: Uint8Array,
|
|
83
42
|
): void {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
43
|
+
// TODO Manage Status
|
|
44
|
+
fetch(`${this.control_url}/v1/streams`, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers: {
|
|
47
|
+
"Content-Type": "application/json",
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({
|
|
50
|
+
resource,
|
|
51
|
+
params,
|
|
52
|
+
}),
|
|
53
|
+
})
|
|
54
|
+
.then((resp) => resp.json())
|
|
55
|
+
.then((uuid) => {
|
|
56
|
+
const evSource = new EventSource(`${this.url}/v1/streams/${uuid}`);
|
|
57
|
+
evSource.addEventListener("init", (e: MessageEvent<string>) => {
|
|
58
|
+
const updates = JSON.parse(e.data) as Entry<Json, Json>[];
|
|
59
|
+
callbacks.update(updates, true);
|
|
89
60
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
61
|
+
evSource.addEventListener("update", (e: MessageEvent<string>) => {
|
|
62
|
+
const updates = JSON.parse(e.data) as Entry<Json, Json>[];
|
|
63
|
+
callbacks.update(updates, false);
|
|
93
64
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
65
|
+
evSource.onerror = (e) => {
|
|
66
|
+
console.log(e);
|
|
67
|
+
};
|
|
68
|
+
this.resources.set(this.toId(resource, params), evSource);
|
|
69
|
+
})
|
|
70
|
+
.catch((e: unknown) => {
|
|
71
|
+
console.log(e);
|
|
72
|
+
});
|
|
101
73
|
}
|
|
102
74
|
|
|
103
|
-
unsubscribe(
|
|
104
|
-
resource
|
|
105
|
-
params: Record<string, string>,
|
|
106
|
-
reactiveAuth?: Uint8Array,
|
|
107
|
-
) {
|
|
108
|
-
const closable = this.resources.get(
|
|
109
|
-
this.toId(resource, params, reactiveAuth),
|
|
110
|
-
);
|
|
75
|
+
unsubscribe(resource: string, params: { [param: string]: string }) {
|
|
76
|
+
const closable = this.resources.get(this.toId(resource, params));
|
|
111
77
|
if (closable) closable.close();
|
|
112
78
|
}
|
|
113
79
|
|
|
114
80
|
shutdown(): void {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.then((client) => {
|
|
118
|
-
client[0].close();
|
|
119
|
-
})
|
|
120
|
-
.catch((e: unknown) => console.error(e));
|
|
81
|
+
for (const res of this.resources.values()) {
|
|
82
|
+
res.close();
|
|
121
83
|
}
|
|
122
84
|
}
|
|
123
85
|
|
|
124
|
-
private
|
|
125
|
-
|
|
126
|
-
params: Record<string, string>,
|
|
127
|
-
callbacks: {
|
|
128
|
-
update: (updates: Entry<TJSON, TJSON>[], isInit: boolean) => void;
|
|
129
|
-
error: (error: TJSON) => void;
|
|
130
|
-
loading: () => void;
|
|
131
|
-
},
|
|
132
|
-
reactiveAuth?: Uint8Array,
|
|
133
|
-
): Promise<void> {
|
|
134
|
-
const [client, creds] = await this.client!;
|
|
135
|
-
const publicKey = new Uint8Array(await Protocol.exportKey(creds.publicKey));
|
|
136
|
-
const reactive = await this.auth(resource, params, publicKey);
|
|
137
|
-
// TODO Manage Status
|
|
138
|
-
const close = client.subscribe(
|
|
139
|
-
reactive.collection,
|
|
140
|
-
BigInt(reactive.watermark),
|
|
141
|
-
callbacks.update,
|
|
142
|
-
);
|
|
143
|
-
this.resources.set(this.toId(resource, params, reactiveAuth), close);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private toId(
|
|
147
|
-
resource: string,
|
|
148
|
-
params: Record<string, string>,
|
|
149
|
-
reactiveAuth?: Uint8Array,
|
|
150
|
-
): string {
|
|
86
|
+
private toId(resource: string, params: { [param: string]: string }): string {
|
|
87
|
+
// TODO: This is equivalent to `querystring.encode(params, ',', ':')`.
|
|
151
88
|
const strparams: string[] = [];
|
|
152
89
|
for (const key of Object.keys(params).sort()) {
|
|
153
90
|
strparams.push(`${key}:${params[key]}`);
|
|
154
91
|
}
|
|
155
|
-
|
|
156
|
-
return `${resource}[${strparams.join(",")}]${hex}`;
|
|
92
|
+
return `${resource}[${strparams.join(",")}]`;
|
|
157
93
|
}
|
|
158
94
|
}
|