@rdfc/js-runner 3.0.2 → 3.0.4-remote

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.
Files changed (84) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/README.md +41 -1
  3. package/__tests__/echoProcessor.test.ts +11 -12
  4. package/bin/runner.js +7 -1
  5. package/bin/server.js +13 -0
  6. package/bun.lock +820 -0
  7. package/examples/echo/.idea/echo.iml +9 -0
  8. package/examples/echo/.idea/misc.xml +6 -0
  9. package/{.idea → examples/echo/.idea}/modules.xml +1 -1
  10. package/examples/echo/.idea/vcs.xml +7 -0
  11. package/examples/echo/.swls/config.json +1 -0
  12. package/examples/echo/package-lock.json +27 -29
  13. package/examples/echo/pipeline.ttl +0 -1
  14. package/examples/echo/processors.ttl +1 -1
  15. package/examples/echo/remote_pipeline.ttl +18 -0
  16. package/examples/echo/server.ttl +5 -0
  17. package/examples/echo/untitled:/types/MyType.ttl +0 -0
  18. package/file:/home/silvius/Projects/mumo-pipeline/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
  19. package/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
  20. package/lib/client.d.ts +2 -1
  21. package/lib/client.js +70 -22
  22. package/lib/index.d.ts +2 -0
  23. package/lib/index.js +3 -1
  24. package/lib/jsonld.d.ts +17 -0
  25. package/lib/jsonld.js +135 -0
  26. package/lib/logger.d.ts +1 -0
  27. package/lib/logger.js +19 -9
  28. package/lib/reader.d.ts +4 -1
  29. package/lib/reader.js +11 -3
  30. package/lib/runner.d.ts +6 -1
  31. package/lib/runner.js +43 -15
  32. package/lib/server.d.ts +9 -0
  33. package/lib/server.js +459 -0
  34. package/lib/state.d.ts +32 -0
  35. package/lib/state.js +71 -0
  36. package/lib/testUtils/duplex.js +1 -1
  37. package/lib/testUtils/index.d.ts +9 -9
  38. package/lib/testUtils/index.js +9 -9
  39. package/lib/testUtils.d.ts +24 -0
  40. package/lib/testUtils.js +150 -0
  41. package/lib/tsconfig.tsbuildinfo +1 -1
  42. package/lib/writer.d.ts +5 -1
  43. package/lib/writer.js +26 -10
  44. package/minimal.ttl +99 -0
  45. package/package.json +21 -19
  46. package/src/client.ts +99 -24
  47. package/src/index.ts +2 -0
  48. package/src/logger.ts +15 -7
  49. package/src/reader.ts +19 -9
  50. package/src/runner.ts +61 -12
  51. package/src/server.ts +545 -0
  52. package/src/state.ts +105 -0
  53. package/src/testUtils/duplex.ts +1 -4
  54. package/src/testUtils/index.ts +25 -21
  55. package/src/writer.ts +36 -12
  56. package/.idea/LNKD.tech Editor.xml +0 -194
  57. package/.idea/codeStyles/Project.xml +0 -52
  58. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  59. package/.idea/copilot.data.migration.agent.xml +0 -6
  60. package/.idea/copilot.data.migration.ask.xml +0 -6
  61. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  62. package/.idea/copilot.data.migration.edit.xml +0 -6
  63. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  64. package/.idea/js-runner.iml +0 -12
  65. package/.idea/vcs.xml +0 -6
  66. package/dist/args.d.ts +0 -4
  67. package/dist/args.js +0 -58
  68. package/dist/connectors/file.d.ts +0 -15
  69. package/dist/connectors/file.js +0 -89
  70. package/dist/connectors/http.d.ts +0 -14
  71. package/dist/connectors/http.js +0 -82
  72. package/dist/connectors/kafka.d.ts +0 -48
  73. package/dist/connectors/kafka.js +0 -68
  74. package/dist/connectors/ws.d.ts +0 -10
  75. package/dist/connectors/ws.js +0 -72
  76. package/dist/connectors.d.ts +0 -73
  77. package/dist/connectors.js +0 -168
  78. package/dist/index.cjs +0 -732
  79. package/dist/index.d.ts +0 -42
  80. package/dist/index.js +0 -83
  81. package/dist/tsconfig.tsbuildinfo +0 -1
  82. package/dist/util.d.ts +0 -71
  83. package/dist/util.js +0 -92
  84. package/jest.config.js +0 -2
package/lib/writer.js CHANGED
@@ -9,16 +9,23 @@ export class WriterInstance {
9
9
  awaitingProcessed = [];
10
10
  openStreams = 0;
11
11
  shouldClose = [];
12
+ hasClosed = false;
13
+ remoteCloseReceived = false;
12
14
  runnerId;
13
- constructor(uri, client, notifyOrchestrator, runnerId, logger) {
15
+ tracker;
16
+ constructor(uri, client, notifyOrchestrator, runnerId, logger, tracker) {
14
17
  this.client = client;
15
18
  this.notifyOrchestrator = notifyOrchestrator;
16
19
  this.uri = uri;
17
20
  this.logger = logger;
18
21
  this.runnerId = runnerId;
22
+ this.tracker = tracker;
19
23
  }
20
- awaitProcessed() {
21
- return new Promise((res) => this.awaitingProcessed.push(res));
24
+ awaitProcessed(bytes) {
25
+ const startMs = Date.now();
26
+ return new Promise((resolve) => {
27
+ this.awaitingProcessed.push({ resolve, startMs, bytes });
28
+ });
22
29
  }
23
30
  async any(any) {
24
31
  if ('stream' in any) {
@@ -34,7 +41,7 @@ export class WriterInstance {
34
41
  async buffer(buffer) {
35
42
  this.logger.debug(`${this.uri} sends buffer ${buffer.length} bytes`);
36
43
  const localSequenceNumber = this.localSequenceNumber++;
37
- const handledPromise = this.awaitProcessed();
44
+ const handledPromise = this.awaitProcessed(buffer.length);
38
45
  await this.notifyOrchestrator({
39
46
  msg: { data: buffer, channel: this.uri, localSequenceNumber },
40
47
  });
@@ -44,7 +51,7 @@ export class WriterInstance {
44
51
  this.openStreams += 1;
45
52
  const t = transform || ((x) => x);
46
53
  const stream = this.client.sendStreamMessage();
47
- const handledPromise = this.awaitProcessed();
54
+ const handledPromise = this.awaitProcessed(0);
48
55
  const writeStreamMessageChunk = promisify(stream.write.bind(stream));
49
56
  const localSequenceNumber = this.localSequenceNumber++;
50
57
  await writeStreamMessageChunk({
@@ -70,10 +77,11 @@ export class WriterInstance {
70
77
  async string(msg) {
71
78
  this.logger.debug(`${this.uri} sends string ${msg.length} characters`);
72
79
  const localSequenceNumber = this.localSequenceNumber++;
73
- const handledPromise = this.awaitProcessed();
80
+ const encoded = encoder.encode(msg);
81
+ const handledPromise = this.awaitProcessed(encoded.length);
74
82
  await this.notifyOrchestrator({
75
83
  msg: {
76
- data: encoder.encode(msg),
84
+ data: encoded,
77
85
  channel: this.uri,
78
86
  localSequenceNumber,
79
87
  },
@@ -81,12 +89,17 @@ export class WriterInstance {
81
89
  await handledPromise;
82
90
  }
83
91
  async close(issued = false) {
92
+ if (issued)
93
+ this.remoteCloseReceived = true;
84
94
  if (this.openStreams !== 0) {
85
95
  await new Promise((resolve) => this.shouldClose.push(resolve));
86
96
  return;
87
97
  }
98
+ if (this.hasClosed)
99
+ return;
100
+ this.hasClosed = true;
88
101
  this.logger.debug(`${this.uri} closes stream`);
89
- if (!issued) {
102
+ if (!this.remoteCloseReceived) {
90
103
  await this.notifyOrchestrator({
91
104
  close: { channel: this.uri },
92
105
  });
@@ -99,7 +112,10 @@ export class WriterInstance {
99
112
  }
100
113
  handled() {
101
114
  if (this.awaitingProcessed.length > 0) {
102
- this.awaitingProcessed.shift()();
115
+ const { resolve, startMs, bytes } = this.awaitingProcessed.shift();
116
+ const latencyMs = Date.now() - startMs;
117
+ this.tracker?.recordMessage(bytes, latencyMs);
118
+ resolve();
103
119
  }
104
120
  else {
105
121
  this.logger.error('Expected to be waiting for a message to be processed, but this is not the case ' +
@@ -107,4 +123,4 @@ export class WriterInstance {
107
123
  }
108
124
  }
109
125
  }
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBbUJoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEdBQUcsQ0FBUTtJQUNwQixtQkFBbUIsR0FBVyxDQUFDLENBQUE7SUFDZCxNQUFNLENBQWM7SUFDcEIsa0JBQWtCLENBQVU7SUFDNUIsTUFBTSxDQUFRO0lBRXZCLGlCQUFpQixHQUFzQixFQUFFLENBQUE7SUFFekMsV0FBVyxHQUFXLENBQUMsQ0FBQTtJQUN2QixXQUFXLEdBQXNCLEVBQUUsQ0FBQTtJQUUxQixRQUFRLENBQVE7SUFFakMsWUFDRSxHQUFXLEVBQ1gsTUFBb0IsRUFDcEIsa0JBQTRCLEVBQzVCLFFBQWdCLEVBQ2hCLE1BQWM7UUFFZCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUE7UUFDNUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUE7UUFDZCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtJQUMxQixDQUFDO0lBRU8sY0FBYztRQUNwQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDL0QsQ0FBQztJQUVELEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBUTtRQUNoQixJQUFJLFFBQVEsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FB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R0FBRyxFQUFFLENBQUE7UUFDcEMsT0FBTyxPQUFPLEVBQUUsQ0FBQztZQUNmLE9BQU8sRUFBRSxDQUFBO1lBQ1QsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDbEMsQ0FBQztJQUNILENBQUM7SUFLRCxPQUFPO1FBQ0wsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUcsRUFBRSxDQUFBO1FBQ25DLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2YsaUZBQWlGO2dCQUMvRSxJQUFJLENBQUMsR0FBRyxDQUNYLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRnJvbVJ1bm5lciwgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnd2luc3RvbidcbmltcG9ydCB7IEFueSB9IGZyb20gJy4vcmVhZGVyJ1xuXG50eXBlIFdyaXRhYmxlID0gKG1zZzogRnJvbVJ1bm5lcikgPT4gUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICByZWFkb25seSB1cmk6IHN0cmluZ1xuICBidWZmZXIoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmVhbShidWZmZXI6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBQcm9taXNlPHZvaWQ+XG4gIHN0cmVhbTxUPihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtOiAoeDogVCkgPT4gVWludDhBcnJheSxcbiAgKTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmluZyhidWZmZXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cbiAgYW55KGFueTogQW55KTogUHJvbWlzZTx2b2lkPlxuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+XG59XG5jb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKClcbmV4cG9ydCBjbGFzcyBXcml0ZXJJbnN0YW5jZSBpbXBsZW1lbnRzIFdyaXRlciB7XG4gIHJlYWRvbmx5IHVyaTogc3RyaW5nXG4gIGxvY2FsU2VxdWVuY2VOdW1iZXI6IG51bWJlciA9IDFcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFJ1bm5lckNsaWVudFxuICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGVcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlclxuXG4gIHByaXZhdGUgYXdhaXRpbmdQcm9jZXNzZWQ6IEFycmF5PCgpID0+IHZvaWQ+ID0gW11cblxuICBwcml2YXRlIG9wZW5TdHJlYW1zOiBudW1iZXIgPSAwXG4gIHByaXZhdGUgc2hvdWxkQ2xvc2U6IEFycmF5PCgpID0+IHZvaWQ+ID0gW11cblxuICBwcml2YXRlIHJlYWRvbmx5IHJ1bm5lcklkOiBzdHJpbmdcblxuICBjb25zdHJ1Y3RvcihcbiAgICB1cmk6IHN0cmluZyxcbiAgICBjbGllbnQ6IFJ1bm5lckNsaWVudCxcbiAgICBub3RpZnlPcmNoZXN0cmF0b3I6IFdyaXRhYmxlLFxuICAgIHJ1bm5lcklkOiBzdHJpbmcsXG4gICAgbG9nZ2VyOiBMb2dnZXIsXG4gICkge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50XG4gICAgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3IgPSBub3RpZnlPcmNoZXN0cmF0b3JcbiAgICB0aGlzLnVyaSA9IHVyaVxuICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyXG4gICAgdGhpcy5ydW5uZXJJZCA9IHJ1bm5lcklkXG4gIH1cblxuICBwcml2YXRlIGF3YWl0UHJvY2Vzc2VkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzKSA9PiB0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLnB1c2gocmVzKSlcbiAgfVxuXG4gIGFzeW5jIGFueShhbnk6IEFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICgnc3RyZWFtJyBpbiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RyZWFtKGFueS5zdHJlYW0pXG4gICAgfVxuICAgIGlmICgnYnVmZmVyJyBpbiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuYnVmZmVyKGFueS5idWZmZXIpXG4gICAgfVxuICAgIGlmICgnc3RyaW5nJyBpbiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RyaW5nKGFueS5zdHJpbmcpXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYnVmZmVyKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3RoaXMudXJpfSBzZW5kcyBidWZmZXIgJHtidWZmZXIubGVuZ3RofSBieXRlc2ApXG4gICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgY29uc3QgaGFuZGxlZFByb21pc2UgPSB0aGlzLmF3YWl0UHJvY2Vzc2VkKClcblxuICAgIGF3YWl0IHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yKHtcbiAgICAgIG1zZzogeyBkYXRhOiBidWZmZXIsIGNoYW5uZWw6IHRoaXMudXJpLCBsb2NhbFNlcXVlbmNlTnVtYmVyIH0sXG4gICAgfSlcbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgYXN5bmMgc3RyZWFtPFQgPSBVaW50OEFycmF5PihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtPzogKHg6IFQpID0+IFVpbnQ4QXJyYXksXG4gICkge1xuICAgIHRoaXMub3BlblN0cmVhbXMgKz0gMVxuICAgIGNvbnN0IHQgPSB0cmFuc2Zvcm0gfHwgKCh4OiB1bmtub3duKSA9PiA8VWludDhBcnJheT54KVxuICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuY2xpZW50LnNlbmRTdHJlYW1NZXNzYWdlKClcblxuICAgIGNvbnN0IGhhbmRsZWRQcm9taXNlID0gdGhpcy5hd2FpdFByb2Nlc3NlZCgpXG4gICAgY29uc3Qgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsgPSBwcm9taXNpZnkoc3RyZWFtLndyaXRlLmJpbmQoc3RyZWFtKSlcbiAgICBjb25zdCBsb2NhbFNlcXVlbmNlTnVtYmVyID0gdGhpcy5sb2NhbFNlcXVlbmNlTnVtYmVyKytcbiAgICBhd2FpdCB3cml0ZVN0cmVhbU1lc3NhZ2VDaHVuayh7XG4gICAgICBpZDoge1xuICAgICAgICBjaGFubmVsOiB0aGlzLnVyaSxcbiAgICAgICAgbG9jYWxTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgcnVubmVyOiB0aGlzLnJ1bm5lcklkLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgY29uc3QgaWQgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzKSA9PiBzdHJlYW0ub25jZSgnZGF0YScsIHJlcykpXG5cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgIGAke3RoaXMudXJpfSBzdHJlYW1zIG1lc3NhZ2Ugd2l0aCBpZCAke0pTT04uc3RyaW5naWZ5KGlkKX1gLFxuICAgIClcblxuICAgIGZvciBhd2FpdCAoY29uc3QgbXNnIG9mIGJ1ZmZlcikge1xuICAgICAgY29uc3QgcHJvY2Vzc2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMpID0+IHN0cmVhbS5vbmNlKCdkYXRhJywgcmVzKSlcbiAgICAgIGF3YWl0IHdyaXRlU3RyZWFtTWVzc2FnZUNodW5rKHsgZGF0YTogeyBkYXRhOiB0KG1zZykgfSB9KVxuICAgICAgLy8gQXdhaXQgYSBtZXNzYWdlIG9uIHRoZSBzdHJlYW0sIGluZGljYXRpbmcgdGhhdCB0aGUgY2h1bmsgaGFzIGJlZW4gcHJvY2Vzc2VkXG4gICAgICBhd2FpdCBwcm9jZXNzZWRQcm9taXNlXG4gICAgfVxuXG4gICAgc3RyZWFtLmVuZCgpXG5cbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuXG4gICAgdGhpcy5vcGVuU3RyZWFtcyAtPSAxXG5cbiAgICBpZiAodGhpcy5zaG91bGRDbG9zZS5sZW5ndGggPiAwKSBhd2FpdCB0aGlzLmNsb3NlKClcbiAgfVxuXG4gIGFzeW5jIHN0cmluZyhtc2c6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3RoaXMudXJpfSBzZW5kcyBzdHJpbmcgJHttc2cubGVuZ3RofSBjaGFyYWN0ZXJzYClcbiAgICBjb25zdCBsb2NhbFNlcXVlbmNlTnVtYmVyID0gdGhpcy5sb2NhbFNlcXVlbmNlTnVtYmVyKytcbiAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoKVxuXG4gICAgYXdhaXQgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3Ioe1xuICAgICAgbXNnOiB7XG4gICAgICAgIGRhdGE6IGVuY29kZXIuZW5jb2RlKG1zZyksXG4gICAgICAgIGNoYW5uZWw6IHRoaXMudXJpLFxuICAgICAgICBsb2NhbFNlcXVlbmNlTnVtYmVyLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgYXdhaXQgaGFuZGxlZFByb21pc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFjZWZ1bGx5IGNsb3NlcyB0aGlzIGNoYW5uZWwuXG4gICAqXG4gICAqIEJlaGF2aW9yOlxuICAgKiAtIElmIHRoZXJlIGFyZSBzdGlsbCBhY3RpdmUgc3RyZWFtcywgY2xvc2luZyBpcyBkZWZlcnJlZCB1bnRpbCB0aGV5IGNvbXBsZXRlLlxuICAgKiAtIElmIG11bHRpcGxlIGNhbGxlcnMgaW52b2tlIGBjbG9zZSgpYCB3aGlsZSB3YWl0aW5nLCB0aGVpciBQcm9taXNlcyBhcmUgcXVldWVkIGFuZFxuICAgKiAgIHJlc29sdmVkIG9uY2UgdGhlIGNoYW5uZWwgYWN0dWFsbHkgY2xvc2VzLlxuICAgKiAtIElmIHRoaXMgc2lkZSBpbml0aWF0ZWQgdGhlIGNsb3NlIChgaXNzdWVkID0gZmFsc2VgKSwgYSBjbG9zZSBtZXNzYWdlIGlzIHNlbnQgdG8gdGhlIHJlbW90ZS5cbiAgICpcbiAgICogQHBhcmFtIGlzc3VlZCAtIElmIHRydWUsIGluZGljYXRlcyB0aGUgY2xvc2UgcmVxdWVzdCBvcmlnaW5hdGVkIHJlbW90ZWx5XG4gICAqL1xuICBhc3luYyBjbG9zZShpc3N1ZWQgPSBmYWxzZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIENhc2UgMTogQWN0aXZlIHN0cmVhbXMgc3RpbGwgcnVubmluZyDihpIgd2FpdCB1bnRpbCB0aGV5IGZpbmlzaFxuICAgIGlmICh0aGlzLm9wZW5TdHJlYW1zICE9PSAwKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gdGhpcy5zaG91bGRDbG9zZS5wdXNoKHJlc29sdmUpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBObyBhY3RpdmUgc3RyZWFtcyDihpIgcGVyZm9ybSBhY3R1YWwgY2xvc2VcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHt0aGlzLnVyaX0gY2xvc2VzIHN0cmVhbWApXG4gICAgaWYgKCFpc3N1ZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMubm90aWZ5T3JjaGVzdHJhdG9yKHtcbiAgICAgICAgY2xvc2U6IHsgY2hhbm5lbDogdGhpcy51cmkgfSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgbGV0IHJlc29sdmUgPSB0aGlzLnNob3VsZENsb3NlLnBvcCgpXG4gICAgd2hpbGUgKHJlc29sdmUpIHtcbiAgICAgIHJlc29sdmUoKVxuICAgICAgcmVzb2x2ZSA9IHRoaXMuc2hvdWxkQ2xvc2UucG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQSBtZXNzYWdlIGlzIGhhbmRsZWQsIGxldCdzIG5vdGlmeSB0aGUgZmlmbyB7QGxpbmsgYXdhaXRQcm9jZXNzZWR9XG4gICAqL1xuICBoYW5kbGVkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmF3YWl0aW5nUHJvY2Vzc2VkLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQuc2hpZnQoKSEoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihcbiAgICAgICAgJ0V4cGVjdGVkIHRvIGJlIHdhaXRpbmcgZm9yIGEgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQsIGJ1dCB0aGlzIGlzIG5vdCB0aGUgY2FzZSAnICtcbiAgICAgICAgICB0aGlzLnVyaSxcbiAgICAgIClcbiAgICB9XG4gIH1cbn1cbiJdfQ==
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBb0JoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEdBQUcsQ0FBUTtJQUNwQixtQkFBbUIsR0FBVyxDQUFDLENBQUE7SUFDZCxNQUFNLENBQWM7SUFDcEIsa0JBQWtCLENBQVU7SUFDNUIsTUFBTSxDQUFRO0lBRXZCLGlCQUFpQixHQUlwQixFQUFFLENBQUE7SUFFQyxXQUFXLEdBQVcsQ0FBQyxDQUFBO0lBQ3ZCLFdBQVcsR0FBc0IsRUFBRSxDQUFBO0lBQ25DLFNBQVMsR0FBRyxLQUFLLENBQUE7SUFDakIsbUJBQW1CLEdBQUcsS0FBSyxDQUFBO0lBRWxCLFFBQVEsQ0FBUTtJQUNoQixPQUFPLENBQTRCO0lBRXBELFlBQ0UsR0FBVyxFQUNYLE1BQW9CLEVBQ3BCLGtCQUE0QixFQUM1QixRQUFnQixFQUNoQixNQUFjLEVBQ2QsT0FBd0I7UUFFeEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFBO1FBQzVDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFBO1FBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7UUFDeEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUE7SUFDeEIsQ0FBQztJQUVPLGNBQWMsQ0FBQyxLQUFhO1FBQ2xDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQTtRQUMxQixPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLGlC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QU0sQ0FBQyxLQUFLLENBQ2YsaUZBQWlGO2dCQUMvRSxJQUFJLENBQUMsR0FBRyxDQUNYLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRnJvbVJ1bm5lciwgUnVubmVyQ2xpZW50IH0gZnJvbSAnQHJkZmMvcHJvdG8nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnd2luc3RvbidcbmltcG9ydCB7IEFueSB9IGZyb20gJy4vcmVhZGVyJ1xuaW1wb3J0IHsgQ2hhbm5lbFRyYWNrZXIgfSBmcm9tICcuL3N0YXRlJ1xuXG50eXBlIFdyaXRhYmxlID0gKG1zZzogRnJvbVJ1bm5lcikgPT4gUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXIge1xuICByZWFkb25seSB1cmk6IHN0cmluZ1xuICBidWZmZXIoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmVhbShidWZmZXI6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBQcm9taXNlPHZvaWQ+XG4gIHN0cmVhbTxUPihcbiAgICBidWZmZXI6IEFzeW5jSXRlcmFibGU8VD4sXG4gICAgdHJhbnNmb3JtOiAoeDogVCkgPT4gVWludDhBcnJheSxcbiAgKTogUHJvbWlzZTx2b2lkPlxuXG4gIHN0cmluZyhidWZmZXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cbiAgYW55KGFueTogQW55KTogUHJvbWlzZTx2b2lkPlxuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+XG59XG5jb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKClcbmV4cG9ydCBjbGFzcyBXcml0ZXJJbnN0YW5jZSBpbXBsZW1lbnRzIFdyaXRlciB7XG4gIHJlYWRvbmx5IHVyaTogc3RyaW5nXG4gIGxvY2FsU2VxdWVuY2VOdW1iZXI6IG51bWJlciA9IDFcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFJ1bm5lckNsaWVudFxuICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGVcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlclxuXG4gIHByaXZhdGUgYXdhaXRpbmdQcm9jZXNzZWQ6IEFycmF5PHtcbiAgICByZXNvbHZlOiAoKSA9PiB2b2lkXG4gICAgc3RhcnRNczogbnVtYmVyXG4gICAgYnl0ZXM6IG51bWJlclxuICB9PiA9IFtdXG5cbiAgcHJpdmF0ZSBvcGVuU3RyZWFtczogbnVtYmVyID0gMFxuICBwcml2YXRlIHNob3VsZENsb3NlOiBBcnJheTwoKSA9PiB2b2lkPiA9IFtdXG4gIHByaXZhdGUgaGFzQ2xvc2VkID0gZmFsc2VcbiAgcHJpdmF0ZSByZW1vdGVDbG9zZVJlY2VpdmVkID0gZmFsc2VcblxuICBwcml2YXRlIHJlYWRvbmx5IHJ1bm5lcklkOiBzdHJpbmdcbiAgcHJpdmF0ZSByZWFkb25seSB0cmFja2VyOiBDaGFubmVsVHJhY2tlciB8IHVuZGVmaW5lZFxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHVyaTogc3RyaW5nLFxuICAgIGNsaWVudDogUnVubmVyQ2xpZW50LFxuICAgIG5vdGlmeU9yY2hlc3RyYXRvcjogV3JpdGFibGUsXG4gICAgcnVubmVySWQ6IHN0cmluZyxcbiAgICBsb2dnZXI6IExvZ2dlcixcbiAgICB0cmFja2VyPzogQ2hhbm5lbFRyYWNrZXIsXG4gICkge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50XG4gICAgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3IgPSBub3RpZnlPcmNoZXN0cmF0b3JcbiAgICB0aGlzLnVyaSA9IHVyaVxuICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyXG4gICAgdGhpcy5ydW5uZXJJZCA9IHJ1bm5lcklkXG4gICAgdGhpcy50cmFja2VyID0gdHJhY2tlclxuICB9XG5cbiAgcHJpdmF0ZSBhd2FpdFByb2Nlc3NlZChieXRlczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnRNcyA9IERhdGUubm93KClcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQucHVzaCh7IHJlc29sdmUsIHN0YXJ0TXMsIGJ5dGVzIH0pXG4gICAgfSlcbiAgfVxuXG4gIGFzeW5jIGFueShhbnk6IEFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICgnc3RyZWFtJyBpbiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RyZWFtKGFueS5zdHJlYW0pXG4gICAgfVxuICAgIGlmICgnYnVmZmVyJyBpbiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuYnVmZmVyKGFueS5idWZmZXIpXG4gICAgfVxuICAgIGlmICgnc3RyaW5nJyBpbiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RyaW5nKGFueS5zdHJpbmcpXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgYnVmZmVyKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3RoaXMudXJpfSBzZW5kcyBidWZmZXIgJHtidWZmZXIubGVuZ3RofSBieXRlc2ApXG4gICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgY29uc3QgaGFuZGxlZFByb21pc2UgPSB0aGlzLmF3YWl0UHJvY2Vzc2VkKGJ1ZmZlci5sZW5ndGgpXG5cbiAgICBhd2FpdCB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvcih7XG4gICAgICBtc2c6IHsgZGF0YTogYnVmZmVyLCBjaGFubmVsOiB0aGlzLnVyaSwgbG9jYWxTZXF1ZW5jZU51bWJlciB9LFxuICAgIH0pXG4gICAgYXdhaXQgaGFuZGxlZFByb21pc2VcbiAgfVxuXG4gIGFzeW5jIHN0cmVhbTxUID0gVWludDhBcnJheT4oXG4gICAgYnVmZmVyOiBBc3luY0l0ZXJhYmxlPFQ+LFxuICAgIHRyYW5zZm9ybT86ICh4OiBUKSA9PiBVaW50OEFycmF5LFxuICApIHtcbiAgICB0aGlzLm9wZW5TdHJlYW1zICs9IDFcbiAgICBjb25zdCB0ID0gdHJhbnNmb3JtIHx8ICgoeDogdW5rbm93bikgPT4gPFVpbnQ4QXJyYXk+eClcbiAgICBjb25zdCBzdHJlYW0gPSB0aGlzLmNsaWVudC5zZW5kU3RyZWFtTWVzc2FnZSgpXG5cbiAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoMCkgLy8gYnl0ZXMgdW5rbm93biBmb3Igc3RyZWFtc1xuICAgIGNvbnN0IHdyaXRlU3RyZWFtTWVzc2FnZUNodW5rID0gcHJvbWlzaWZ5KHN0cmVhbS53cml0ZS5iaW5kKHN0cmVhbSkpXG4gICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgYXdhaXQgd3JpdGVTdHJlYW1NZXNzYWdlQ2h1bmsoe1xuICAgICAgaWQ6IHtcbiAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICAgIHJ1bm5lcjogdGhpcy5ydW5uZXJJZCxcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIGNvbnN0IGlkID0gYXdhaXQgbmV3IFByb21pc2UoKHJlcykgPT4gc3RyZWFtLm9uY2UoJ2RhdGEnLCByZXMpKVxuXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICBgJHt0aGlzLnVyaX0gc3RyZWFtcyBtZXNzYWdlIHdpdGggaWQgJHtKU09OLnN0cmluZ2lmeShpZCl9YCxcbiAgICApXG5cbiAgICBmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBidWZmZXIpIHtcbiAgICAgIGNvbnN0IHByb2Nlc3NlZFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzKSA9PiBzdHJlYW0ub25jZSgnZGF0YScsIHJlcykpXG4gICAgICBhd2FpdCB3cml0ZVN0cmVhbU1lc3NhZ2VDaHVuayh7IGRhdGE6IHsgZGF0YTogdChtc2cpIH0gfSlcbiAgICAgIC8vIEF3YWl0IGEgbWVzc2FnZSBvbiB0aGUgc3RyZWFtLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGNodW5rIGhhcyBiZWVuIHByb2Nlc3NlZFxuICAgICAgYXdhaXQgcHJvY2Vzc2VkUHJvbWlzZVxuICAgIH1cblxuICAgIHN0cmVhbS5lbmQoKVxuXG4gICAgYXdhaXQgaGFuZGxlZFByb21pc2VcblxuICAgIHRoaXMub3BlblN0cmVhbXMgLT0gMVxuXG4gICAgaWYgKHRoaXMuc2hvdWxkQ2xvc2UubGVuZ3RoID4gMCkgYXdhaXQgdGhpcy5jbG9zZSgpXG4gIH1cblxuICBhc3luYyBzdHJpbmcobXNnOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHt0aGlzLnVyaX0gc2VuZHMgc3RyaW5nICR7bXNnLmxlbmd0aH0gY2hhcmFjdGVyc2ApXG4gICAgY29uc3QgbG9jYWxTZXF1ZW5jZU51bWJlciA9IHRoaXMubG9jYWxTZXF1ZW5jZU51bWJlcisrXG4gICAgY29uc3QgZW5jb2RlZCA9IGVuY29kZXIuZW5jb2RlKG1zZylcbiAgICBjb25zdCBoYW5kbGVkUHJvbWlzZSA9IHRoaXMuYXdhaXRQcm9jZXNzZWQoZW5jb2RlZC5sZW5ndGgpXG5cbiAgICBhd2FpdCB0aGlzLm5vdGlmeU9yY2hlc3RyYXRvcih7XG4gICAgICBtc2c6IHtcbiAgICAgICAgZGF0YTogZW5jb2RlZCxcbiAgICAgICAgY2hhbm5lbDogdGhpcy51cmksXG4gICAgICAgIGxvY2FsU2VxdWVuY2VOdW1iZXIsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBhd2FpdCBoYW5kbGVkUHJvbWlzZVxuICB9XG5cbiAgLyoqXG4gICAqIEdyYWNlZnVsbHkgY2xvc2VzIHRoaXMgY2hhbm5lbC5cbiAgICpcbiAgICogQmVoYXZpb3I6XG4gICAqIC0gSWYgdGhlcmUgYXJlIHN0aWxsIGFjdGl2ZSBzdHJlYW1zLCBjbG9zaW5nIGlzIGRlZmVycmVkIHVudGlsIHRoZXkgY29tcGxldGUuXG4gICAqIC0gSWYgbXVsdGlwbGUgY2FsbGVycyBpbnZva2UgYGNsb3NlKClgIHdoaWxlIHdhaXRpbmcsIHRoZWlyIFByb21pc2VzIGFyZSBxdWV1ZWQgYW5kXG4gICAqICAgcmVzb2x2ZWQgb25jZSB0aGUgY2hhbm5lbCBhY3R1YWxseSBjbG9zZXMuXG4gICAqIC0gQSBjbG9zZSBtZXNzYWdlIGlzIHNlbnQgdG8gdGhlIHJlbW90ZSBvbmx5IGlmIHRoZSBjbG9zZSB3YXMgbG9jYWxseSBpbml0aWF0ZWQgYW5kXG4gICAqICAgdGhlIHJlbW90ZSBoYXMgbm90IGFscmVhZHkgc2VudCBhIGNsb3NlLlxuICAgKlxuICAgKiBAcGFyYW0gaXNzdWVkIC0gSWYgdHJ1ZSwgaW5kaWNhdGVzIHRoZSBjbG9zZSByZXF1ZXN0IG9yaWdpbmF0ZWQgcmVtb3RlbHlcbiAgICovXG4gIGFzeW5jIGNsb3NlKGlzc3VlZCA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGlzc3VlZCkgdGhpcy5yZW1vdGVDbG9zZVJlY2VpdmVkID0gdHJ1ZVxuXG4gICAgLy8gQ2FzZSAxOiBBY3RpdmUgc3RyZWFtcyBzdGlsbCBydW5uaW5nIOKGkiBkZWZlciB1bnRpbCB0aGV5IGZpbmlzaFxuICAgIGlmICh0aGlzLm9wZW5TdHJlYW1zICE9PSAwKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gdGhpcy5zaG91bGRDbG9zZS5wdXNoKHJlc29sdmUpKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2FzZSAyOiBBbHJlYWR5IGNsb3NlZCDigJQgbm90aGluZyB0byBkb1xuICAgIGlmICh0aGlzLmhhc0Nsb3NlZCkgcmV0dXJuXG4gICAgdGhpcy5oYXNDbG9zZWQgPSB0cnVlXG5cbiAgICAvLyBDYXNlIDM6IE5vIGFjdGl2ZSBzdHJlYW1zIOKGkiBwZXJmb3JtIGFjdHVhbCBjbG9zZVxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke3RoaXMudXJpfSBjbG9zZXMgc3RyZWFtYClcbiAgICBpZiAoIXRoaXMucmVtb3RlQ2xvc2VSZWNlaXZlZCkge1xuICAgICAgYXdhaXQgdGhpcy5ub3RpZnlPcmNoZXN0cmF0b3Ioe1xuICAgICAgICBjbG9zZTogeyBjaGFubmVsOiB0aGlzLnVyaSB9LFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBsZXQgcmVzb2x2ZSA9IHRoaXMuc2hvdWxkQ2xvc2UucG9wKClcbiAgICB3aGlsZSAocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZSgpXG4gICAgICByZXNvbHZlID0gdGhpcy5zaG91bGRDbG9zZS5wb3AoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBIG1lc3NhZ2UgaXMgaGFuZGxlZCwgbGV0J3Mgbm90aWZ5IHRoZSBmaWZvIHtAbGluayBhd2FpdFByb2Nlc3NlZH1cbiAgICovXG4gIGhhbmRsZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXdhaXRpbmdQcm9jZXNzZWQubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgeyByZXNvbHZlLCBzdGFydE1zLCBieXRlcyB9ID0gdGhpcy5hd2FpdGluZ1Byb2Nlc3NlZC5zaGlmdCgpIVxuICAgICAgY29uc3QgbGF0ZW5jeU1zID0gRGF0ZS5ub3coKSAtIHN0YXJ0TXNcbiAgICAgIHRoaXMudHJhY2tlcj8ucmVjb3JkTWVzc2FnZShieXRlcywgbGF0ZW5jeU1zKVxuICAgICAgcmVzb2x2ZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAnRXhwZWN0ZWQgdG8gYmUgd2FpdGluZyBmb3IgYSBtZXNzYWdlIHRvIGJlIHByb2Nlc3NlZCwgYnV0IHRoaXMgaXMgbm90IHRoZSBjYXNlICcgK1xuICAgICAgICAgIHRoaXMudXJpLFxuICAgICAgKVxuICAgIH1cbiAgfVxufVxuIl19
package/minimal.ttl ADDED
@@ -0,0 +1,99 @@
1
+ @prefix prov: <http://www.w3.org/ns/prov#>.
2
+ @prefix sds: <https://w3id.org/sds#>.
3
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
4
+ @prefix owl: <http://www.w3.org/2002/07/owl#>.
5
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
6
+ @prefix sh: <http://www.w3.org/ns/shacl#>.
7
+ @prefix rdfc: <https://w3id.org/rdf-connect#>.
8
+
9
+ ############################################################
10
+ # General statements #
11
+ ############################################################
12
+ # sds:Activity is a prov:Activity
13
+ sds:Activity rdfs:subClassOf prov:Activity.
14
+
15
+ # rdfc:Processor too
16
+ rdfc:Processor rdfs:subClassOf sds:Activity.
17
+
18
+ # sds:implementationOf is subClassOf
19
+ sds:implementationOf rdfs:subPropertyOf rdfs:subClassOf.
20
+
21
+ ############################################################
22
+ # Javascript statements #
23
+ ############################################################
24
+ # specialized for js too
25
+ rdfc:jsImplementationOf rdfs:subPropertyOf sds:implementationOf.
26
+
27
+ # A node runner, runs things that are rdfc:jsImplementationOf rdfc:Processor (aka, rdfs:subClassOf prov:Activity)
28
+ rdfc:NodeRunner a rdfc:Runner;
29
+ rdfc:handlesSubjectsOf rdfc:jsImplementationOf;
30
+ rdfc:command "npx js-runner".
31
+
32
+ # This shouldn't be necessary, should work with sh:targetSubjectsOf
33
+ # rdfc:processor_definition <JsProcessorShape>.
34
+ #
35
+ # Shape that a Js Processor should fulfil;
36
+ [ ] a sh:NodeShape;
37
+ # This shouldn't be necessary,should work with sh:targetSubjectsOf and this isn't a real Class
38
+ sh:targetClass <JsProcessorShape>;
39
+ # We target it with jsImplementationOf
40
+ sh:targetSubjectsOf rdfc:jsImplementationOf;
41
+ sh:property [
42
+ sh:path rdfc:entrypoint;
43
+ sh:name "location";
44
+ sh:minCount 1;
45
+ sh:maxCount 1;
46
+ sh:datatype xsd:iri;
47
+ ], [
48
+ sh:path rdfc:file;
49
+ sh:name "file";
50
+ sh:minCount 1;
51
+ sh:maxCount 1;
52
+ sh:datatype xsd:iri;
53
+ ], [
54
+ sh:path rdfc:class;
55
+ sh:name "clazz";
56
+ sh:maxCount 1;
57
+ sh:datatype xsd:string;
58
+ ].
59
+
60
+ ############################################################
61
+ # Processor statements #
62
+ ############################################################
63
+ rdfc:FooBarProcessor a owl:Class;
64
+ rdfs:label "My Epic FooBar Processor";
65
+ rdfs:description "FooBars everything!";
66
+ rdfc:jsImplementationOf rdfc:Processor;
67
+ rdfc:entrypoint <./>;
68
+ rdfc:file <./lib/processors.js>;
69
+ rdfc:class "FooBarProcessor".
70
+
71
+ [ ] a sh:NodeShape;
72
+ sh:targetClass rdfc:FooBarProcessor;
73
+ sh:property [
74
+ sh:path rdfc:reader;
75
+ sh:name "reader";
76
+ sh:minCount 1;
77
+ sh:maxCount 1;
78
+ sh:class rdfc:Reader;
79
+ ], [
80
+ sh:path rdfc:writer;
81
+ sh:name "writer";
82
+ sh:maxCount 1;
83
+ sh:class rdfc:Writer;
84
+ ].
85
+
86
+ ############################################################
87
+ # Pipeline statements #
88
+ ############################################################
89
+ <> a rdfc:Pipeline;
90
+ rdfc:consistsOf [
91
+ rdfc:instantiates rdfc:NodeRunner;
92
+ rdfc:processor <foobar>;
93
+ ].
94
+
95
+ <incomingMessages> a rdfc:Reader, rdfc:Writer.
96
+ <foobar> a rdfc:FooBarProcessor;
97
+ rdfc:reader <incomingMessages>;
98
+ rdfc:writer <incomingMessages>.
99
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdfc/js-runner",
3
- "version": "3.0.2",
3
+ "version": "3.0.4-remote",
4
4
  "main": "lib/index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -11,7 +11,8 @@
11
11
  "prepare": "husky"
12
12
  },
13
13
  "bin": {
14
- "js-runner": "./bin/runner.js"
14
+ "js-runner": "./bin/runner.js",
15
+ "js-runner-server": "./bin/server.js"
15
16
  },
16
17
  "husky": {
17
18
  "hooks": {
@@ -25,32 +26,33 @@
25
26
  ]
26
27
  },
27
28
  "keywords": [],
28
- "author": "",
29
- "license": "ISC",
30
- "description": "",
29
+ "author": "Arthur Vercruysse",
30
+ "contributors": [
31
+ "Ieben Smessaert",
32
+ "Julián Rojas"
33
+ ],
34
+ "license": "MIT",
35
+ "description": "JavaScript runner implementation for RDF-Connect",
31
36
  "devDependencies": {
32
- "@eslint/js": "^9.39.2",
37
+ "@eslint/js": "^10.0.1",
33
38
  "@rdfjs/types": "^2.0.1",
34
- "@types/jest": "^30.0.0",
35
39
  "@types/jsonld": "^1.5.15",
36
40
  "@types/n3": "^1.26.1",
37
- "@types/node": "^24.10.9",
38
- "@typescript-eslint/eslint-plugin": "^8.54.0",
39
- "@typescript-eslint/parser": "^8.54.0",
40
- "@vitest/coverage-v8": "^4.0.18",
41
- "eslint": "^9.21.0",
41
+ "@types/node": "^25.5.0",
42
+ "@typescript-eslint/eslint-plugin": "^8.57.1",
43
+ "@typescript-eslint/parser": "^8.57.1",
44
+ "@vitest/coverage-v8": "^4.1.0",
45
+ "eslint": "^10.0.2",
42
46
  "eslint-config-prettier": "^10.1.8",
43
47
  "eslint-plugin-prettier": "^5.5.5",
44
- "globals": "^17.3.0",
48
+ "globals": "^17.4.0",
45
49
  "husky": "^9.1.7",
46
- "jest": "^30.2.0",
47
- "lint-staged": "^16.2.7",
50
+ "lint-staged": "^16.4.0",
48
51
  "prettier": "^3.8.1",
49
- "ts-jest": "^29.4.6",
50
52
  "tsc-alias": "^1.8.16",
51
53
  "typescript": "^5.9.3",
52
- "typescript-eslint": "^8.54.0",
53
- "vitest": "^4.0.18"
54
+ "typescript-eslint": "^8.57.1",
55
+ "vitest": "^4.1.0"
54
56
  },
55
57
  "dependencies": {
56
58
  "@grpc/grpc-js": "^1.14.3",
@@ -58,7 +60,7 @@
58
60
  "@treecg/types": "^0.4.6",
59
61
  "jsonld": "^9.0.0",
60
62
  "jsonld-streaming-parser": "^5.0.1",
61
- "n3": "^2.0.1",
63
+ "n3": "^2.0.3",
62
64
  "rdf-lens": "^1.3.6",
63
65
  "winston": "^3.19.0",
64
66
  "winston-transport": "^4.9.0"
package/src/client.ts CHANGED
@@ -4,46 +4,121 @@ import { RunnerClient, ToRunner } from '@rdfc/proto'
4
4
  import { createLogger } from 'winston'
5
5
  import { RpcTransport } from './logger'
6
6
  import { Runner } from './runner'
7
+ import { State } from './state'
7
8
 
8
- export async function start(addr: string, uri: string) {
9
+ const GRPC_STATE_NAMES = [
10
+ 'IDLE',
11
+ 'CONNECTING',
12
+ 'READY',
13
+ 'TRANSIENT_FAILURE',
14
+ 'SHUTDOWN',
15
+ ] as const
16
+
17
+ function watchGrpcState(
18
+ client: RunnerClient,
19
+ state: State,
20
+ runnerId: string,
21
+ signal: AbortSignal,
22
+ ): void {
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ const ch = (client as any).getChannel() as grpc.Channel
25
+
26
+ const update = () => {
27
+ if (signal.aborted) return
28
+ const s = ch.getConnectivityState(false)
29
+ state.setGrpcState(runnerId, GRPC_STATE_NAMES[s] ?? String(s))
30
+ if (s === grpc.connectivityState.SHUTDOWN) return
31
+ // Watch for the next state change (1-hour deadline)
32
+ ch.watchConnectivityState(s, new Date(Date.now() + 3_600_000), update)
33
+ }
34
+
35
+ update()
36
+ }
37
+
38
+ export async function start(
39
+ addr: string,
40
+ uri: string,
41
+ configPath?: string,
42
+ signal?: AbortSignal,
43
+ state?: State,
44
+ runnerId?: string,
45
+ ) {
9
46
  const client = new RunnerClient(addr, grpc.credentials.createInsecure())
10
47
 
48
+ const logStream = client.logStream(() => {})
49
+
11
50
  const logger = createLogger({
12
51
  transports: [
13
52
  new RpcTransport({
14
53
  entities: [uri, 'cli'],
15
- stream: client.logStream(() => {}),
54
+ stream: logStream,
16
55
  }),
17
56
  ],
18
57
  })
19
58
 
20
59
  const stream = client.connect()
21
60
 
22
- logger.info('Connected with server ' + addr)
23
- const writable = promisify(stream.write.bind(stream))
24
- const runner = new Runner(client, writable, uri, logger)
61
+ const closeConnection = () => {
62
+ stream.end()
63
+ logStream.end()
64
+ client.close()
65
+ }
25
66
 
26
- await writable({ identify: { uri } })
67
+ const abortCtrl = signal ?? new AbortController().signal
68
+ abortCtrl.addEventListener('abort', closeConnection, { once: true })
27
69
 
28
- /* eslint-disable no-async-promise-executor */
29
- await new Promise(async (res) => {
30
- for await (const chunk of stream) {
31
- const msg: ToRunner = chunk
32
- if (msg.proc) {
33
- await runner.addProcessor(msg.proc)
34
- }
35
- if (msg.start) {
36
- runner.start().then(res)
37
- }
70
+ if (state && runnerId) {
71
+ watchGrpcState(client, state, runnerId, abortCtrl)
72
+ }
38
73
 
39
- await runner.handleOrchMessage(msg)
40
- }
74
+ try {
75
+ logger.info('Connected with server ' + addr)
76
+ const writable = promisify(stream.write.bind(stream))
77
+ const runner = new Runner(
78
+ client,
79
+ writable,
80
+ uri,
81
+ logger,
82
+ configPath,
83
+ state,
84
+ runnerId,
85
+ )
41
86
 
42
- logger.error('Stream ended')
43
- })
87
+ await writable({ identify: { uri } })
88
+
89
+ let runnerDone = false
90
+ /* eslint-disable no-async-promise-executor */
91
+ await new Promise(async (res, rej) => {
92
+ try {
93
+ for await (const chunk of stream) {
94
+ const msg: ToRunner = chunk
95
+ if (msg.proc) {
96
+ await runner.addProcessor(msg.proc)
97
+ }
98
+ if (msg.start) {
99
+ if (state && runnerId) state.setStatus(runnerId, 'running')
100
+ runner.start().then(() => {
101
+ runnerDone = true
102
+ res(undefined)
103
+ })
104
+ }
105
+
106
+ await runner.handleOrchMessage(msg)
107
+ }
108
+
109
+ logger.error('Stream ended')
110
+ } catch (err) {
111
+ if (runnerDone) {
112
+ // Stream error after runner finished (e.g. connection dropped during cleanup) — safe to ignore
113
+ return
114
+ }
115
+ rej(err)
116
+ }
117
+ })
44
118
 
45
- logger.info('All processors are finished')
46
- stream.end()
47
- client.close()
48
- setTimeout(() => process.exit(0), 500)
119
+ logger.info('All processors are finished')
120
+ } finally {
121
+ abortCtrl.removeEventListener('abort', closeConnection)
122
+ closeConnection()
123
+ }
49
124
  }
package/src/index.ts CHANGED
@@ -4,5 +4,7 @@ export * from './reader'
4
4
  export * from './processor'
5
5
  export * from './runner'
6
6
  export * from './logger'
7
+ export * from './state'
7
8
 
8
9
  export * as reexports from './reexports'
10
+ export * from './server'
package/src/logger.ts CHANGED
@@ -8,6 +8,7 @@ export class RpcTransport extends Transport {
8
8
  private readonly stream: grpc.ClientWritableStream<LogMessage>
9
9
  private readonly entities: string[]
10
10
  private readonly aliases: string[]
11
+ private draining: boolean
11
12
 
12
13
  constructor(opts: {
13
14
  stream: grpc.ClientWritableStream<LogMessage>
@@ -19,23 +20,30 @@ export class RpcTransport extends Transport {
19
20
  this.stream = opts.stream
20
21
  this.entities = opts.entities
21
22
  this.aliases = opts.aliases || []
23
+ this.draining = true
24
+
25
+ this.stream.on('drain', () => {
26
+ this.draining = true
27
+ })
22
28
  }
23
29
 
24
30
  log(info: LogEntry, callback: () => void) {
25
- if (!this.stream.closed) {
26
- this.stream.write(
27
- {
31
+ if (!this.stream.closed && !this.stream.destroyed && this.stream.writable) {
32
+ if (this.draining) {
33
+ const ok = this.stream.write({
28
34
  msg: info.message,
29
35
  level: info.level,
30
36
  entities: this.entities,
31
37
  aliases: this.aliases,
32
- },
33
- callback,
34
- )
38
+ })
39
+ if (!ok) {
40
+ this.draining = false
41
+ }
42
+ }
35
43
  } else {
36
44
  console.log('Output stream closed')
37
- callback()
38
45
  }
46
+ callback()
39
47
  }
40
48
 
41
49
  withEntity(entity: string): RpcTransport {
package/src/reader.ts CHANGED
@@ -15,17 +15,18 @@ import {
15
15
  } from './convertor'
16
16
  import { Writable } from './runner'
17
17
  import { promisify } from 'util'
18
+ import { ChannelTracker } from './state'
18
19
 
19
20
  export type Any =
20
21
  | {
21
- string: string
22
- }
22
+ string: string
23
+ }
23
24
  | {
24
- stream: AsyncGenerator<Uint8Array>
25
- }
25
+ stream: AsyncGenerator<Uint8Array>
26
+ }
26
27
  | {
27
- buffer: Uint8Array
28
- }
28
+ buffer: Uint8Array
29
+ }
29
30
 
30
31
  export interface Reader {
31
32
  readonly uri: string
@@ -68,7 +69,7 @@ class MyIter<T> implements AsyncIterable<T> {
68
69
 
69
70
  async pushStream(chunks: AsyncIterable<DataChunk>, onComplete: () => void) {
70
71
  // This is an async generator that transforms DataChunks to Buffers
71
- const stream = (async function*(stream) {
72
+ const stream = (async function* (stream) {
72
73
  for await (const chunk of stream) {
73
74
  yield chunk.data
74
75
  }
@@ -106,6 +107,7 @@ export class ReaderInstance implements Reader {
106
107
  readonly uri: string
107
108
  private logger: Logger
108
109
  private readonly notifyOrchestrator: Writable
110
+ private readonly tracker: ChannelTracker | undefined
109
111
 
110
112
  private consumers: MyIter<unknown>[] = []
111
113
 
@@ -114,11 +116,13 @@ export class ReaderInstance implements Reader {
114
116
  client: RunnerClient,
115
117
  notifyOrchestrator: Writable,
116
118
  logger: Logger,
119
+ tracker?: ChannelTracker,
117
120
  ) {
118
121
  this.uri = uri
119
122
  this.client = client
120
123
  this.logger = logger
121
124
  this.notifyOrchestrator = notifyOrchestrator
125
+ this.tracker = tracker
122
126
  }
123
127
 
124
128
  anys(): AsyncIterable<Any> {
@@ -147,6 +151,7 @@ export class ReaderInstance implements Reader {
147
151
 
148
152
  handleMsg(msg: ReceivingMessage) {
149
153
  this.logger.debug(`${this.uri} handling message`)
154
+ this.tracker?.recordMessage(msg.data.length)
150
155
 
151
156
  const promises = []
152
157
  for (const iter of this.consumers) {
@@ -163,9 +168,13 @@ export class ReaderInstance implements Reader {
163
168
  )
164
169
  }
165
170
 
171
+ private hasClosed = false
172
+
166
173
  close() {
174
+ if (this.hasClosed) return
175
+ this.hasClosed = true
167
176
  for (const iter of this.consumers) {
168
- iter.close(() => { })
177
+ iter.close(() => {})
169
178
  }
170
179
  }
171
180
 
@@ -175,6 +184,7 @@ export class ReaderInstance implements Reader {
175
184
  globalSequenceNumber,
176
185
  }: ReceivingStreamMessage) {
177
186
  this.logger.debug(`${this.uri} handling streaming message`)
187
+ this.tracker?.recordMessage(0)
178
188
 
179
189
  const chunks = this.client.receiveStreamMessage()
180
190
  const writeControlMessage = promisify(chunks.write.bind(chunks))
@@ -201,7 +211,7 @@ export class ReaderInstance implements Reader {
201
211
  await writeControlMessage({ globalSequenceNumber })
202
212
 
203
213
  Promise.all(consumersConsumed).then(() => {
204
- console.log('Writing processed for streaming message')
214
+ chunks.end()
205
215
  this.notifyOrchestrator({ processed: { globalSequenceNumber, channel } })
206
216
  })
207
217
  }