@rdfc/js-runner 0.2.2 → 0.3.0-alpha.1

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Js-runner
2
2
 
3
- [![Bun CI](https://github.com/rdf-connect/js-runner/actions/workflows/build-test.yml/badge.svg)](https://github.com/rdf-connect/js-runner/actions/workflows/build-test.yml) [![npm](https://img.shields.io/npm/v/@rdfc/js-runner.svg?style=popout)](https://npmjs.com/package/@rdfc/js-runner)
3
+ [![Build and tests with Node.js](https://github.com/rdf-connect/js-runner/actions/workflows/build-test.yml/badge.svg)](https://github.com/rdf-connect/js-runner/actions/workflows/build-test.yml) [![npm](https://img.shields.io/npm/v/@rdfc/js-runner.svg?style=popout)](https://npmjs.com/package/@rdfc/js-runner)
4
4
 
5
5
  Typescript/Javascript executor for an [RDF-Connect](https://rdf-connect.github.io/rdfc.github.io/) pipeline. Starting from a declarative RDF file describing the pipeline.
6
6
 
@@ -34,7 +34,7 @@ You can execute this pipeline with
34
34
 
35
35
  ```bash
36
36
  tsc
37
- bun bin/js-runner.js input.ttl
37
+ npx bin/js-runner.js input.ttl
38
38
  ```
39
39
 
40
- This example input configuration file uses `owl:imports` to specify additional configuration files.
40
+ This example input configuration file uses `owl:imports` to specify additional configuration files.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { jsRunner } from "../dist/index.js";
3
+
4
+ jsRunner().catch((e) => { console.error("Error:", e); console.error(e.stack) });
package/dist/args.js CHANGED
@@ -1,25 +1,37 @@
1
1
  import commandLineArgs from "command-line-args";
2
2
  import commandLineUsage from "command-line-usage";
3
3
  const optionDefinitions = [
4
- { name: 'input', type: String, defaultOption: true, summary: "Specify what input file to start up" },
5
- { name: 'help', alias: 'h', type: Boolean, description: "Display this help message" },
4
+ {
5
+ name: "input",
6
+ type: String,
7
+ defaultOption: true,
8
+ summary: "Specify what input file to start up",
9
+ },
10
+ {
11
+ name: "help",
12
+ alias: "h",
13
+ type: Boolean,
14
+ description: "Display this help message",
15
+ },
6
16
  ];
7
17
  const sections = [
8
18
  {
9
19
  header: "Js-runner",
10
- content: "JS-runner is part of the {italic connector architecture}. Starting from an input file start up all JsProcessors that are defined. Please do not use blank nodes, skolemize your data somewhere else!"
20
+ content: "JS-runner is part of the {italic connector architecture}. Starting from an input file start up all JsProcessors that are defined. Please do not use blank nodes, skolemize your data somewhere else!",
11
21
  },
12
22
  {
13
23
  header: "Synopsis",
14
- content: "$ js-runner <input>"
24
+ content: "$ js-runner <input>",
15
25
  },
16
26
  {
17
27
  header: "Command List",
18
- content: [{ name: "input", summary: "Specify what input file to start up" }],
28
+ content: [
29
+ { name: "input", summary: "Specify what input file to start up" },
30
+ ],
19
31
  },
20
32
  {
21
- optionList: [optionDefinitions[1]]
22
- }
33
+ optionList: [optionDefinitions[1]],
34
+ },
23
35
  ];
24
36
  function validArgs(args) {
25
37
  if (!args.input)
@@ -71,12 +71,13 @@ export const startFileStreamWriter = (config) => {
71
71
  ? config.path
72
72
  : `${process.cwd()}/${config.path}`;
73
73
  const encoding = config.encoding || "utf-8";
74
+ const writer = new SimpleStream();
74
75
  const init = async () => {
75
76
  if (!config.onReplace) {
76
77
  await writeFile(path, "", { encoding });
77
78
  }
78
79
  };
79
- const push = async (item) => {
80
+ writer.push = async (item) => {
80
81
  if (config.onReplace) {
81
82
  await writeFile(path, item, { encoding });
82
83
  }
@@ -84,6 +85,5 @@ export const startFileStreamWriter = (config) => {
84
85
  await appendFile(path, item, { encoding });
85
86
  }
86
87
  };
87
- const end = async () => { };
88
- return { writer: { push, end }, init };
88
+ return { writer, init };
89
89
  };
@@ -14,7 +14,7 @@ function streamToString(stream, binary) {
14
14
  });
15
15
  }
16
16
  export const startHttpStreamReader = (config) => {
17
- let server;
17
+ let server = undefined;
18
18
  const stream = new SimpleStream(() => new Promise((res) => {
19
19
  if (server !== undefined) {
20
20
  server.close(() => {
@@ -57,8 +57,9 @@ export const startHttpStreamReader = (config) => {
57
57
  };
58
58
  export const startHttpStreamWriter = (config) => {
59
59
  const requestConfig = new URL(config.endpoint);
60
- const push = async (item) => {
61
- await new Promise(async (resolve) => {
60
+ const writer = new SimpleStream();
61
+ writer.push = async (item) => {
62
+ await new Promise((resolve) => {
62
63
  const options = {
63
64
  hostname: requestConfig.hostname,
64
65
  path: requestConfig.path,
@@ -72,10 +73,10 @@ export const startHttpStreamWriter = (config) => {
72
73
  });
73
74
  };
74
75
  const req = http.request(options, cb);
75
- await new Promise((res) => req.write(item, res));
76
- await new Promise((res) => req.end(res));
76
+ req.write(item, () => {
77
+ req.end();
78
+ });
77
79
  });
78
80
  };
79
- const end = async () => { };
80
- return { writer: { push, end }, init: async () => { } };
81
+ return { writer, init: async () => { } };
81
82
  };
@@ -10,7 +10,7 @@ export const startKafkaStreamReader = (config) => {
10
10
  Object.assign(brokerConfig, config.broker);
11
11
  }
12
12
  if (brokerConfig && brokerConfig.hosts) {
13
- brokerConfig.brokers = brokerConfig.hosts;
13
+ brokerConfig.brokers = (brokerConfig).hosts;
14
14
  }
15
15
  const kafka = new Kafka(brokerConfig);
16
16
  const consumer = kafka.consumer(config.consumer);
@@ -29,9 +29,7 @@ export const startKafkaStreamReader = (config) => {
29
29
  async eachMessage({ topic, message, }) {
30
30
  if (topic === config.topic.name) {
31
31
  const element = message.value?.toString() ?? "";
32
- stream.push(element).catch((error) => {
33
- throw error;
34
- });
32
+ await stream.push(element);
35
33
  }
36
34
  },
37
35
  })
@@ -51,16 +49,16 @@ export const startKafkaStreamWriter = (config) => {
51
49
  Object.assign(brokerConfig, config.broker);
52
50
  }
53
51
  if (brokerConfig && brokerConfig.hosts) {
54
- brokerConfig.brokers = brokerConfig.hosts;
52
+ brokerConfig.brokers = (brokerConfig).hosts;
55
53
  }
56
54
  const kafka = new Kafka(brokerConfig);
57
55
  const producer = kafka.producer(config.producer);
56
+ const writer = new SimpleStream(async () => {
57
+ await producer.disconnect();
58
+ });
58
59
  const init = () => producer.connect();
59
- const push = async (item) => {
60
+ writer.push = async (item) => {
60
61
  await producer.send({ topic, messages: [{ value: item }] });
61
62
  };
62
- const end = async () => {
63
- await producer.disconnect();
64
- };
65
- return { writer: { push, end }, init };
63
+ return { writer, init };
66
64
  };
@@ -59,11 +59,11 @@ export const startWsStreamWriter = (config) => {
59
59
  ws = await connectWs(config.url);
60
60
  ws.on("open", () => console.log("open"));
61
61
  };
62
- const push = async (item) => {
63
- ws.send(item);
64
- };
65
- const end = async () => {
62
+ const writer = new SimpleStream(async () => {
66
63
  ws.close();
64
+ });
65
+ writer.push = async (item) => {
66
+ ws.send(item);
67
67
  };
68
- return { writer: { push, end }, init };
68
+ return { writer, init };
69
69
  };
@@ -29,6 +29,7 @@ export declare class ChannelFactory {
29
29
  export interface Writer<T> {
30
30
  push(item: T): Promise<void>;
31
31
  end(): Promise<void>;
32
+ on(event: "end", listener: Handler<void>): this;
32
33
  }
33
34
  export interface Stream<T> {
34
35
  lastElement?: T;
@@ -43,6 +44,7 @@ export declare class SimpleStream<T> implements Stream<T> {
43
44
  private readonly endHandlers;
44
45
  readonly disconnect: () => Promise<void>;
45
46
  lastElement?: T | undefined;
47
+ private ended;
46
48
  constructor(onDisconnect?: () => Promise<void>);
47
49
  data(listener: Handler<T>): this;
48
50
  push(data: T): Promise<void>;
@@ -42,13 +42,15 @@ export class ChannelFactory {
42
42
  const id = c.channel.id.value;
43
43
  if (c.channel.id.termType === "NamedNode") {
44
44
  if (!this.jsChannelsNamedNodes[id]) {
45
- this.jsChannelsNamedNodes[id] = new SimpleStream();
45
+ this.jsChannelsNamedNodes[id] =
46
+ new SimpleStream();
46
47
  }
47
48
  return this.jsChannelsNamedNodes[id];
48
49
  }
49
50
  if (c.channel.id.termType === "BlankNode") {
50
51
  if (!this.jsChannelsBlankNodes[id]) {
51
- this.jsChannelsBlankNodes[id] = new SimpleStream();
52
+ this.jsChannelsBlankNodes[id] =
53
+ new SimpleStream();
52
54
  }
53
55
  return this.jsChannelsBlankNodes[id];
54
56
  }
@@ -85,13 +87,15 @@ export class ChannelFactory {
85
87
  const id = c.channel.id.value;
86
88
  if (c.channel.id.termType === "NamedNode") {
87
89
  if (!this.jsChannelsNamedNodes[id]) {
88
- this.jsChannelsNamedNodes[id] = new SimpleStream();
90
+ this.jsChannelsNamedNodes[id] =
91
+ new SimpleStream();
89
92
  }
90
93
  return this.jsChannelsNamedNodes[id];
91
94
  }
92
95
  if (c.channel.id.termType === "BlankNode") {
93
96
  if (!this.jsChannelsBlankNodes[id]) {
94
- this.jsChannelsBlankNodes[id] = new SimpleStream();
97
+ this.jsChannelsBlankNodes[id] =
98
+ new SimpleStream();
95
99
  }
96
100
  return this.jsChannelsBlankNodes[id];
97
101
  }
@@ -109,6 +113,7 @@ export class SimpleStream {
109
113
  endHandlers = [];
110
114
  disconnect;
111
115
  lastElement;
116
+ ended = false;
112
117
  constructor(onDisconnect) {
113
118
  this.disconnect = onDisconnect || (async () => { });
114
119
  }
@@ -117,12 +122,16 @@ export class SimpleStream {
117
122
  return this;
118
123
  }
119
124
  async push(data) {
125
+ if (this.ended) {
126
+ throw new Error("Trying to push to a stream that has ended!");
127
+ }
120
128
  this.lastElement = data;
121
129
  await Promise.all(this.dataHandlers.map((handler) => handler(data)));
122
130
  }
123
131
  async end() {
124
132
  await this.disconnect();
125
133
  await Promise.all(this.endHandlers.map((handler) => handler()));
134
+ this.ended = true;
126
135
  }
127
136
  on(event, listener) {
128
137
  if (event === "data") {
package/dist/index.cjs CHANGED
@@ -8,8 +8,8 @@ var http = require('http');
8
8
  var https = require('https');
9
9
  var types = require('@treecg/types');
10
10
  var debug = require('debug');
11
- var promises = require('fs/promises');
12
11
  var path = require('path');
12
+ var promises = require('fs/promises');
13
13
  var node_fs = require('node:fs');
14
14
  var ws = require('ws');
15
15
  var kafkajs = require('kafkajs');
@@ -35,25 +35,37 @@ function _interopNamespaceDefault(e) {
35
35
  var http__namespace = /*#__PURE__*/_interopNamespaceDefault(http);
36
36
 
37
37
  const optionDefinitions = [
38
- { name: 'input', type: String, defaultOption: true, summary: "Specify what input file to start up" },
39
- { name: 'help', alias: 'h', type: Boolean, description: "Display this help message" },
38
+ {
39
+ name: "input",
40
+ type: String,
41
+ defaultOption: true,
42
+ summary: "Specify what input file to start up",
43
+ },
44
+ {
45
+ name: "help",
46
+ alias: "h",
47
+ type: Boolean,
48
+ description: "Display this help message",
49
+ },
40
50
  ];
41
51
  const sections = [
42
52
  {
43
53
  header: "Js-runner",
44
- content: "JS-runner is part of the {italic connector architecture}. Starting from an input file start up all JsProcessors that are defined. Please do not use blank nodes, skolemize your data somewhere else!"
54
+ content: "JS-runner is part of the {italic connector architecture}. Starting from an input file start up all JsProcessors that are defined. Please do not use blank nodes, skolemize your data somewhere else!",
45
55
  },
46
56
  {
47
57
  header: "Synopsis",
48
- content: "$ js-runner <input>"
58
+ content: "$ js-runner <input>",
49
59
  },
50
60
  {
51
61
  header: "Command List",
52
- content: [{ name: "input", summary: "Specify what input file to start up" }],
62
+ content: [
63
+ { name: "input", summary: "Specify what input file to start up" },
64
+ ],
53
65
  },
54
66
  {
55
- optionList: [optionDefinitions[1]]
56
- }
67
+ optionList: [optionDefinitions[1]],
68
+ },
57
69
  ];
58
70
  function validArgs(args) {
59
71
  if (!args.input)
@@ -144,7 +156,7 @@ async function load_store(location, store, recursive = true) {
144
156
  if (recursive) {
145
157
  const loc = location.type === "remote" ? location.location : location.baseIRI;
146
158
  const other_imports = store.getObjects(namedNode(loc), OWL.terms.imports, null);
147
- for (let other of other_imports) {
159
+ for (const other of other_imports) {
148
160
  await load_store({ location: other.value, type: "remote" }, store, true);
149
161
  }
150
162
  }
@@ -218,12 +230,13 @@ const startFileStreamWriter = (config) => {
218
230
  ? config.path
219
231
  : `${process.cwd()}/${config.path}`;
220
232
  const encoding = config.encoding || "utf-8";
233
+ const writer = new SimpleStream();
221
234
  const init = async () => {
222
235
  if (!config.onReplace) {
223
236
  await promises.writeFile(path$1, "", { encoding });
224
237
  }
225
238
  };
226
- const push = async (item) => {
239
+ writer.push = async (item) => {
227
240
  if (config.onReplace) {
228
241
  await promises.writeFile(path$1, item, { encoding });
229
242
  }
@@ -231,8 +244,7 @@ const startFileStreamWriter = (config) => {
231
244
  await promises.appendFile(path$1, item, { encoding });
232
245
  }
233
246
  };
234
- const end = async () => { };
235
- return { writer: { push, end }, init };
247
+ return { writer, init };
236
248
  };
237
249
 
238
250
  function _connectWs(url, res) {
@@ -293,13 +305,13 @@ const startWsStreamWriter = (config) => {
293
305
  ws = await connectWs(config.url);
294
306
  ws.on("open", () => console.log("open"));
295
307
  };
296
- const push = async (item) => {
297
- ws.send(item);
298
- };
299
- const end = async () => {
308
+ const writer = new SimpleStream(async () => {
300
309
  ws.close();
310
+ });
311
+ writer.push = async (item) => {
312
+ ws.send(item);
301
313
  };
302
- return { writer: { push, end }, init };
314
+ return { writer, init };
303
315
  };
304
316
 
305
317
  const startKafkaStreamReader = (config) => {
@@ -311,7 +323,7 @@ const startKafkaStreamReader = (config) => {
311
323
  Object.assign(brokerConfig, config.broker);
312
324
  }
313
325
  if (brokerConfig && brokerConfig.hosts) {
314
- brokerConfig.brokers = brokerConfig.hosts;
326
+ brokerConfig.brokers = (brokerConfig).hosts;
315
327
  }
316
328
  const kafka = new kafkajs.Kafka(brokerConfig);
317
329
  const consumer = kafka.consumer(config.consumer);
@@ -352,18 +364,18 @@ const startKafkaStreamWriter = (config) => {
352
364
  Object.assign(brokerConfig, config.broker);
353
365
  }
354
366
  if (brokerConfig && brokerConfig.hosts) {
355
- brokerConfig.brokers = brokerConfig.hosts;
367
+ brokerConfig.brokers = (brokerConfig).hosts;
356
368
  }
357
369
  const kafka = new kafkajs.Kafka(brokerConfig);
358
370
  const producer = kafka.producer(config.producer);
371
+ const writer = new SimpleStream(async () => {
372
+ await producer.disconnect();
373
+ });
359
374
  const init = () => producer.connect();
360
- const push = async (item) => {
375
+ writer.push = async (item) => {
361
376
  await producer.send({ topic, messages: [{ value: item }] });
362
377
  };
363
- const end = async () => {
364
- await producer.disconnect();
365
- };
366
- return { writer: { push, end }, init };
378
+ return { writer, init };
367
379
  };
368
380
 
369
381
  function streamToString(stream, binary) {
@@ -379,7 +391,7 @@ function streamToString(stream, binary) {
379
391
  });
380
392
  }
381
393
  const startHttpStreamReader = (config) => {
382
- let server;
394
+ let server = undefined;
383
395
  const stream = new SimpleStream(() => new Promise((res) => {
384
396
  if (server !== undefined) {
385
397
  server.close(() => {
@@ -422,8 +434,9 @@ const startHttpStreamReader = (config) => {
422
434
  };
423
435
  const startHttpStreamWriter = (config) => {
424
436
  const requestConfig = new URL(config.endpoint);
425
- const push = async (item) => {
426
- await new Promise(async (resolve) => {
437
+ const writer = new SimpleStream();
438
+ writer.push = async (item) => {
439
+ await new Promise((resolve) => {
427
440
  const options = {
428
441
  hostname: requestConfig.hostname,
429
442
  path: requestConfig.path,
@@ -437,12 +450,12 @@ const startHttpStreamWriter = (config) => {
437
450
  });
438
451
  };
439
452
  const req = http__namespace.request(options, cb);
440
- await new Promise((res) => req.write(item, res));
441
- await new Promise((res) => req.end(res));
453
+ req.write(item, () => {
454
+ req.end();
455
+ });
442
456
  });
443
457
  };
444
- const end = async () => { };
445
- return { writer: { push, end }, init: async () => { } };
458
+ return { writer, init: async () => { } };
446
459
  };
447
460
 
448
461
  const Conn = types.createTermNamespace("https://w3id.org/conn#", "FileReaderChannel", "FileWriterChannel", "HttpReaderChannel", "HttpWriterChannel", "KafkaReaderChannel", "KafkaWriterChannel", "WsReaderChannel", "WsWriterChannel", "WriterChannel", "ReaderChannel");
@@ -479,13 +492,15 @@ class ChannelFactory {
479
492
  const id = c.channel.id.value;
480
493
  if (c.channel.id.termType === "NamedNode") {
481
494
  if (!this.jsChannelsNamedNodes[id]) {
482
- this.jsChannelsNamedNodes[id] = new SimpleStream();
495
+ this.jsChannelsNamedNodes[id] =
496
+ new SimpleStream();
483
497
  }
484
498
  return this.jsChannelsNamedNodes[id];
485
499
  }
486
500
  if (c.channel.id.termType === "BlankNode") {
487
501
  if (!this.jsChannelsBlankNodes[id]) {
488
- this.jsChannelsBlankNodes[id] = new SimpleStream();
502
+ this.jsChannelsBlankNodes[id] =
503
+ new SimpleStream();
489
504
  }
490
505
  return this.jsChannelsBlankNodes[id];
491
506
  }
@@ -522,13 +537,15 @@ class ChannelFactory {
522
537
  const id = c.channel.id.value;
523
538
  if (c.channel.id.termType === "NamedNode") {
524
539
  if (!this.jsChannelsNamedNodes[id]) {
525
- this.jsChannelsNamedNodes[id] = new SimpleStream();
540
+ this.jsChannelsNamedNodes[id] =
541
+ new SimpleStream();
526
542
  }
527
543
  return this.jsChannelsNamedNodes[id];
528
544
  }
529
545
  if (c.channel.id.termType === "BlankNode") {
530
546
  if (!this.jsChannelsBlankNodes[id]) {
531
- this.jsChannelsBlankNodes[id] = new SimpleStream();
547
+ this.jsChannelsBlankNodes[id] =
548
+ new SimpleStream();
532
549
  }
533
550
  return this.jsChannelsBlankNodes[id];
534
551
  }
@@ -546,6 +563,7 @@ class SimpleStream {
546
563
  endHandlers = [];
547
564
  disconnect;
548
565
  lastElement;
566
+ ended = false;
549
567
  constructor(onDisconnect) {
550
568
  this.disconnect = onDisconnect || (async () => { });
551
569
  }
@@ -554,12 +572,16 @@ class SimpleStream {
554
572
  return this;
555
573
  }
556
574
  async push(data) {
575
+ if (this.ended) {
576
+ throw new Error("Trying to push to a stream that has ended!");
577
+ }
557
578
  this.lastElement = data;
558
579
  await Promise.all(this.dataHandlers.map((handler) => handler(data)));
559
580
  }
560
581
  async end() {
561
582
  await this.disconnect();
562
583
  await Promise.all(this.endHandlers.map((handler) => handler()));
584
+ this.ended = true;
563
585
  }
564
586
  on(event, listener) {
565
587
  if (event === "data") {
@@ -598,10 +620,10 @@ function extractSteps(proc, quads, config) {
598
620
  .map((x) => x.subject);
599
621
  const processorLens = config.lenses[proc.ty.value];
600
622
  const fields = proc.mapping.parameters;
601
- for (let id of subjects) {
623
+ for (const id of subjects) {
602
624
  const obj = processorLens.execute({ id, quads });
603
625
  const functionArgs = new Array(fields.length);
604
- for (let field of fields) {
626
+ for (const field of fields) {
605
627
  functionArgs[field.position] = obj[field.parameter];
606
628
  }
607
629
  out.push(functionArgs);
@@ -622,16 +644,16 @@ async function jsRunner() {
622
644
  const { processors, quads, shapes: config, } = await extractProcessors(source, apply);
623
645
  LOG.main("Found %d processors", processors.length);
624
646
  const starts = [];
625
- for (let proc of processors) {
647
+ for (const proc of processors) {
626
648
  const argss = extractSteps(proc, quads, config);
627
649
  const jsProgram = await import("file://" + proc.file);
628
650
  process.chdir(proc.location);
629
- for (let args of argss) {
651
+ for (const args of argss) {
630
652
  starts.push(await jsProgram[proc.func](...args));
631
653
  }
632
654
  }
633
655
  await factory.init();
634
- for (let s of starts) {
656
+ for (const s of starts) {
635
657
  if (s && typeof s === "function") {
636
658
  s();
637
659
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export * from "./connectors.js";
2
1
  import { Quad, Term } from "@rdfjs/types";
3
2
  import { Shapes } from "rdf-lens";
3
+ export * from "./connectors.js";
4
4
  type Processor = {
5
5
  ty: Term;
6
6
  file: string;
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Store } from "n3";
2
2
  import { getArgs } from "./args.js";
3
3
  import { load_store, LOG } from "./util.js";
4
- export * from "./connectors.js";
5
4
  import path from "path";
6
5
  import { RDF } from "@treecg/types";
7
6
  import { ChannelFactory, Conn, JsOntology } from "./connectors.js";
8
- import { extractShapes } from "rdf-lens";
7
+ import { envReplace, extractShapes } from "rdf-lens";
8
+ export * from "./connectors.js";
9
9
  function safeJoin(a, b) {
10
10
  if (b.startsWith("/")) {
11
11
  return b;
@@ -23,7 +23,8 @@ export async function extractProcessors(source, apply) {
23
23
  .map((x) => x.subject);
24
24
  const processorLens = config.lenses[JsOntology.JsProcess.value];
25
25
  const processors = subjects.map((id) => processorLens.execute({ id, quads }));
26
- return { processors, quads, shapes: config };
26
+ const newQuads = envReplace().execute(quads);
27
+ return { processors, quads: newQuads, shapes: config };
27
28
  }
28
29
  export function extractSteps(proc, quads, config) {
29
30
  const out = [];
@@ -32,10 +33,10 @@ export function extractSteps(proc, quads, config) {
32
33
  .map((x) => x.subject);
33
34
  const processorLens = config.lenses[proc.ty.value];
34
35
  const fields = proc.mapping.parameters;
35
- for (let id of subjects) {
36
+ for (const id of subjects) {
36
37
  const obj = processorLens.execute({ id, quads });
37
38
  const functionArgs = new Array(fields.length);
38
- for (let field of fields) {
39
+ for (const field of fields) {
39
40
  functionArgs[field.position] = obj[field.parameter];
40
41
  }
41
42
  out.push(functionArgs);
@@ -56,16 +57,16 @@ export async function jsRunner() {
56
57
  const { processors, quads, shapes: config, } = await extractProcessors(source, apply);
57
58
  LOG.main("Found %d processors", processors.length);
58
59
  const starts = [];
59
- for (let proc of processors) {
60
+ for (const proc of processors) {
60
61
  const argss = extractSteps(proc, quads, config);
61
62
  const jsProgram = await import("file://" + proc.file);
62
63
  process.chdir(proc.location);
63
- for (let args of argss) {
64
+ for (const args of argss) {
64
65
  starts.push(await jsProgram[proc.func](...args));
65
66
  }
66
67
  }
67
68
  await factory.init();
68
- for (let s of starts) {
69
+ for (const s of starts) {
69
70
  if (s && typeof s === "function") {
70
71
  s();
71
72
  }