@rdfc/js-runner 2.0.0-alpha.6 → 2.0.0-alpha.8

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 (43) hide show
  1. package/.editorconfig +9 -0
  2. package/__tests__/channels.test.js +117 -0
  3. package/examples/echo/.idea/echo.iml +9 -0
  4. package/examples/echo/.idea/misc.xml +6 -0
  5. package/examples/echo/.idea/modules.xml +8 -0
  6. package/examples/echo/.idea/vcs.xml +7 -0
  7. package/examples/echo/.swls/config.json +1 -0
  8. package/examples/echo/index.ttl +3 -0
  9. package/examples/echo/minimal.ttl +90 -0
  10. package/examples/echo/pipeline.ttl +22 -4
  11. package/examples/echo/processors.ttl +5 -7
  12. package/examples/echo/shacl.ttl +9 -0
  13. package/examples/echo/shape.ttl +1339 -0
  14. package/examples/echo/src/processors.js +123 -0
  15. package/examples/echo/src/processors.ts +3 -4
  16. package/examples/echo/test.ttl +9 -12
  17. package/file:/home/silvius/Projects/mumo-pipeline/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
  18. package/index.ttl +28 -20
  19. package/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
  20. package/lib/client.js +1 -1
  21. package/lib/index.d.ts +1 -1
  22. package/lib/index.js +2 -2
  23. package/lib/jsonld.js +4 -3
  24. package/lib/reader.d.ts +2 -1
  25. package/lib/reader.js +8 -16
  26. package/lib/reexports.d.ts +2 -2
  27. package/lib/reexports.js +3 -3
  28. package/lib/runner.js +29 -20
  29. package/lib/testUtils.js +6 -4
  30. package/lib/tsconfig.tsbuildinfo +1 -1
  31. package/lib/writer.d.ts +2 -1
  32. package/lib/writer.js +1 -1
  33. package/minimal.ttl +99 -0
  34. package/package.json +1 -1
  35. package/src/client.ts +16 -14
  36. package/src/index.ts +1 -1
  37. package/src/jsonld.ts +5 -2
  38. package/src/reader.ts +17 -20
  39. package/src/reexports.ts +5 -2
  40. package/src/runner.ts +50 -32
  41. package/src/testUtils.ts +34 -25
  42. package/src/writer.ts +2 -1
  43. package/vite.config.js +11 -0
package/src/client.ts CHANGED
@@ -8,11 +8,13 @@ import { Runner } from './runner'
8
8
  export async function start(addr: string, uri: string) {
9
9
  const client = new RunnerClient(addr, grpc.credentials.createInsecure())
10
10
 
11
+
12
+
11
13
  const logger = winston.createLogger({
12
14
  transports: [
13
15
  new RpcTransport({
14
16
  entities: [uri, 'cli'],
15
- stream: client.logStream(() => {}),
17
+ stream: client.logStream(() => { }),
16
18
  }),
17
19
  ],
18
20
  })
@@ -27,21 +29,21 @@ export async function start(addr: string, uri: string) {
27
29
 
28
30
  let processorsEnd!: (v: unknown) => unknown
29
31
  const processorsEnded = new Promise((res) => (processorsEnd = res))
30
- ;(async () => {
31
- for await (const chunk of stream) {
32
- const msg: RunnerMessage = chunk
33
- if (msg.proc) {
34
- await runner.addProcessor(msg.proc)
32
+ ; (async () => {
33
+ for await (const chunk of stream) {
34
+ const msg: RunnerMessage = chunk
35
+ if (msg.proc) {
36
+ await runner.addProcessor(msg.proc)
37
+ }
38
+ if (msg.start) {
39
+ runner.start().then(processorsEnd)
40
+ }
41
+
42
+ await runner.handleOrchMessage(msg)
35
43
  }
36
- if (msg.start) {
37
- runner.start().then(processorsEnd)
38
- }
39
-
40
- await runner.handleOrchMessage(msg)
41
- }
42
44
 
43
- logger.error('Stream ended')
44
- })()
45
+ logger.error('Stream ended')
46
+ })()
45
47
 
46
48
  await processorsEnded
47
49
 
package/src/index.ts CHANGED
@@ -4,4 +4,4 @@ export * from './reader'
4
4
  export * from './processor'
5
5
  export * from './runner'
6
6
 
7
- export * as reexports from "./reexports";
7
+ export * as reexports from './reexports'
package/src/jsonld.ts CHANGED
@@ -30,7 +30,7 @@ const RDFL = createUriAndTermNamespace(
30
30
 
31
31
  type Writable = (msg: OrchestratorMessage) => Promise<unknown>
32
32
  const RDFC = createNamespace(
33
- 'https://w3id.org/rdf-connect/ontology#',
33
+ 'https://w3id.org/rdf-connect#',
34
34
  (x) => x,
35
35
  'Reader',
36
36
  'Writer',
@@ -189,7 +189,10 @@ function expandArgs(args: Arg, cont: Cont, logger: Logger) {
189
189
  let x = 'object'
190
190
  try {
191
191
  x = JSON.stringify(v)
192
- } catch (e) {}
192
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
193
+ } catch (_e: unknown) {
194
+ // default is set
195
+ }
193
196
 
194
197
  return k + ': ' + x
195
198
  }),
package/src/reader.ts CHANGED
@@ -11,16 +11,17 @@ import {
11
11
 
12
12
  export type Any =
13
13
  | {
14
- string: string
15
- }
14
+ string: string
15
+ }
16
16
  | {
17
- stream: AsyncGenerator<Uint8Array>
18
- }
17
+ stream: AsyncGenerator<Uint8Array>
18
+ }
19
19
  | {
20
- buffer: Uint8Array
21
- }
20
+ buffer: Uint8Array
21
+ }
22
22
 
23
23
  export interface Reader {
24
+ readonly uri: string
24
25
  strings(): AsyncIterable<string>
25
26
  streams(): AsyncIterable<AsyncGenerator<Uint8Array>>
26
27
  buffers(): AsyncIterable<Uint8Array>
@@ -30,7 +31,7 @@ export interface Reader {
30
31
  class MyIter<T> implements AsyncIterable<T> {
31
32
  private convertor: Convertor<T>
32
33
  private queue: (T | undefined)[] = []
33
- private resolveNext: ((value: T | undefined) => void) | null = null
34
+ private resolveNext: ((value: undefined) => void) | null = null
34
35
 
35
36
  constructor(convertor: Convertor<T>) {
36
37
  this.convertor = convertor
@@ -38,36 +39,33 @@ class MyIter<T> implements AsyncIterable<T> {
38
39
 
39
40
  push(buffer: Uint8Array) {
40
41
  const item = this.convertor.from(buffer)
42
+ this.queue.push(item)
41
43
  if (this.resolveNext) {
42
- this.resolveNext(item)
44
+ this.resolveNext(undefined)
43
45
  this.resolveNext = null
44
- } else {
45
- this.queue.push(item)
46
46
  }
47
47
  }
48
48
 
49
49
  close() {
50
+ this.queue.push(undefined)
50
51
  if (this.resolveNext) {
51
52
  this.resolveNext(undefined)
52
53
  this.resolveNext = null
53
- } else {
54
- this.queue.push(undefined)
55
54
  }
56
55
  }
57
56
 
58
57
  async pushStream(chunks: ClientReadableStream<DataChunk>) {
59
- const stream = (async function* (stream) {
58
+ const stream = (async function*(stream) {
60
59
  for await (const c of stream) {
61
60
  const chunk: DataChunk = c
62
61
  yield chunk.data
63
62
  }
64
63
  })(chunks)
65
64
  const item = await this.convertor.fromStream(stream)
65
+ this.queue.push(item)
66
66
  if (this.resolveNext) {
67
- this.resolveNext(item)
67
+ this.resolveNext(undefined)
68
68
  this.resolveNext = null
69
- } else {
70
- this.queue.push(item)
71
69
  }
72
70
  }
73
71
 
@@ -78,11 +76,9 @@ class MyIter<T> implements AsyncIterable<T> {
78
76
  if (item === undefined) break
79
77
  yield item
80
78
  } else {
81
- const item = await new Promise<T | undefined>(
79
+ await new Promise<undefined>(
82
80
  (resolve) => (this.resolveNext = resolve),
83
81
  )
84
- if (item === undefined) break
85
- yield item
86
82
  }
87
83
  }
88
84
  }
@@ -90,7 +86,7 @@ class MyIter<T> implements AsyncIterable<T> {
90
86
 
91
87
  export class ReaderInstance implements Reader {
92
88
  private client: RunnerClient
93
- private uri: string
89
+ readonly uri: string
94
90
  private logger: winston.Logger
95
91
 
96
92
  private iterators: MyIter<unknown>[] = []
@@ -127,6 +123,7 @@ export class ReaderInstance implements Reader {
127
123
 
128
124
  handleMsg(msg: Message) {
129
125
  this.logger.debug(`${this.uri} handling message`)
126
+ console.log(`${this.uri} handling message`)
130
127
  for (const iter of this.iterators) {
131
128
  iter.push(msg.data)
132
129
  }
package/src/reexports.ts CHANGED
@@ -1,3 +1,6 @@
1
- export * from "@rdfc/proto";
2
- export { ClientReadableStreamImpl, ClientReadableStream } from '@grpc/grpc-js/build/src/call.js'
1
+ export * from '@rdfc/proto'
2
+ export {
3
+ ClientReadableStreamImpl,
4
+ ClientReadableStream,
5
+ } from '@grpc/grpc-js/build/src/call.js'
3
6
  export * as grpc from '@grpc/grpc-js'
package/src/runner.ts CHANGED
@@ -11,7 +11,6 @@ import { Logger } from 'winston'
11
11
 
12
12
  import winston from 'winston'
13
13
  import { RpcTransport } from './logger'
14
- import { parse_jsonld } from './jsonld'
15
14
  import { Cont, empty, extractShapes, Shapes } from 'rdf-lens'
16
15
  import { NamedNode, Parser } from 'n3'
17
16
  import { createNamespace, createUriAndTermNamespace, RDF } from '@treecg/types'
@@ -31,7 +30,7 @@ const RDFL = createUriAndTermNamespace(
31
30
  )
32
31
 
33
32
  const RDFC = createNamespace(
34
- 'https://w3id.org/rdf-connect/ontology#',
33
+ 'https://w3id.org/rdf-connect#',
35
34
  (x) => x,
36
35
  'Reader',
37
36
  'Writer',
@@ -45,7 +44,8 @@ type ProcessorConfig = {
45
44
  clazz?: string
46
45
  }
47
46
 
48
- export type FullProc<C extends Proc<unknown>> = C extends Proc<infer T> ? T & C : unknown;
47
+ export type FullProc<C extends Proc<unknown>> =
48
+ C extends Proc<infer T> ? T & C : unknown
49
49
  export class Runner {
50
50
  private readonly readers: { [uri: string]: ReaderInstance[] } = {}
51
51
  private readonly writers: { [uri: string]: WriterInstance[] } = {}
@@ -72,7 +72,9 @@ export class Runner {
72
72
  this.logger = logger
73
73
  }
74
74
 
75
- async addProcessor<P extends Proc<unknown>>(proc: Processor): Promise<FullProc<P>> {
75
+ async addProcessor<P extends Proc<unknown>>(
76
+ proc: Processor,
77
+ ): Promise<FullProc<P>> {
76
78
  const procLogger = winston.createLogger({
77
79
  transports: [
78
80
  new RpcTransport({
@@ -82,53 +84,60 @@ export class Runner {
82
84
  ],
83
85
  })
84
86
 
85
- const ty = JSON.stringify(this.quads.filter(x => x.subject.value === proc.uri && x.predicate.equals(RDF.terms.type)).map(x => x.object.value))
86
- this.logger.info("parsing " + proc.uri + " type " + ty)
87
+ const ty = JSON.stringify(
88
+ this.quads
89
+ .filter(
90
+ (x) =>
91
+ x.subject.value === proc.uri && x.predicate.equals(RDF.terms.type),
92
+ )
93
+ .map((x) => x.object.value),
94
+ )
95
+ this.logger.info('parsing ' + proc.uri + ' type ' + ty)
87
96
  const args = this.shapes.lenses[RDFL.TypedExtract].execute({
88
97
  id: new NamedNode(proc.uri),
89
98
  quads: this.quads,
90
99
  })
91
100
 
92
101
  const config: ProcessorConfig = JSON.parse(proc.config)
93
- const url = new URL(config.location)
94
- process.chdir(url.pathname)
102
+ // const url = new URL(config.location)
103
+ // process.chdir(url.pathname)
95
104
  const jsProgram = await import(config.file)
96
105
  const clazz = jsProgram[config.clazz || 'default']
97
106
  const instance: Proc<unknown> = new clazz(args, procLogger)
98
107
  await instance.init()
99
108
 
100
- this.logger.info("inited " + proc.uri + " type " + ty)
101
- await this.write({ init: { uri: proc.uri } })
109
+ this.logger.info('inited ' + proc.uri + ' type ' + ty)
102
110
 
103
111
  this.processors.push(instance)
104
112
  this.processorTransforms.push(instance.transform())
105
113
 
106
- return <FullProc<P>>instance;
114
+ await this.write({ init: { uri: proc.uri } })
115
+
116
+ return <FullProc<P>>instance
107
117
  }
108
118
 
109
119
  async start() {
110
- await Promise.all(this.processors.map((x) => x.produce()))
111
- await Promise.all(this.processorTransforms)
120
+ try {
121
+ await Promise.all(this.processors.map((x) => x.produce()))
122
+ await Promise.all(this.processorTransforms)
123
+ } catch (ex: unknown) {
124
+ this.logger.error("Start failed: " + JSON.stringify(ex))
125
+ }
112
126
  }
113
127
 
114
128
  createWriter(uri: Term): Writer {
115
- const ids = uri.value;
129
+ const ids = uri.value
116
130
 
117
131
  if (this.writers[ids] === undefined) {
118
132
  this.writers[ids] = []
119
133
  }
120
- const writer = new WriterInstance(
121
- ids,
122
- this.client,
123
- this.write,
124
- this.logger,
125
- )
134
+ const writer = new WriterInstance(ids, this.client, this.write, this.logger)
126
135
  this.writers[ids].push(writer)
127
136
  return writer
128
137
  }
129
138
 
130
139
  createReader(uri: Term): Reader {
131
- const ids = uri.value;
140
+ const ids = uri.value
132
141
 
133
142
  if (this.readers[ids] === undefined) {
134
143
  this.readers[ids] = []
@@ -165,17 +174,26 @@ export class Runner {
165
174
  }
166
175
 
167
176
  if (msg.pipeline) {
168
- // here
169
- const quads = new Parser().parse(msg.pipeline);
170
- this.shapes = extractShapes(quads, {
171
- [RDFC.Reader]: (x: Cont) => this.createReader(x.id),
172
- [RDFC.Writer]: (x: Cont) => this.createWriter(x.id)
173
- }, {
174
- [RDFC.Reader]: empty<Cont>(),
175
- [RDFC.Writer]: empty<Cont>()
176
- });
177
- this.quads = quads;
178
- this.logger.info("extracted shapes " + JSON.stringify(Object.keys(this.shapes.lenses)));
177
+ try {
178
+
179
+ // here
180
+ const quads = new Parser().parse(msg.pipeline)
181
+ this.shapes = extractShapes(
182
+ quads,
183
+ {
184
+ [RDFC.Reader]: (x: Cont) => this.createReader(x.id),
185
+ [RDFC.Writer]: (x: Cont) => this.createWriter(x.id),
186
+ },
187
+ {
188
+ [RDFC.Reader]: empty<Cont>(),
189
+ [RDFC.Writer]: empty<Cont>(),
190
+ },
191
+ )
192
+ this.quads = quads
193
+ }
194
+ catch (ex: unknown) {
195
+ this.logger.error("Pipeline failed: " + JSON.stringify(ex))
196
+ }
179
197
  }
180
198
  }
181
199
  }
package/src/testUtils.ts CHANGED
@@ -1,20 +1,22 @@
1
- import { DataChunk, OrchestratorMessage, RunnerClient } from '@rdfc/proto'
1
+ import { DataChunk, RunnerClient } from '@rdfc/proto'
2
2
  import { ClientReadableStream } from '@grpc/grpc-js'
3
3
  import * as grpc from '@grpc/grpc-js'
4
4
  import { ClientReadableStreamImpl } from './reexports'
5
- import { extractShapes } from 'rdf-lens';
6
- import { Parser } from 'n3';
7
- import { readFile } from 'fs/promises';
8
- import winston, { createLogger } from 'winston';
9
- import { WriterInstance } from './writer';
10
- import { ReaderInstance } from './reader';
5
+ import { extractShapes } from 'rdf-lens'
6
+ import { Parser } from 'n3'
7
+ import { readFile } from 'fs/promises'
8
+ import winston, { createLogger } from 'winston'
9
+ import { WriterInstance } from './writer'
10
+ import { ReaderInstance } from './reader'
11
11
 
12
- export async function getProcessorShape(baseIRI = process.cwd() + "/node_modules/@rdfc/js-runner/index.ttl") {
13
- const configFile = await readFile(baseIRI, { encoding: "utf8" });
14
- const configQuads = new Parser().parse(configFile);
15
- const shapes = extractShapes(configQuads);
12
+ export async function getProcessorShape(
13
+ baseIRI = process.cwd() + '/node_modules/@rdfc/js-runner/index.ttl',
14
+ ) {
15
+ const configFile = await readFile(baseIRI, { encoding: 'utf8' })
16
+ const configQuads = new Parser().parse(configFile)
17
+ const shapes = extractShapes(configQuads)
16
18
 
17
- return shapes;
19
+ return shapes
18
20
  }
19
21
 
20
22
  export class TestClient extends RunnerClient {
@@ -46,23 +48,30 @@ export async function one<T>(iter: AsyncIterable<T>): Promise<T | undefined> {
46
48
  export const client = new TestClient()
47
49
  export const uri = 'someUri'
48
50
  export const logger = createLogger({
49
- transports: new winston.transports.Console({ level: process.env['DEBUG'] || 'info' }),
51
+ transports: new winston.transports.Console({
52
+ level: process.env['DEBUG'] || 'info',
53
+ }),
50
54
  })
51
55
 
52
56
  export function createWriter(iri = uri): [WriterInstance, ReaderInstance] {
53
- const reader = createReader(iri);
54
- const writeStream = new WriterInstance(iri, client, async (msg) => {
55
- if (msg.msg) {
56
- reader.handleMsg(msg.msg);
57
- }
58
- if(msg.close) {
59
- reader.close()
60
- }
61
- }, logger)
62
- return [writeStream, reader];
57
+ const reader = createReader(iri)
58
+ const writeStream = new WriterInstance(
59
+ iri,
60
+ client,
61
+ async (msg) => {
62
+ if (msg.msg) {
63
+ reader.handleMsg(msg.msg)
64
+ }
65
+ if (msg.close) {
66
+ reader.close()
67
+ }
68
+ },
69
+ logger,
70
+ )
71
+ return [writeStream, reader]
63
72
  }
64
73
 
65
74
  export function createReader(iri = uri): ReaderInstance {
66
- const reader = new ReaderInstance(iri, client, logger);
67
- return reader;
75
+ const reader = new ReaderInstance(iri, client, logger)
76
+ return reader
68
77
  }
package/src/writer.ts CHANGED
@@ -5,6 +5,7 @@ import { Any } from './reader'
5
5
 
6
6
  type Writable = (msg: OrchestratorMessage) => Promise<unknown>
7
7
  export interface Writer {
8
+ readonly uri: string
8
9
  buffer(buffer: Uint8Array): Promise<void>
9
10
 
10
11
  stream(buffer: AsyncIterable<Uint8Array>): Promise<void>
@@ -19,7 +20,7 @@ export interface Writer {
19
20
  }
20
21
  const encoder = new TextEncoder()
21
22
  export class WriterInstance implements Writer {
22
- private readonly uri: string
23
+ readonly uri: string
23
24
  private readonly client: RunnerClient
24
25
  private readonly write: Writable
25
26
  private readonly logger: Logger
package/vite.config.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("vitest/config");
4
+ exports.default = (0, config_1.defineConfig)({
5
+ test: {
6
+ coverage: {
7
+ enabled: true,
8
+ include: ['src/'],
9
+ },
10
+ },
11
+ });