@rdfc/js-runner 3.1.0-alpha.1 → 3.1.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/__tests__/channels.test.ts +9 -5
- package/lib/reader.js +2 -1
- package/lib/runner.js +2 -2
- package/lib/testUtils/index.js +7 -3
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/writer.d.ts +5 -8
- package/lib/writer.js +39 -72
- package/package.json +2 -2
- package/src/reader.ts +2 -0
- package/src/runner.ts +1 -1
- package/src/testUtils/index.ts +6 -2
- package/src/writer.ts +104 -111
- package/dist/args.d.ts +0 -4
- package/dist/args.js +0 -58
- package/dist/connectors/file.d.ts +0 -15
- package/dist/connectors/file.js +0 -89
- package/dist/connectors/http.d.ts +0 -14
- package/dist/connectors/http.js +0 -82
- package/dist/connectors/kafka.d.ts +0 -48
- package/dist/connectors/kafka.js +0 -68
- package/dist/connectors/ws.d.ts +0 -10
- package/dist/connectors/ws.js +0 -72
- package/dist/connectors.d.ts +0 -73
- package/dist/connectors.js +0 -168
- package/dist/index.cjs +0 -732
- package/dist/index.d.ts +0 -42
- package/dist/index.js +0 -83
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/util.d.ts +0 -71
- package/dist/util.js +0 -92
package/lib/writer.js
CHANGED
|
@@ -11,7 +11,6 @@ export class WriterInstance {
|
|
|
11
11
|
shouldClose = [];
|
|
12
12
|
closed = false;
|
|
13
13
|
_canceled = false;
|
|
14
|
-
cancelSignal = new AbortController();
|
|
15
14
|
cancelHandlers = new Set();
|
|
16
15
|
runnerId;
|
|
17
16
|
constructor(uri, client, notifyOrchestrator, runnerId, logger) {
|
|
@@ -33,51 +32,6 @@ export class WriterInstance {
|
|
|
33
32
|
cancellationError() {
|
|
34
33
|
return new Error(`Writer for channel ${this.uri} was canceled by the connected reader`);
|
|
35
34
|
}
|
|
36
|
-
emitCancel() {
|
|
37
|
-
for (const handler of this.cancelHandlers) {
|
|
38
|
-
try {
|
|
39
|
-
Promise.resolve(handler()).catch((error) => {
|
|
40
|
-
this.logger.error(`Cancel listener for channel ${this.uri} failed: ${String(error)}`);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
this.logger.error(`Cancel listener for channel ${this.uri} failed: ${String(error)}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
assertCanWrite() {
|
|
49
|
-
if (this._canceled) {
|
|
50
|
-
throw this.cancellationError();
|
|
51
|
-
}
|
|
52
|
-
if (this.closed) {
|
|
53
|
-
throw new Error(`Writer for channel ${this.uri} is closed`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async raceWithCancellation(promise) {
|
|
57
|
-
this.assertCanWrite();
|
|
58
|
-
return await new Promise((resolve, reject) => {
|
|
59
|
-
const onAbort = () => reject(this.cancellationError());
|
|
60
|
-
this.cancelSignal.signal.addEventListener('abort', onAbort, {
|
|
61
|
-
once: true,
|
|
62
|
-
});
|
|
63
|
-
promise.then((value) => {
|
|
64
|
-
this.cancelSignal.signal.removeEventListener('abort', onAbort);
|
|
65
|
-
resolve(value);
|
|
66
|
-
}, (error) => {
|
|
67
|
-
this.cancelSignal.signal.removeEventListener('abort', onAbort);
|
|
68
|
-
reject(error);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
rejectPendingProcessed(error) {
|
|
73
|
-
while (this.awaitingProcessed.length > 0) {
|
|
74
|
-
this.awaitingProcessed.shift().reject(error);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
awaitProcessed() {
|
|
78
|
-
this.assertCanWrite();
|
|
79
|
-
return new Promise((resolve, reject) => this.awaitingProcessed.push({ resolve, reject }));
|
|
80
|
-
}
|
|
81
35
|
async any(any) {
|
|
82
36
|
if ('stream' in any) {
|
|
83
37
|
await this.stream(any.stream);
|
|
@@ -89,6 +43,14 @@ export class WriterInstance {
|
|
|
89
43
|
await this.string(any.string);
|
|
90
44
|
}
|
|
91
45
|
}
|
|
46
|
+
assertCanWrite() {
|
|
47
|
+
if (this._canceled) {
|
|
48
|
+
throw this.cancellationError();
|
|
49
|
+
}
|
|
50
|
+
if (this.closed) {
|
|
51
|
+
throw new Error(`Writer for channel ${this.uri} is closed`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
92
54
|
async buffer(buffer) {
|
|
93
55
|
this.assertCanWrite();
|
|
94
56
|
this.logger.debug(`${this.uri} sends buffer ${buffer.length} bytes`);
|
|
@@ -115,7 +77,7 @@ export class WriterInstance {
|
|
|
115
77
|
runner: this.runnerId,
|
|
116
78
|
},
|
|
117
79
|
});
|
|
118
|
-
const id = await
|
|
80
|
+
const id = await new Promise((res) => stream.once('data', res));
|
|
119
81
|
this.logger.debug(`${this.uri} streams message with id ${JSON.stringify(id)}`);
|
|
120
82
|
for await (const msg of buffer) {
|
|
121
83
|
const processedPromise = new Promise((res) => stream.once('data', res));
|
|
@@ -150,43 +112,35 @@ export class WriterInstance {
|
|
|
150
112
|
await handledPromise;
|
|
151
113
|
}
|
|
152
114
|
async close(issued = false) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
this.closed = true;
|
|
159
|
-
const cancelError = this.cancellationError();
|
|
160
|
-
this.rejectPendingProcessed(cancelError);
|
|
161
|
-
this.cancelSignal.abort(cancelError);
|
|
162
|
-
let waiting = this.shouldClose.pop();
|
|
163
|
-
while (waiting) {
|
|
164
|
-
waiting();
|
|
165
|
-
waiting = this.shouldClose.pop();
|
|
166
|
-
}
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (this.closed) {
|
|
170
|
-
return;
|
|
115
|
+
this.closed = true;
|
|
116
|
+
if (issued && !this._canceled) {
|
|
117
|
+
this._canceled = true;
|
|
118
|
+
await this.emitCancel();
|
|
171
119
|
}
|
|
172
120
|
if (this.openStreams !== 0) {
|
|
173
121
|
await new Promise((resolve) => this.shouldClose.push(resolve));
|
|
174
122
|
return;
|
|
175
123
|
}
|
|
176
124
|
this.logger.debug(`${this.uri} closes stream`);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
125
|
+
if (!issued) {
|
|
126
|
+
await this.notifyOrchestrator({
|
|
127
|
+
close: { channel: this.uri },
|
|
128
|
+
});
|
|
129
|
+
}
|
|
181
130
|
let resolve = this.shouldClose.pop();
|
|
182
131
|
while (resolve) {
|
|
183
132
|
resolve();
|
|
184
133
|
resolve = this.shouldClose.pop();
|
|
185
134
|
}
|
|
186
135
|
}
|
|
187
|
-
handled() {
|
|
136
|
+
handled(error) {
|
|
188
137
|
if (this.awaitingProcessed.length > 0) {
|
|
189
|
-
|
|
138
|
+
if (error) {
|
|
139
|
+
this.awaitingProcessed.shift().reject(new Error(error));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.awaitingProcessed.shift().resolve();
|
|
143
|
+
}
|
|
190
144
|
}
|
|
191
145
|
else if (this.closed || this._canceled) {
|
|
192
146
|
return;
|
|
@@ -196,5 +150,18 @@ export class WriterInstance {
|
|
|
196
150
|
this.uri);
|
|
197
151
|
}
|
|
198
152
|
}
|
|
153
|
+
async emitCancel() {
|
|
154
|
+
await Promise.all(Array.from(this.cancelHandlers).map(async (handler) => {
|
|
155
|
+
try {
|
|
156
|
+
await handler();
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
this.logger.error(`Cancel listener for channel ${this.uri} failed: ${String(error)}`);
|
|
160
|
+
}
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
awaitProcessed() {
|
|
164
|
+
return new Promise((resolve, reject) => this.awaitingProcessed.push({ resolve, reject }));
|
|
165
|
+
}
|
|
199
166
|
}
|
|
200
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBeUJoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEdBQUcsQ0FBUTtJQUNwQixtQkFBbUIsR0FBVyxDQUFDLENBQUE7SUFDZCxNQUFNLENBQWM7SUFDcEIsa0JBQWtCLENBQVU7SUFDNUIsTUFBTSxDQUFRO0lBR3ZCLGlCQUFpQixHQUdwQixFQUFFLENBQUE7SUFFQyxXQUFXLEdBQVcsQ0FBQyxDQUFBO0lBRXZCLFdBQVcsR0FBc0IsRUFBRSxDQUFBO0lBQ25DLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDZCxTQUFTLEdBQUcsS0FBSyxDQUFBO0lBR1IsWUFBWSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUE7SUFFcEMsY0FBYyxHQUFHLElBQUksR0FBRyxFQUFXLENBQUE7SUFFbkMsUUFBUSxDQUFRO0lBRWpDLFlBQ0UsR0FBVyxFQUNYLE1BQW9CLEVBQ3BCLGtCQUE0QixFQUM1QixRQUFnQixFQUNoQixNQUFjO1FBRWQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFBO1FBQzVDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFBO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDMUIsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQTtJQUN2QixDQUFDO0lBRUQsRUFBRSxDQUFDLEtBQWUsRUFBRSxRQUFpQjtRQUNuQyxJQUFJLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN2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RUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtTQUM3QixDQUFDLENBQUE7UUFFRixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ3BDLE9BQU8sT0FBTyxFQUFFLENBQUM7WUFDZixPQUFPLEVBQUUsQ0FBQTtZQUNULE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBS0QsT0FBTztRQUNMLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFHLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDM0MsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFFekMsT0FBTTtRQUNSLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2YsaUZBQWlGO2dCQUMvRSxJQUFJLENBQUMsR0FBRyxDQUNYLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRnJvbVJ1bm5lciwgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnd2luc3RvbidcbmltcG9ydCB7IEFueSB9IGZyb20gJy4vcmVhZGVyJ1xuXG50eXBlIFdyaXRhYmxlID0gKG1zZzogRnJvbVJ1bm5lcikgPT4gUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IHR5cGUgSGFuZGxlcjxUID0gdm9pZD4gPSBbVF0gZXh0ZW5kcyBbdm9pZF1cbiAgPyAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPlxuICA6ICh2YWx1ZTogVCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD5cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICByZWFkb25seSB1cmk6IHN0cmluZ1xuICByZWFkb25seSBjYW5jZWxlZDogYm9vbGVhblxuICBvbihldmVudDogJ2NhbmNlbCcsIGxpc3RlbmVyOiBIYW5kbGVyKTogdGhpc1xuICBidWZmZXIoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmVhbShidWZmZXI6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBQcm9taXNlPHZvaWQ+XG4gIHN0cmVhbTxUPihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtOiAoeDogVCkgPT4gVWludDhBcnJheSxcbiAgKTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmluZyhidWZmZXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cbiAgYW55KGFueTogQW55KTogUHJvbWlzZTx2b2lkPlxuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+XG59XG5jb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKClcbmV4cG9ydCBjbGFzcyBXcml0ZXJJbnN0YW5jZSBpbXBsZW1lbnRzIFdyaXRlciB7XG4gIHJlYWRvbmx5IHVyaTogc3RyaW5nXG4gIGxvY2FsU2VxdWVuY2VOdW1iZXI6IG51bWJlciA9IDFcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFJ1bm5lckNsaWVudFxuICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGVcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlclxuXG4gIC8vIEZJRk8gb2YgbWVzc2FnZS1sZXZlbCBhY2tub3dsZWRnZW1lbnRzIGNvbWluZyBiYWNrIGZyb20gdGhlIG9yY2hlc3RyYXRvci5cbiAgcHJpdmF0ZSBhd2FpdGluZ1Byb2Nlc3NlZDogQXJyYXk8e1xuICAgIHJlc29sdmU6ICgpID0+IHZvaWRcbiAgICByZWplY3Q6IChyZWFzb246IEVycm9yKSA9PiB2b2lkXG4gIH0+ID0gW11cblxuICBwcml2YXRlIG9wZW5TdHJlYW1zOiBudW1iZXIgPSAwXG4gIC8vIENsb3NlIGNhbGxlcnMgd2FpdCBoZXJlIHdoaWxlIGFjdGl2ZSBzdHJlYW1zIGFyZSBzdGlsbCBmbHVzaGluZy5cbiAgcHJpdmF0ZSBzaG91bGRDbG9zZTogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXVxuICBwcml2YXRlIGNsb3NlZCA9IGZhbHNlXG4gIHByaXZhdGUgX2NhbmNlbGVkID0gZmFsc2VcblxuICAvLyBTaGFyZWQgY2FuY2VsbGF0aW9uIHNpZ25hbCB0byBhYm9ydCBpbi1mbGlnaHQgd2FpdHMgd2hlbiB0aGUgcmVtb3RlIGNsb3Nlcy5cbiAgcHJpdmF0ZSByZWFkb25seSBjYW5jZWxTaWduYWwgPSBuZXcgQWJvcnRDb250cm9sbGVyKClcbiAgLy8gUHJvY2Vzc29ycyBjYW4gc3Vic2NyaWJlIGhlcmUgdG8gc3RvcCB1cHN0cmVhbSB3b3JrIHdoZW4gZG93bnN0cmVhbSBjYW5jZWxzLlxuICBwcml2YXRlIHJlYWRvbmx5IGNhbmNlbEhhbmRsZXJzID0gbmV3IFNldDxIYW5kbGVyPigpXG5cbiAgcHJpdmF0ZSByZWFkb25seSBydW5uZXJJZDogc3RyaW5nXG5cbiAgY29uc3RydWN0b3IoXG4gICAgdXJpOiBzdHJpbmcsXG4gICAgY2xpZW50OiBSdW5uZXJDbGllbnQsXG4gICAgbm90aWZ5T3JjaGVzdHJhdG9yOiBXcml0YWJsZSxcbiAgICBydW5uZXJJZDogc3RyaW5nLFxuICAgIGxvZ2dlcjogTG9nZ2VyLFxuICApIHtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudFxuICAgIHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yID0gbm90aWZ5T3JjaGVzdHJhdG9yXG4gICAgdGhpcy51cmkgPSB1cmlcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlclxuICAgIHRoaXMucnVubmVySWQgPSBydW5uZXJJZFxuICB9XG5cbiAgZ2V0IGNhbmNlbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9jYW5jZWxlZFxuICB9XG5cbiAgb24oZXZlbnQ6ICdjYW5jZWwnLCBsaXN0ZW5lcjogSGFuZGxlcik6IHRoaXMge1xuICAgIGlmIChldmVudCA9PT0gJ2NhbmNlbCcpIHtcbiAgICAgIHRoaXMuY2FuY2VsSGFuZGxlcnMuYWRkKGxpc3RlbmVyKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBwcml2YXRlIGNhbmNlbGxhdGlvbkVycm9yKCk6IEVycm9yIHtcbiAgICByZXR1cm4gbmV3IEVycm9yKFxuICAgICAgYFdyaXRlciBmb3IgY2hhbm5lbCAke3RoaXMudXJpfSB3YXMgY2FuY2VsZWQgYnkgdGhlIGNvbm5lY3RlZCByZWFkZXJgLFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgZW1pdENhbmNlbCgpIHtcbiAgICBmb3IgKGNvbnN0IGhhbmRsZXIgb2YgdGhpcy5jYW5jZWxIYW5kbGVycykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKGhhbmRsZXIoKSkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICBgQ2FuY2VsIGxpc3RlbmVyIGZvciBjaGFubmVsICR7dGhpcy51cml9IGZhaWxlZDogJHtTdHJpbmcoZXJyb3IpfWAsXG4gICAgICAgICAgKVxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgYENhbmNlbCBsaXN0ZW5lciBmb3IgY2hhbm5lbCAke3RoaXMudXJpfSBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX1gLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3NlcnRDYW5Xcml0ZSgpIHtcbiAgICBpZiAodGhpcy5fY2FuY2VsZWQpIHtcbiAgICAgIHRocm93IHRoaXMuY2FuY2VsbGF0aW9uRXJyb3IoKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBXcml0ZXIgZm9yIGNoYW5uZWwgJHt0aGlzLnVyaX0gaXMgY2xvc2VkYClcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJhY2VXaXRoQ2FuY2VsbGF0aW9uPFQ+KHByb21pc2U6IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICB0aGlzLmFzc2VydENhbldyaXRlKClcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4gcmVqZWN0KHRoaXMuY2FuY2VsbGF0aW9uRXJyb3IoKSlcbiAgICAgIHRoaXMuY2FuY2VsU2lnbmFsLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQsIHtcbiAgICAgICAgb25jZTogdHJ1ZSxcbiAgICAgIH0pXG5cbiAgICAgIHByb21pc2UudGhlbihcbiAgICAgICAgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgLy8gQ2xlYW4gdXAgdGhlIGFib3J0IGxpc3RlbmVyIGlmIHRoZSBvcmlnaW5hbCBvcGVyYXRpb24gZmluaXNoZWQgZmlyc3QuXG4gICAgICAgICAgdGhpcy5jYW5jZWxTaWduYWwuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydClcbiAgICAgICAgICByZXNvbHZlKHZhbHVlKVxuICAgICAgICB9LFxuICAgICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgICB0aGlzLmNhbmNlbFNpZ25hbC5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkFib3J0KVxuICAgICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgICAgfSxcbiAgICAgIClcbiAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSByZWplY3RQZW5kaW5nUHJvY2Vzc2VkKGVycm9yOiBFcnJvcikge1xuICAgIC8vIFJlamVjdCBhbGwgcXVldWVkIG1lc3NhZ2Ugd2FpdHMgc28gY2FsbGVycyBkbyBub3QgaGFuZyBkdXJpbmcgY2FuY2VsbGF0aW9uLlxuICAgIHdoaWxlICh0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEucmVqZWN0KGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXdhaXRQcm9jZXNzZWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+XG4gICAgICB0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLnB1c2goeyByZXNvbHZlLCByZWplY3QgfSksXG4gICAgKVxuICB9XG5cbiAgYXN5bmMgYW55KGFueTogQW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCdzdHJlYW0nIGluIGFueSkge1xuICAgICAgYXdhaXQgdGhpcy5zdHJlYW0oYW55LnN0cmVhbSlcbiAgICB9XG4gICAgaWYgKCdidWZmZXInIGluIGFueSkge1xuICAgICAgYXdhaXQgdGhpcy5idWZmZXIoYW55LmJ1ZmZlcilcbiAgICB9XG4gICAgaWYgKCdzdHJpbmcnIGluIGFueSkge1xuICAgICAgYXdhaXQgdGhpcy5zdHJpbmcoYW55LnN0cmluZylcbiAgICB9XG4gIH1cblxuICBhc3luYyBidWZmZXIoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7dGhpcy51cml9IHNlbmRzIGJ1ZmZlciAke2J1ZmZlci5sZW5ndGh9IGJ5dGVzYClcbiAgICBjb25zdCBsb2NhbFNlcXVlbmNlTnVtYmVyID0gdGhpcy5sb2NhbFNlcXVlbmNlTnVtYmVyKytcbiAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoKVxuXG4gICAgYXdhaXQgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3Ioe1xuICAgICAgbXNnOiB7IGRhdGE6IGJ1ZmZlciwgY2hhbm5lbDogdGhpcy51cmksIGxvY2FsU2VxdWVuY2VOdW1iZXIgfSxcbiAgICB9KVxuICAgIGF3YWl0IGhhbmRsZWRQcm9taXNlXG4gIH1cblxuICBhc3luYyBzdHJlYW08VCA9IFVpbnQ4QXJyYXk+KFxuICAgIGJ1ZmZlcjogQXN5bmNJdGVyYWJsZTxUPixcbiAgICB0cmFuc2Zvcm0/OiAoeDogVCkgPT4gVWludDhBcnJheSxcbiAgKSB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5vcGVuU3RyZWFtcyArPSAxXG4gICAgY29uc3QgdCA9IHRyYW5zZm9ybSB8fCAoKHg6IHVua25vd24pID0+IDxVaW50OEFycmF5PngpXG4gICAgY29uc3Qgc3RyZWFtID0gdGhpcy5jbGllbnQuc2VuZFN0cmVhbU1lc3NhZ2UoKVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE1lc3NhZ2UtbGV2ZWwgYWNrIHRoYXQgc2lnbmFscyB0aGUgd2hvbGUgc3RyZWFtIG1lc3NhZ2UgaXMgZnVsbHkgaGFuZGxlZC5cbiAgICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG4gICAgICBjb25zdCB3cml0ZVN0cmVhbU1lc3NhZ2VDaHVuayA9IHByb21pc2lmeShzdHJlYW0ud3JpdGUuYmluZChzdHJlYW0pKVxuICAgICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgICBhd2FpdCB3cml0ZVN0cmVhbU1lc3NhZ2VDaHVuayh7XG4gICAgICAgIGlkOiB7XG4gICAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgICAgbG9jYWxTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgICBydW5uZXI6IHRoaXMucnVubmVySWQsXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBGaXJzdCByZXNwb25zZSBjb25maXJtcyBzdHJlYW0gaWQgcmVnaXN0cmF0aW9uIG9uIHRoZSByZW1vdGUgc2lkZS5cbiAgICAgIGNvbnN0IGlkID0gYXdhaXQgdGhpcy5yYWNlV2l0aENhbmNlbGxhdGlvbihcbiAgICAgICAgbmV3IFByb21pc2UoKHJlcykgPT4gc3RyZWFtLm9uY2UoJ2RhdGEnLCByZXMpKSxcbiAgICAgIClcblxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGAke3RoaXMudXJpfSBzdHJlYW1zIG1lc3NhZ2Ugd2l0aCBpZCAke0pTT04uc3RyaW5naWZ5KGlkKX1gLFxuICAgICAgKVxuXG4gICAgICBmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBidWZmZXIpIHtcbiAgICAgICAgY29uc3QgcHJvY2Vzc2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcbiAgICAgICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoeyBkYXRhOiB7IGRhdGE6IHQobXNnKSB9IH0pXG4gICAgICAgIC8vIEF3YWl0IGEgbWVzc2FnZSBvbiB0aGUgc3RyZWFtLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNodW5rIGhhcyBiZWVuIHByb2Nlc3NlZFxuICAgICAgICBhd2FpdCBwcm9jZXNzZWRQcm9taXNlXG4gICAgICB9XG5cbiAgICAgIHN0cmVhbS5lbmQoKVxuXG4gICAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLm9wZW5TdHJlYW1zIC09IDFcblxuICAgICAgaWYgKCFzdHJlYW0ud3JpdGFibGVFbmRlZCkge1xuICAgICAgICBzdHJlYW0uZW5kKClcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYSBjbG9zZSBjYWxsIHdhcyBkZWZlcnJlZCB3aGlsZSBzdHJlYW1pbmcsIGNvbXBsZXRlIGl0IG5vdy5cbiAgICAgIGlmICh0aGlzLnNob3VsZENsb3NlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbG9zZSgpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc3RyaW5nKG1zZzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7dGhpcy51cml9IHNlbmRzIHN0cmluZyAke21zZy5sZW5ndGh9IGNoYXJhY3RlcnNgKVxuICAgIGNvbnN0IGxvY2FsU2VxdWVuY2VOdW1iZXIgPSB0aGlzLmxvY2FsU2VxdWVuY2VOdW1iZXIrK1xuICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG5cbiAgICBhd2FpdCB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvcih7XG4gICAgICBtc2c6IHtcbiAgICAgICAgZGF0YTogZW5jb2Rlci5lbmNvZGUobXNnKSxcbiAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgLyoqXG4gICAqIEdyYWNlZnVsbHkgY2xvc2VzIHRoaXMgY2hhbm5lbC5cbiAgICpcbiAgICogQmVoYXZpb3I6XG4gICAqIC0gSWYgdGhlcmUgYXJlIHN0aWxsIGFjdGl2ZSBzdHJlYW1zLCBjbG9zaW5nIGlzIGRlZmVycmVkIHVudGlsIHRoZXkgY29tcGxldGUuXG4gICAqIC0gSWYgbXVsdGlwbGUgY2FsbGVycyBpbnZva2UgYGNsb3NlKClgIHdoaWxlIHdhaXRpbmcsIHRoZWlyIFByb21pc2VzIGFyZSBxdWV1ZWQgYW5kXG4gICAqICAgcmVzb2x2ZWQgb25jZSB0aGUgY2hhbm5lbCBhY3R1YWxseSBjbG9zZXMuXG4gICAqIC0gSWYgdGhpcyBzaWRlIGluaXRpYXRlZCB0aGUgY2xvc2UgKGBpc3N1ZWQgPSBmYWxzZWApLCBhIGNsb3NlIG1lc3NhZ2UgaXMgc2VudCB0byB0aGUgcmVtb3RlLlxuICAgKlxuICAgKiBAcGFyYW0gaXNzdWVkIC0gSWYgdHJ1ZSwgaW5kaWNhdGVzIHRoZSBjbG9zZSByZXF1ZXN0IG9yaWdpbmF0ZWQgcmVtb3RlbHlcbiAgICovXG4gIGFzeW5jIGNsb3NlKGlzc3VlZCA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGlzc3VlZCkge1xuICAgICAgaWYgKCF0aGlzLmNsb3NlZCkge1xuICAgICAgICAvLyBSZW1vdGUgaW5pdGlhdGVkIGNsb3NlOiBtYXJrIHdyaXRlciBjYW5jZWxlZCB0byBmYWlsIGZ1dHVyZSB3cml0ZXMuXG4gICAgICAgIHRoaXMuX2NhbmNlbGVkID0gdHJ1ZVxuXG4gICAgICAgIC8vIE5vdGlmeSBwcm9jZXNzb3JzIHNvIHRoZXkgY2FuIHN0b3AgcHJvZHVjaW5nIHVwc3RyZWFtIHdvcmsgYXMgd2VsbC5cbiAgICAgICAgdGhpcy5lbWl0Q2FuY2VsKClcbiAgICAgIH1cbiAgICAgIHRoaXMuY2xvc2VkID0gdHJ1ZVxuXG4gICAgICBjb25zdCBjYW5jZWxFcnJvciA9IHRoaXMuY2FuY2VsbGF0aW9uRXJyb3IoKVxuICAgICAgdGhpcy5yZWplY3RQZW5kaW5nUHJvY2Vzc2VkKGNhbmNlbEVycm9yKVxuICAgICAgdGhpcy5jYW5jZWxTaWduYWwuYWJvcnQoY2FuY2VsRXJyb3IpXG5cbiAgICAgIC8vIFVuYmxvY2sgYW55IGxvY2FsIGNsb3NlKCkgY2FsbGVycyB3YWl0aW5nIGZvciBzdHJlYW1zIHRvIHNldHRsZS5cbiAgICAgIGxldCB3YWl0aW5nID0gdGhpcy5zaG91bGRDbG9zZS5wb3AoKVxuICAgICAgd2hpbGUgKHdhaXRpbmcpIHtcbiAgICAgICAgd2FpdGluZygpXG4gICAgICAgIHdhaXRpbmcgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIENhc2UgMTogQWN0aXZlIHN0cmVhbXMgc3RpbGwgcnVubmluZyDihpIgd2FpdCB1bnRpbCB0aGV5IGZpbmlzaFxuICAgIGlmICh0aGlzLm9wZW5TdHJlYW1zICE9PSAwKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gdGhpcy5zaG91bGRDbG9zZS5wdXNoKHJlc29sdmUpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBhY3RpdmUgc3RyZWFtcyDihpIgcGVyZm9ybSBhY3R1YWwgY2xvc2VcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHt0aGlzLnVyaX0gY2xvc2VzIHN0cmVhbWApXG4gICAgdGhpcy5jbG9zZWQgPSB0cnVlXG4gICAgYXdhaXQgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3Ioe1xuICAgICAgY2xvc2U6IHsgY2hhbm5lbDogdGhpcy51cmkgfSxcbiAgICB9KVxuXG4gICAgbGV0IHJlc29sdmUgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgd2hpbGUgKHJlc29sdmUpIHtcbiAgICAgIHJlc29sdmUoKVxuICAgICAgcmVzb2x2ZSA9IHRoaXMuc2hvdWxkQ2xvc2UucG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQSBtZXNzYWdlIGlzIGhhbmRsZWQsIGxldCdzIG5vdGlmeSB0aGUgZmlmbyB7QGxpbmsgYXdhaXRQcm9jZXNzZWR9XG4gICAqL1xuICBoYW5kbGVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEucmVzb2x2ZSgpXG4gICAgfSBlbHNlIGlmICh0aGlzLmNsb3NlZCB8fCB0aGlzLl9jYW5jZWxlZCkge1xuICAgICAgLy8gQSBsYXRlIGFjayBjYW4gYXJyaXZlIGFmdGVyIGEgY2xvc2UvY2FuY2VsIHJhY2U7IG5vdGhpbmcgdG8gcmVzb2x2ZSBhbnltb3JlLlxuICAgICAgcmV0dXJuXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAnRXhwZWN0ZWQgdG8gYmUgd2FpdGluZyBmb3IgYSBtZXNzYWdlIHRvIGJlIHByb2Nlc3NlZCwgYnV0IHRoaXMgaXMgbm90IHRoZSBjYXNlICcgK1xuICAgICAgICAgIHRoaXMudXJpLFxuICAgICAgKVxuICAgIH1cbiAgfVxufVxuIl19
|
|
167
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBK0VoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEdBQUcsQ0FBUTtJQUNwQixtQkFBbUIsR0FBVyxDQUFDLENBQUE7SUFDZCxNQUFNLENBQWM7SUFDcEIsa0JBQWtCLENBQVU7SUFDNUIsTUFBTSxDQUFRO0lBR3ZCLGlCQUFpQixHQUdwQixFQUFFLENBQUE7SUFFQyxXQUFXLEdBQVcsQ0FBQyxDQUFBO0lBRXZCLFdBQVcsR0FBc0IsRUFBRSxDQUFBO0lBQ25DLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDZCxTQUFTLEdBQUcsS0FBSyxDQUFBO0lBR1IsY0FBYyxHQUFHLElBQUksR0FBRyxFQUFXLENBQUE7SUFFbkMsUUFBUSxDQUFRO0lBRWpDLFlBQ0UsR0FBVyxFQUNYLE1BQW9CLEVBQ3BCLGtCQUE0QixFQUM1QixRQUFnQixFQUNoQixNQUFjO1FBRWQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFBO1FBQzVDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFBO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDMUIsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQTtJQUN2QixDQUFDO0lBRUQsRUFBRSxDQUFDLEtBQWUsRUFBRSxRQUFpQjtRQUNuQyxJQUFJLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFR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Q25FLENBQUE7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtJQUNILENBQUM7SUFFTyxjQUFjO1FBQ3BCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FDckMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUNqRCxDQUFBO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRnJvbVJ1bm5lciwgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnd2luc3RvbidcbmltcG9ydCB7IEFueSB9IGZyb20gJy4vcmVhZGVyJ1xuXG50eXBlIFdyaXRhYmxlID0gKG1zZzogRnJvbVJ1bm5lcikgPT4gUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IHR5cGUgSGFuZGxlcjxUID0gdm9pZD4gPSBbVF0gZXh0ZW5kcyBbdm9pZF1cbiAgPyAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPlxuICA6ICh2YWx1ZTogVCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD5cblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICByZWFkb25seSB1cmk6IHN0cmluZ1xuICByZWFkb25seSBjYW5jZWxlZDogYm9vbGVhblxuICBvbihldmVudDogJ2NhbmNlbCcsIGxpc3RlbmVyOiBIYW5kbGVyKTogdGhpc1xuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBjb21wbGV0ZSBidWZmZXIgdG8gdGhlIGNoYW5uZWwuIFRoZSBQcm9taXNlIHJlc29sdmVzIG9uY2UgdGhlIG1lc3NhZ2UgaXMgZnVsbHkgcHJvY2Vzc2VkIGJ5IHRoZSByZW1vdGUuXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIG9yIGNhbmNlbGVkIGF0IHRoZSBtb21lbnQgb2YgdGhlIHdyaXRlIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIGJ1ZmZlciAtIFRoZSBkYXRhIHRvIHNlbmQgYXMgYSBVaW50OEFycmF5XG4gICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG1lc3NhZ2UgaXMgYWNrbm93bGVkZ2VkIGFzIHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKi9cbiAgYnVmZmVyKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD5cblxuICAvKipcbiAgICogV3JpdGVzIGEgc3RyZWFtIG9mIGRhdGEgdG8gYSBzZXBhcmF0ZSBzdHJlYW0tc3BlY2lmaWMgY2hhbm5lbC5cbiAgICogVGhlIFByb21pc2UgcmVzb2x2ZXMgb25jZSB0aGUgZW50aXJlIHN0cmVhbSBpcyBmdWxseSBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICpcbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgY2hhbm5lbCBpcyBjbG9zZWQgb3IgY2FuY2VsZWQgYXQgdGhlIG1vbWVudCBvZiBpbml0aWF0aW5nIGEgc3RyZWFtLXNwZWNpZmljIGNoYW5uZWwuXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBc3luY0l0ZXJhYmxlIHRoYXQgcHJvZHVjZXMgdGhlIGRhdGEgdG8gc2VuZCBhcyBVaW50OEFycmF5c1xuICAgKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBlbnRpcmUgc3RyZWFtIGlzIGFja25vd2xlZGdlZCBhcyBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICovXG4gIHN0cmVhbShidWZmZXI6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBQcm9taXNlPHZvaWQ+XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN0cmVhbSBvZiBkYXRhIHRvIGEgc2VwYXJhdGUgc3RyZWFtLXNwZWNpZmljIGNoYW5uZWwuXG4gICAqIFRoZSBQcm9taXNlIHJlc29sdmVzIG9uY2UgdGhlIGVudGlyZSBzdHJlYW0gaXMgZnVsbHkgcHJvY2Vzc2VkIGJ5IHRoZSByZW1vdGUuXG4gICAqXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGNoYW5uZWwgaXMgY2xvc2VkIG9yIGNhbmNlbGVkIGF0IHRoZSBtb21lbnQgb2YgaW5pdGlhdGluZyBhIHN0cmVhbS1zcGVjaWZpYyBjaGFubmVsLlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQW4gQXN5bmNJdGVyYWJsZSB0aGF0IHByb2R1Y2VzIHRoZSBkYXRhIHRvIHNlbmQsIHdoaWNoIHdpbGwgYmUgdHJhbnNmb3JtZWQgaW50byBVaW50OEFycmF5cyB1c2luZyB0aGUgcHJvdmlkZWQgdHJhbnNmb3JtIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB0cmFuc2Zvcm0gLSBBIGZ1bmN0aW9uIHRoYXQgdHJhbnNmb3JtcyBpdGVtcyBmcm9tIHRoZSBidWZmZXIgQXN5bmNJdGVyYWJsZSBpbnRvIFVpbnQ4QXJyYXlzIGZvciBzZW5kaW5nLiBJZiBub3QgcHJvdmlkZWQsIGl0ZW1zIGFyZSBhc3N1bWVkIHRvIGFscmVhZHkgYmUgVWludDhBcnJheXMuXG4gICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGVudGlyZSBzdHJlYW0gaXMgYWNrbm93bGVkZ2VkIGFzIHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKi9cbiAgc3RyZWFtPFQ+KFxuICAgIGJ1ZmZlcjogQXN5bmNJdGVyYWJsZTxUPixcbiAgICB0cmFuc2Zvcm06ICh4OiBUKSA9PiBVaW50OEFycmF5LFxuICApOiBQcm9taXNlPHZvaWQ+XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN0cmluZyBtZXNzYWdlIHRvIHRoZSBjaGFubmVsLiBUaGUgUHJvbWlzZSByZXNvbHZlcyBvbmNlIHRoZSBtZXNzYWdlIGlzIGZ1bGx5IHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBvciBjYW5jZWxlZCBhdCB0aGUgbW9tZW50IG9mIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gICAqIEBwYXJhbSBidWZmZXIgLSBUaGUgc3RyaW5nIG1lc3NhZ2UgdG8gc2VuZFxuICAgKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBtZXNzYWdlIGlzIGFja25vd2xlZGdlZCBhcyBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICovXG4gIHN0cmluZyhidWZmZXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cblxuICAvKipcbiAgICogV3JpdGVzIGEgbWVzc2FnZSBvZiBhbnkgc3VwcG9ydGVkIHR5cGUgKHN0cmluZywgYnVmZmVyLCBvciBzdHJlYW0pIHRvIHRoZSBjaGFubmVsLlxuICAgKiBUaGUgUHJvbWlzZSByZXNvbHZlcyBvbmNlIHRoZSBtZXNzYWdlIGlzIGZ1bGx5IHByb2Nlc3NlZCBieSB0aGUgcmVtb3RlLlxuICAgKlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBjaGFubmVsIGlzIGNsb3NlZCBvciBjYW5jZWxlZCBhdCB0aGUgbW9tZW50IG9mIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gICAqIEBwYXJhbSBhbnkgLSBBbiBvYmplY3QgY29udGFpbmluZyBvbmUgb2YgdGhlIHN1cHBvcnRlZCBtZXNzYWdlIHR5cGVzIChzdHJpbmcsIGJ1ZmZlciwgb3Igc3RyZWFtKVxuICAgKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBtZXNzYWdlIGlzIGFja25vd2xlZGdlZCBhcyBwcm9jZXNzZWQgYnkgdGhlIHJlbW90ZS5cbiAgICovXG4gIGFueShhbnk6IEFueSk6IFByb21pc2U8dm9pZD5cblxuICAvKipcbiAgICogR3JhY2VmdWxseSBjbG9zZXMgdGhpcyBjaGFubmVsLlxuICAgKlxuICAgKiBCZWhhdmlvcjpcbiAgICogLSBJZiB0aGVyZSBhcmUgc3RpbGwgYWN0aXZlIHN0cmVhbXMsIGNsb3NpbmcgaXMgZGVmZXJyZWQgdW50aWwgdGhleSBjb21wbGV0ZS5cbiAgICogLSBJZiBtdWx0aXBsZSBjYWxsZXJzIGludm9rZSBgY2xvc2UoKWAgd2hpbGUgd2FpdGluZywgdGhlaXIgUHJvbWlzZXMgYXJlIHF1ZXVlZCBhbmRcbiAgICogICByZXNvbHZlZCBvbmNlIHRoZSBjaGFubmVsIGFjdHVhbGx5IGNsb3Nlcy5cbiAgICogLSBJZiB0aGlzIHNpZGUgaW5pdGlhdGVkIHRoZSBjbG9zZSAoYGlzc3VlZCA9IGZhbHNlYCksIGEgY2xvc2UgbWVzc2FnZSBpcyBzZW50IHRvIHRoZSByZW1vdGUuXG4gICAqXG4gICAqIEBwYXJhbSBpc3N1ZWQgLSBJZiB0cnVlLCBpbmRpY2F0ZXMgdGhlIGNsb3NlIHJlcXVlc3Qgb3JpZ2luYXRlZCByZW1vdGVseVxuICAgKi9cbiAgY2xvc2UoaXNzdWVkPzogYm9vbGVhbik6IFByb21pc2U8dm9pZD5cbn1cbmNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKVxuZXhwb3J0IGNsYXNzIFdyaXRlckluc3RhbmNlIGltcGxlbWVudHMgV3JpdGVyIHtcbiAgcmVhZG9ubHkgdXJpOiBzdHJpbmdcbiAgbG9jYWxTZXF1ZW5jZU51bWJlcjogbnVtYmVyID0gMVxuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogUnVubmVyQ2xpZW50XG4gIHByaXZhdGUgcmVhZG9ubHkgbm90aWZ5T3JjaGVzdHJhdG9yOiBXcml0YWJsZVxuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlcjogTG9nZ2VyXG5cbiAgLy8gRklGTyBvZiBtZXNzYWdlLWxldmVsIGFja25vd2xlZGdlbWVudHMgY29taW5nIGJhY2sgZnJvbSB0aGUgb3JjaGVzdHJhdG9yLlxuICBwcml2YXRlIGF3YWl0aW5nUHJvY2Vzc2VkOiBBcnJheTx7XG4gICAgcmVzb2x2ZTogKCkgPT4gdm9pZFxuICAgIHJlamVjdDogKHJlYXNvbjogRXJyb3IpID0+IHZvaWRcbiAgfT4gPSBbXVxuXG4gIHByaXZhdGUgb3BlblN0cmVhbXM6IG51bWJlciA9IDBcbiAgLy8gQ2xvc2UgY2FsbGVycyB3YWl0IGhlcmUgd2hpbGUgYWN0aXZlIHN0cmVhbXMgYXJlIHN0aWxsIGZsdXNoaW5nLlxuICBwcml2YXRlIHNob3VsZENsb3NlOiBBcnJheTwoKSA9PiB2b2lkPiA9IFtdXG4gIHByaXZhdGUgY2xvc2VkID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FuY2VsZWQgPSBmYWxzZVxuXG4gIC8vIFByb2Nlc3NvcnMgY2FuIHN1YnNjcmliZSBoZXJlIHRvIHN0b3AgdXBzdHJlYW0gd29yayB3aGVuIGRvd25zdHJlYW0gY2FuY2Vscy5cbiAgcHJpdmF0ZSByZWFkb25seSBjYW5jZWxIYW5kbGVycyA9IG5ldyBTZXQ8SGFuZGxlcj4oKVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgcnVubmVySWQ6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHVyaTogc3RyaW5nLFxuICAgIGNsaWVudDogUnVubmVyQ2xpZW50LFxuICAgIG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGUsXG4gICAgcnVubmVySWQ6IHN0cmluZyxcbiAgICBsb2dnZXI6IExvZ2dlcixcbiAgKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnRcbiAgICB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvciA9IG5vdGlmeU9yY2hlc3RyYXRvclxuICAgIHRoaXMudXJpID0gdXJpXG4gICAgdGhpcy5sb2dnZXIgPSBsb2dnZXJcbiAgICB0aGlzLnJ1bm5lcklkID0gcnVubmVySWRcbiAgfVxuXG4gIGdldCBjYW5jZWxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY2FuY2VsZWRcbiAgfVxuXG4gIG9uKGV2ZW50OiAnY2FuY2VsJywgbGlzdGVuZXI6IEhhbmRsZXIpOiB0aGlzIHtcbiAgICBpZiAoZXZlbnQgPT09ICdjYW5jZWwnKSB7XG4gICAgICB0aGlzLmNhbmNlbEhhbmRsZXJzLmFkZChsaXN0ZW5lcilcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHJpdmF0ZSBjYW5jZWxsYXRpb25FcnJvcigpOiBFcnJvciB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihcbiAgICAgIGBXcml0ZXIgZm9yIGNoYW5uZWwgJHt0aGlzLnVyaX0gd2FzIGNhbmNlbGVkIGJ5IHRoZSBjb25uZWN0ZWQgcmVhZGVyYCxcbiAgICApXG4gIH1cblxuICBhc3luYyBhbnkoYW55OiBBbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoJ3N0cmVhbScgaW4gYW55KSB7XG4gICAgICBhd2FpdCB0aGlzLnN0cmVhbShhbnkuc3RyZWFtKVxuICAgIH1cbiAgICBpZiAoJ2J1ZmZlcicgaW4gYW55KSB7XG4gICAgICBhd2FpdCB0aGlzLmJ1ZmZlcihhbnkuYnVmZmVyKVxuICAgIH1cbiAgICBpZiAoJ3N0cmluZycgaW4gYW55KSB7XG4gICAgICBhd2FpdCB0aGlzLnN0cmluZyhhbnkuc3RyaW5nKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXNzZXJ0Q2FuV3JpdGUoKSB7XG4gICAgaWYgKHRoaXMuX2NhbmNlbGVkKSB7XG4gICAgICB0aHJvdyB0aGlzLmNhbmNlbGxhdGlvbkVycm9yKClcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgV3JpdGVyIGZvciBjaGFubmVsICR7dGhpcy51cml9IGlzIGNsb3NlZGApXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYnVmZmVyKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXNzZXJ0Q2FuV3JpdGUoKVxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3RoaXMudXJpfSBzZW5kcyBidWZmZXIgJHtidWZmZXIubGVuZ3RofSBieXRlc2ApXG4gICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgY29uc3QgaGFuZGxlZFByb21pc2UgPSB0aGlzLmF3YWl0UHJvY2Vzc2VkKClcblxuICAgIGF3YWl0IHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yKHtcbiAgICAgIG1zZzogeyBkYXRhOiBidWZmZXIsIGNoYW5uZWw6IHRoaXMudXJpLCBsb2NhbFNlcXVlbmNlTnVtYmVyIH0sXG4gICAgfSlcbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgYXN5bmMgc3RyZWFtPFQgPSBVaW50OEFycmF5PihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtPzogKHg6IFQpID0+IFVpbnQ4QXJyYXksXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXNzZXJ0Q2FuV3JpdGUoKVxuICAgIHRoaXMub3BlblN0cmVhbXMgKz0gMVxuICAgIGNvbnN0IHQgPSB0cmFuc2Zvcm0gfHwgKCh4OiB1bmtub3duKSA9PiA8VWludDhBcnJheT54KVxuICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuY2xpZW50LnNlbmRTdHJlYW1NZXNzYWdlKClcblxuICAgIHRyeSB7XG4gICAgICAvLyBNZXNzYWdlLWxldmVsIGFjayB0aGF0IHNpZ25hbHMgdGhlIHdob2xlIHN0cmVhbSBtZXNzYWdlIGlzIGZ1bGx5IGhhbmRsZWQuXG4gICAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoKVxuICAgICAgY29uc3Qgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsgPSBwcm9taXNpZnkoc3RyZWFtLndyaXRlLmJpbmQoc3RyZWFtKSlcbiAgICAgIGNvbnN0IGxvY2FsU2VxdWVuY2VOdW1iZXIgPSB0aGlzLmxvY2FsU2VxdWVuY2VOdW1iZXIrK1xuICAgICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoe1xuICAgICAgICBpZDoge1xuICAgICAgICAgIGNoYW5uZWw6IHRoaXMudXJpLFxuICAgICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICAgICAgcnVubmVyOiB0aGlzLnJ1bm5lcklkLFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gRmlyc3QgcmVzcG9uc2UgY29uZmlybXMgc3RyZWFtIGlkIHJlZ2lzdHJhdGlvbiBvbiB0aGUgcmVtb3RlIHNpZGUuXG4gICAgICBjb25zdCBpZCA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcblxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGAke3RoaXMudXJpfSBzdHJlYW1zIG1lc3NhZ2Ugd2l0aCBpZCAke0pTT04uc3RyaW5naWZ5KGlkKX1gLFxuICAgICAgKVxuXG4gICAgICAvLyBUT0RPOiBkb24ndCBhd2FpdCB0byBhbGxvdyBjb25zdW1pbmcgcHJvY2Vzc29ycyB0byByZWFkIGFuZCBoYW5kbGUgaW4gcGFyYWxsZWwuXG4gICAgICBmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBidWZmZXIpIHtcbiAgICAgICAgY29uc3QgcHJvY2Vzc2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcbiAgICAgICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoeyBkYXRhOiB7IGRhdGE6IHQobXNnKSB9IH0pXG4gICAgICAgIC8vIEF3YWl0IGEgbWVzc2FnZSBvbiB0aGUgc3RyZWFtLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNodW5rIGhhcyBiZWVuIHByb2Nlc3NlZFxuICAgICAgICBhd2FpdCBwcm9jZXNzZWRQcm9taXNlXG4gICAgICB9XG5cbiAgICAgIHN0cmVhbS5lbmQoKVxuXG4gICAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLm9wZW5TdHJlYW1zIC09IDFcblxuICAgICAgaWYgKCFzdHJlYW0ud3JpdGFibGVFbmRlZCkge1xuICAgICAgICBzdHJlYW0uZW5kKClcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYSBjbG9zZSBjYWxsIHdhcyBkZWZlcnJlZCB3aGlsZSBzdHJlYW1pbmcsIGNvbXBsZXRlIGl0IG5vdy5cbiAgICAgIGlmICh0aGlzLnNob3VsZENsb3NlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbG9zZSgpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc3RyaW5nKG1zZzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDYW5Xcml0ZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7dGhpcy51cml9IHNlbmRzIHN0cmluZyAke21zZy5sZW5ndGh9IGNoYXJhY3RlcnNgKVxuICAgIGNvbnN0IGxvY2FsU2VxdWVuY2VOdW1iZXIgPSB0aGlzLmxvY2FsU2VxdWVuY2VOdW1iZXIrK1xuICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG5cbiAgICBhd2FpdCB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvcih7XG4gICAgICBtc2c6IHtcbiAgICAgICAgZGF0YTogZW5jb2Rlci5lbmNvZGUobXNnKSxcbiAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgYXN5bmMgY2xvc2UoaXNzdWVkID0gZmFsc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNsb3NlZCA9IHRydWVcbiAgICBpZiAoaXNzdWVkICYmICF0aGlzLl9jYW5jZWxlZCkge1xuICAgICAgLy8gUmVtb3RlIGluaXRpYXRlZCBjbG9zZTogbWFyayB3cml0ZXIgY2FuY2VsZWQgdG8gZmFpbCBmdXR1cmUgd3JpdGVzLlxuICAgICAgdGhpcy5fY2FuY2VsZWQgPSB0cnVlXG5cbiAgICAgIC8vIE5vdGlmeSBwcm9jZXNzb3JzIHNvIHRoZXkgY2FuIHN0b3AgcHJvZHVjaW5nIHVwc3RyZWFtIHdvcmsgYXMgd2VsbC5cbiAgICAgIGF3YWl0IHRoaXMuZW1pdENhbmNlbCgpXG4gICAgfVxuICAgIC8vIENhc2UgMTogQWN0aXZlIHN0cmVhbXMgc3RpbGwgcnVubmluZyDihpIgd2FpdCB1bnRpbCB0aGV5IGZpbmlzaFxuICAgIGlmICh0aGlzLm9wZW5TdHJlYW1zICE9PSAwKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gdGhpcy5zaG91bGRDbG9zZS5wdXNoKHJlc29sdmUpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBhY3RpdmUgc3RyZWFtcyDihpIgcGVyZm9ybSBhY3R1YWwgY2xvc2VcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHt0aGlzLnVyaX0gY2xvc2VzIHN0cmVhbWApXG4gICAgaWYgKCFpc3N1ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yKHtcbiAgICAgICAgY2xvc2U6IHsgY2hhbm5lbDogdGhpcy51cmkgfSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgbGV0IHJlc29sdmUgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgd2hpbGUgKHJlc29sdmUpIHtcbiAgICAgIHJlc29sdmUoKVxuICAgICAgcmVzb2x2ZSA9IHRoaXMuc2hvdWxkQ2xvc2UucG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQSBtZXNzYWdlIGlzIGhhbmRsZWQsIGxldCdzIG5vdGlmeSB0aGUgZmlmbyB7QGxpbmsgYXdhaXRQcm9jZXNzZWR9XG4gICAqL1xuICBoYW5kbGVkKGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEucmVqZWN0KG5ldyBFcnJvcihlcnJvcikpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLnNoaWZ0KCkhLnJlc29sdmUoKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5jbG9zZWQgfHwgdGhpcy5fY2FuY2VsZWQpIHtcbiAgICAgIC8vIEEgbGF0ZSBhY2sgY2FuIGFycml2ZSBhZnRlciBhIGNsb3NlL2NhbmNlbCByYWNlOyBub3RoaW5nIHRvIHJlc29sdmUgYW55bW9yZS5cbiAgICAgIHJldHVyblxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIHRvIGJlIHdhaXRpbmcgZm9yIGEgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQsIGJ1dCB0aGlzIGlzIG5vdCB0aGUgY2FzZSAnICtcbiAgICAgICAgICB0aGlzLnVyaSxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVtaXRDYW5jZWwoKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBBcnJheS5mcm9tKHRoaXMuY2FuY2VsSGFuZGxlcnMpLm1hcChhc3luYyAoaGFuZGxlcikgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGhhbmRsZXIoKVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgYENhbmNlbCBsaXN0ZW5lciBmb3IgY2hhbm5lbCAke3RoaXMudXJpfSBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX1gLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKVxuICB9XG5cbiAgcHJpdmF0ZSBhd2FpdFByb2Nlc3NlZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT5cbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQucHVzaCh7IHJlc29sdmUsIHJlamVjdCB9KSxcbiAgICApXG4gIH1cbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rdfc/js-runner",
|
|
3
|
-
"version": "3.1.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@grpc/grpc-js": "^1.14.3",
|
|
58
|
-
"@rdfc/proto": "^0.1.
|
|
58
|
+
"@rdfc/proto": "^0.1.3",
|
|
59
59
|
"@treecg/types": "^0.4.6",
|
|
60
60
|
"jsonld": "^9.0.0",
|
|
61
61
|
"jsonld-streaming-parser": "^5.0.1",
|
package/src/reader.ts
CHANGED
package/src/runner.ts
CHANGED
|
@@ -260,7 +260,7 @@ export class Runner {
|
|
|
260
260
|
private handleProcessed(processed: LocalAck) {
|
|
261
261
|
const writer = this.writers[processed.channel]
|
|
262
262
|
if (writer) {
|
|
263
|
-
writer.handled()
|
|
263
|
+
writer.handled(processed.error)
|
|
264
264
|
} else {
|
|
265
265
|
this.logger.error(
|
|
266
266
|
`Received processed message for channel ${processed.channel}, but no writer was present.`,
|
package/src/testUtils/index.ts
CHANGED
|
@@ -83,9 +83,13 @@ export class OrchestratorMock {
|
|
|
83
83
|
// Always bounce processed msgs back to the runner
|
|
84
84
|
connectStream.register(
|
|
85
85
|
(msg) => msg.processed,
|
|
86
|
-
({ channel, globalSequenceNumber }, send) => {
|
|
86
|
+
({ channel, globalSequenceNumber, error }, send) => {
|
|
87
87
|
send({
|
|
88
|
-
processed: {
|
|
88
|
+
processed: {
|
|
89
|
+
channel,
|
|
90
|
+
localSequenceNumber: globalSequenceNumber,
|
|
91
|
+
error,
|
|
92
|
+
},
|
|
89
93
|
})
|
|
90
94
|
},
|
|
91
95
|
)
|
package/src/writer.ts
CHANGED
|
@@ -12,17 +12,71 @@ export interface Writer {
|
|
|
12
12
|
readonly uri: string
|
|
13
13
|
readonly canceled: boolean
|
|
14
14
|
on(event: 'cancel', listener: Handler): this
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Writes a complete buffer to the channel. The Promise resolves once the message is fully processed by the remote.
|
|
18
|
+
*
|
|
19
|
+
* @throws Error if the channel is closed or canceled at the moment of the write operation.
|
|
20
|
+
* @param buffer - The data to send as a Uint8Array
|
|
21
|
+
* @returns A Promise that resolves when the message is acknowledged as processed by the remote.
|
|
22
|
+
*/
|
|
15
23
|
buffer(buffer: Uint8Array): Promise<void>
|
|
16
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Writes a stream of data to a separate stream-specific channel.
|
|
27
|
+
* The Promise resolves once the entire stream is fully processed by the remote.
|
|
28
|
+
*
|
|
29
|
+
* @throws Error if the channel is closed or canceled at the moment of initiating a stream-specific channel.
|
|
30
|
+
* @param buffer - An AsyncIterable that produces the data to send as Uint8Arrays
|
|
31
|
+
* @returns A Promise that resolves when the entire stream is acknowledged as processed by the remote.
|
|
32
|
+
*/
|
|
17
33
|
stream(buffer: AsyncIterable<Uint8Array>): Promise<void>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Writes a stream of data to a separate stream-specific channel.
|
|
37
|
+
* The Promise resolves once the entire stream is fully processed by the remote.
|
|
38
|
+
*
|
|
39
|
+
* @throws Error if the channel is closed or canceled at the moment of initiating a stream-specific channel.
|
|
40
|
+
* @param buffer - An AsyncIterable that produces the data to send, which will be transformed into Uint8Arrays using the provided transform function
|
|
41
|
+
* @param transform - A function that transforms items from the buffer AsyncIterable into Uint8Arrays for sending. If not provided, items are assumed to already be Uint8Arrays.
|
|
42
|
+
* @returns A Promise that resolves when the entire stream is acknowledged as processed by the remote.
|
|
43
|
+
*/
|
|
18
44
|
stream<T>(
|
|
19
45
|
buffer: AsyncIterable<T>,
|
|
20
46
|
transform: (x: T) => Uint8Array,
|
|
21
47
|
): Promise<void>
|
|
22
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Writes a string message to the channel. The Promise resolves once the message is fully processed by the remote.
|
|
51
|
+
*
|
|
52
|
+
* @throws Error if the channel is closed or canceled at the moment of the write operation.
|
|
53
|
+
* @param buffer - The string message to send
|
|
54
|
+
* @returns A Promise that resolves when the message is acknowledged as processed by the remote.
|
|
55
|
+
*/
|
|
23
56
|
string(buffer: string): Promise<void>
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Writes a message of any supported type (string, buffer, or stream) to the channel.
|
|
60
|
+
* The Promise resolves once the message is fully processed by the remote.
|
|
61
|
+
*
|
|
62
|
+
* @throws Error if the channel is closed or canceled at the moment of the write operation.
|
|
63
|
+
* @param any - An object containing one of the supported message types (string, buffer, or stream)
|
|
64
|
+
* @returns A Promise that resolves when the message is acknowledged as processed by the remote.
|
|
65
|
+
*/
|
|
24
66
|
any(any: Any): Promise<void>
|
|
25
|
-
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Gracefully closes this channel.
|
|
70
|
+
*
|
|
71
|
+
* Behavior:
|
|
72
|
+
* - If there are still active streams, closing is deferred until they complete.
|
|
73
|
+
* - If multiple callers invoke `close()` while waiting, their Promises are queued and
|
|
74
|
+
* resolved once the channel actually closes.
|
|
75
|
+
* - If this side initiated the close (`issued = false`), a close message is sent to the remote.
|
|
76
|
+
*
|
|
77
|
+
* @param issued - If true, indicates the close request originated remotely
|
|
78
|
+
*/
|
|
79
|
+
close(issued?: boolean): Promise<void>
|
|
26
80
|
}
|
|
27
81
|
const encoder = new TextEncoder()
|
|
28
82
|
export class WriterInstance implements Writer {
|
|
@@ -44,8 +98,6 @@ export class WriterInstance implements Writer {
|
|
|
44
98
|
private closed = false
|
|
45
99
|
private _canceled = false
|
|
46
100
|
|
|
47
|
-
// Shared cancellation signal to abort in-flight waits when the remote closes.
|
|
48
|
-
private readonly cancelSignal = new AbortController()
|
|
49
101
|
// Processors can subscribe here to stop upstream work when downstream cancels.
|
|
50
102
|
private readonly cancelHandlers = new Set<Handler>()
|
|
51
103
|
|
|
@@ -83,19 +135,15 @@ export class WriterInstance implements Writer {
|
|
|
83
135
|
)
|
|
84
136
|
}
|
|
85
137
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.logger.error(
|
|
96
|
-
`Cancel listener for channel ${this.uri} failed: ${String(error)}`,
|
|
97
|
-
)
|
|
98
|
-
}
|
|
138
|
+
async any(any: Any): Promise<void> {
|
|
139
|
+
if ('stream' in any) {
|
|
140
|
+
await this.stream(any.stream)
|
|
141
|
+
}
|
|
142
|
+
if ('buffer' in any) {
|
|
143
|
+
await this.buffer(any.buffer)
|
|
144
|
+
}
|
|
145
|
+
if ('string' in any) {
|
|
146
|
+
await this.string(any.string)
|
|
99
147
|
}
|
|
100
148
|
}
|
|
101
149
|
|
|
@@ -109,55 +157,6 @@ export class WriterInstance implements Writer {
|
|
|
109
157
|
}
|
|
110
158
|
}
|
|
111
159
|
|
|
112
|
-
private async raceWithCancellation<T>(promise: Promise<T>): Promise<T> {
|
|
113
|
-
this.assertCanWrite()
|
|
114
|
-
|
|
115
|
-
return await new Promise<T>((resolve, reject) => {
|
|
116
|
-
const onAbort = () => reject(this.cancellationError())
|
|
117
|
-
this.cancelSignal.signal.addEventListener('abort', onAbort, {
|
|
118
|
-
once: true,
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
promise.then(
|
|
122
|
-
(value) => {
|
|
123
|
-
// Clean up the abort listener if the original operation finished first.
|
|
124
|
-
this.cancelSignal.signal.removeEventListener('abort', onAbort)
|
|
125
|
-
resolve(value)
|
|
126
|
-
},
|
|
127
|
-
(error) => {
|
|
128
|
-
this.cancelSignal.signal.removeEventListener('abort', onAbort)
|
|
129
|
-
reject(error)
|
|
130
|
-
},
|
|
131
|
-
)
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
private rejectPendingProcessed(error: Error) {
|
|
136
|
-
// Reject all queued message waits so callers do not hang during cancellation.
|
|
137
|
-
while (this.awaitingProcessed.length > 0) {
|
|
138
|
-
this.awaitingProcessed.shift()!.reject(error)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private awaitProcessed(): Promise<void> {
|
|
143
|
-
this.assertCanWrite()
|
|
144
|
-
return new Promise((resolve, reject) =>
|
|
145
|
-
this.awaitingProcessed.push({ resolve, reject }),
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async any(any: Any): Promise<void> {
|
|
150
|
-
if ('stream' in any) {
|
|
151
|
-
await this.stream(any.stream)
|
|
152
|
-
}
|
|
153
|
-
if ('buffer' in any) {
|
|
154
|
-
await this.buffer(any.buffer)
|
|
155
|
-
}
|
|
156
|
-
if ('string' in any) {
|
|
157
|
-
await this.string(any.string)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
160
|
async buffer(buffer: Uint8Array): Promise<void> {
|
|
162
161
|
this.assertCanWrite()
|
|
163
162
|
this.logger.debug(`${this.uri} sends buffer ${buffer.length} bytes`)
|
|
@@ -173,7 +172,7 @@ export class WriterInstance implements Writer {
|
|
|
173
172
|
async stream<T = Uint8Array>(
|
|
174
173
|
buffer: AsyncIterable<T>,
|
|
175
174
|
transform?: (x: T) => Uint8Array,
|
|
176
|
-
) {
|
|
175
|
+
): Promise<void> {
|
|
177
176
|
this.assertCanWrite()
|
|
178
177
|
this.openStreams += 1
|
|
179
178
|
const t = transform || ((x: unknown) => <Uint8Array>x)
|
|
@@ -193,14 +192,13 @@ export class WriterInstance implements Writer {
|
|
|
193
192
|
})
|
|
194
193
|
|
|
195
194
|
// First response confirms stream id registration on the remote side.
|
|
196
|
-
const id = await
|
|
197
|
-
new Promise((res) => stream.once('data', res)),
|
|
198
|
-
)
|
|
195
|
+
const id = await new Promise((res) => stream.once('data', res))
|
|
199
196
|
|
|
200
197
|
this.logger.debug(
|
|
201
198
|
`${this.uri} streams message with id ${JSON.stringify(id)}`,
|
|
202
199
|
)
|
|
203
200
|
|
|
201
|
+
// TODO: don't await to allow consuming processors to read and handle in parallel.
|
|
204
202
|
for await (const msg of buffer) {
|
|
205
203
|
const processedPromise = new Promise((res) => stream.once('data', res))
|
|
206
204
|
await writeStreamMessageChunk({ data: { data: t(msg) } })
|
|
@@ -242,45 +240,15 @@ export class WriterInstance implements Writer {
|
|
|
242
240
|
await handledPromise
|
|
243
241
|
}
|
|
244
242
|
|
|
245
|
-
/**
|
|
246
|
-
* Gracefully closes this channel.
|
|
247
|
-
*
|
|
248
|
-
* Behavior:
|
|
249
|
-
* - If there are still active streams, closing is deferred until they complete.
|
|
250
|
-
* - If multiple callers invoke `close()` while waiting, their Promises are queued and
|
|
251
|
-
* resolved once the channel actually closes.
|
|
252
|
-
* - If this side initiated the close (`issued = false`), a close message is sent to the remote.
|
|
253
|
-
*
|
|
254
|
-
* @param issued - If true, indicates the close request originated remotely
|
|
255
|
-
*/
|
|
256
243
|
async close(issued = false): Promise<void> {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
// Notify processors so they can stop producing upstream work as well.
|
|
263
|
-
this.emitCancel()
|
|
264
|
-
}
|
|
265
|
-
this.closed = true
|
|
266
|
-
|
|
267
|
-
const cancelError = this.cancellationError()
|
|
268
|
-
this.rejectPendingProcessed(cancelError)
|
|
269
|
-
this.cancelSignal.abort(cancelError)
|
|
244
|
+
this.closed = true
|
|
245
|
+
if (issued && !this._canceled) {
|
|
246
|
+
// Remote initiated close: mark writer canceled to fail future writes.
|
|
247
|
+
this._canceled = true
|
|
270
248
|
|
|
271
|
-
//
|
|
272
|
-
|
|
273
|
-
while (waiting) {
|
|
274
|
-
waiting()
|
|
275
|
-
waiting = this.shouldClose.pop()
|
|
276
|
-
}
|
|
277
|
-
return
|
|
249
|
+
// Notify processors so they can stop producing upstream work as well.
|
|
250
|
+
await this.emitCancel()
|
|
278
251
|
}
|
|
279
|
-
|
|
280
|
-
if (this.closed) {
|
|
281
|
-
return
|
|
282
|
-
}
|
|
283
|
-
|
|
284
252
|
// Case 1: Active streams still running → wait until they finish
|
|
285
253
|
if (this.openStreams !== 0) {
|
|
286
254
|
await new Promise<void>((resolve) => this.shouldClose.push(resolve))
|
|
@@ -289,10 +257,11 @@ export class WriterInstance implements Writer {
|
|
|
289
257
|
|
|
290
258
|
// Case 2: No active streams → perform actual close
|
|
291
259
|
this.logger.debug(`${this.uri} closes stream`)
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
260
|
+
if (!issued) {
|
|
261
|
+
await this.notifyOrchestrator({
|
|
262
|
+
close: { channel: this.uri },
|
|
263
|
+
})
|
|
264
|
+
}
|
|
296
265
|
|
|
297
266
|
let resolve = this.shouldClose.pop()
|
|
298
267
|
while (resolve) {
|
|
@@ -304,9 +273,13 @@ export class WriterInstance implements Writer {
|
|
|
304
273
|
/**
|
|
305
274
|
* A message is handled, let's notify the fifo {@link awaitProcessed}
|
|
306
275
|
*/
|
|
307
|
-
handled(): void {
|
|
276
|
+
handled(error?: string): void {
|
|
308
277
|
if (this.awaitingProcessed.length > 0) {
|
|
309
|
-
|
|
278
|
+
if (error) {
|
|
279
|
+
this.awaitingProcessed.shift()!.reject(new Error(error))
|
|
280
|
+
} else {
|
|
281
|
+
this.awaitingProcessed.shift()!.resolve()
|
|
282
|
+
}
|
|
310
283
|
} else if (this.closed || this._canceled) {
|
|
311
284
|
// A late ack can arrive after a close/cancel race; nothing to resolve anymore.
|
|
312
285
|
return
|
|
@@ -317,4 +290,24 @@ export class WriterInstance implements Writer {
|
|
|
317
290
|
)
|
|
318
291
|
}
|
|
319
292
|
}
|
|
293
|
+
|
|
294
|
+
private async emitCancel() {
|
|
295
|
+
await Promise.all(
|
|
296
|
+
Array.from(this.cancelHandlers).map(async (handler) => {
|
|
297
|
+
try {
|
|
298
|
+
await handler()
|
|
299
|
+
} catch (error: unknown) {
|
|
300
|
+
this.logger.error(
|
|
301
|
+
`Cancel listener for channel ${this.uri} failed: ${String(error)}`,
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
}),
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private awaitProcessed(): Promise<void> {
|
|
309
|
+
return new Promise((resolve, reject) =>
|
|
310
|
+
this.awaitingProcessed.push({ resolve, reject }),
|
|
311
|
+
)
|
|
312
|
+
}
|
|
320
313
|
}
|
package/dist/args.d.ts
DELETED