@rdfc/js-runner 2.0.0-alpha.7 → 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.
package/src/reader.ts CHANGED
@@ -2,148 +2,144 @@ import { ClientReadableStream } from '@grpc/grpc-js'
2
2
  import { DataChunk, Message, RunnerClient, StreamMessage } from '@rdfc/proto'
3
3
  import winston from 'winston'
4
4
  import {
5
- AnyConvertor,
6
- Convertor,
7
- NoConvertor,
8
- StreamConvertor,
9
- StringConvertor,
5
+ AnyConvertor,
6
+ Convertor,
7
+ NoConvertor,
8
+ StreamConvertor,
9
+ StringConvertor,
10
10
  } from './convertor'
11
11
 
12
12
  export type Any =
13
- | {
14
- string: string
15
- }
16
- | {
17
- stream: AsyncGenerator<Uint8Array>
18
- }
19
- | {
20
- buffer: Uint8Array
21
- }
13
+ | {
14
+ string: string
15
+ }
16
+ | {
17
+ stream: AsyncGenerator<Uint8Array>
18
+ }
19
+ | {
20
+ buffer: Uint8Array
21
+ }
22
22
 
23
23
  export interface Reader {
24
- readonly uri: string
25
- strings(): AsyncIterable<string>
26
- streams(): AsyncIterable<AsyncGenerator<Uint8Array>>
27
- buffers(): AsyncIterable<Uint8Array>
28
- anys(): AsyncIterable<Any>
24
+ readonly uri: string
25
+ strings(): AsyncIterable<string>
26
+ streams(): AsyncIterable<AsyncGenerator<Uint8Array>>
27
+ buffers(): AsyncIterable<Uint8Array>
28
+ anys(): AsyncIterable<Any>
29
29
  }
30
30
 
31
31
  class MyIter<T> implements AsyncIterable<T> {
32
- private convertor: Convertor<T>
33
- private queue: (T | undefined)[] = []
34
- private resolveNext: ((value: T | undefined) => void) | null = null
35
-
36
- constructor(convertor: Convertor<T>) {
37
- this.convertor = convertor
38
- }
39
-
40
- push(buffer: Uint8Array) {
41
- const item = this.convertor.from(buffer)
42
- if (this.resolveNext) {
43
- this.resolveNext(item)
44
- this.resolveNext = null
45
- } else {
46
- this.queue.push(item)
47
- }
48
- }
49
-
50
- close() {
51
- if (this.resolveNext) {
52
- this.resolveNext(undefined)
53
- this.resolveNext = null
54
- } else {
55
- this.queue.push(undefined)
56
- }
57
- }
58
-
59
- async pushStream(chunks: ClientReadableStream<DataChunk>) {
60
- const stream = (async function*(stream) {
61
- for await (const c of stream) {
62
- const chunk: DataChunk = c
63
- yield chunk.data
64
- }
65
- })(chunks)
66
- const item = await this.convertor.fromStream(stream)
67
- if (this.resolveNext) {
68
- this.resolveNext(item)
69
- this.resolveNext = null
70
- } else {
71
- this.queue.push(item)
72
- }
73
- }
74
-
75
- async *[Symbol.asyncIterator]() {
76
- while (true) {
77
- if (this.queue.length > 0) {
78
- const item = this.queue.shift()!
79
- if (item === undefined) break
80
- yield item
81
- } else {
82
- const item = await new Promise<T | undefined>(
83
- (resolve) => (this.resolveNext = resolve),
84
- )
85
- if (item === undefined) break
86
- yield item
87
- }
88
- }
89
- }
32
+ private convertor: Convertor<T>
33
+ private queue: (T | undefined)[] = []
34
+ private resolveNext: ((value: undefined) => void) | null = null
35
+
36
+ constructor(convertor: Convertor<T>) {
37
+ this.convertor = convertor
38
+ }
39
+
40
+ push(buffer: Uint8Array) {
41
+ const item = this.convertor.from(buffer)
42
+ this.queue.push(item)
43
+ if (this.resolveNext) {
44
+ this.resolveNext(undefined)
45
+ this.resolveNext = null
46
+ }
47
+ }
48
+
49
+ close() {
50
+ this.queue.push(undefined)
51
+ if (this.resolveNext) {
52
+ this.resolveNext(undefined)
53
+ this.resolveNext = null
54
+ }
55
+ }
56
+
57
+ async pushStream(chunks: ClientReadableStream<DataChunk>) {
58
+ const stream = (async function*(stream) {
59
+ for await (const c of stream) {
60
+ const chunk: DataChunk = c
61
+ yield chunk.data
62
+ }
63
+ })(chunks)
64
+ const item = await this.convertor.fromStream(stream)
65
+ this.queue.push(item)
66
+ if (this.resolveNext) {
67
+ this.resolveNext(undefined)
68
+ this.resolveNext = null
69
+ }
70
+ }
71
+
72
+ async *[Symbol.asyncIterator]() {
73
+ while (true) {
74
+ if (this.queue.length > 0) {
75
+ const item = this.queue.shift()!
76
+ if (item === undefined) break
77
+ yield item
78
+ } else {
79
+ await new Promise<undefined>(
80
+ (resolve) => (this.resolveNext = resolve),
81
+ )
82
+ }
83
+ }
84
+ }
90
85
  }
91
86
 
92
87
  export class ReaderInstance implements Reader {
93
- private client: RunnerClient
94
- readonly uri: string
95
- private logger: winston.Logger
96
-
97
- private iterators: MyIter<unknown>[] = []
98
-
99
- constructor(uri: string, client: RunnerClient, logger: winston.Logger) {
100
- this.uri = uri
101
- this.client = client
102
- this.logger = logger
103
- }
104
-
105
- anys(): AsyncIterable<Any> {
106
- const iter = new MyIter(AnyConvertor)
107
- this.iterators.push(iter)
108
- return iter
109
- }
110
-
111
- strings(): AsyncIterable<string> {
112
- const iter = new MyIter(StringConvertor)
113
- this.iterators.push(iter)
114
- return iter
115
- }
116
-
117
- buffers(): AsyncIterable<Uint8Array> {
118
- const iter = new MyIter(NoConvertor)
119
- this.iterators.push(iter)
120
- return iter
121
- }
122
-
123
- streams(): AsyncIterable<AsyncGenerator<Uint8Array>> {
124
- const iter = new MyIter(StreamConvertor)
125
- this.iterators.push(iter)
126
- return iter
127
- }
128
-
129
- handleMsg(msg: Message) {
130
- this.logger.debug(`${this.uri} handling message`)
131
- for (const iter of this.iterators) {
132
- iter.push(msg.data)
133
- }
134
- }
135
-
136
- close() {
137
- for (const iter of this.iterators) {
138
- iter.close()
139
- }
140
- }
141
-
142
- handleStreamingMessage(msg: StreamMessage) {
143
- this.logger.debug(`${this.uri} handling streaming message`)
144
- const chunks = this.client.receiveStreamMessage(msg.id!)
145
- for (const iter of this.iterators) {
146
- iter.pushStream(chunks)
147
- }
148
- }
88
+ private client: RunnerClient
89
+ readonly uri: string
90
+ private logger: winston.Logger
91
+
92
+ private iterators: MyIter<unknown>[] = []
93
+
94
+ constructor(uri: string, client: RunnerClient, logger: winston.Logger) {
95
+ this.uri = uri
96
+ this.client = client
97
+ this.logger = logger
98
+ }
99
+
100
+ anys(): AsyncIterable<Any> {
101
+ const iter = new MyIter(AnyConvertor)
102
+ this.iterators.push(iter)
103
+ return iter
104
+ }
105
+
106
+ strings(): AsyncIterable<string> {
107
+ const iter = new MyIter(StringConvertor)
108
+ this.iterators.push(iter)
109
+ return iter
110
+ }
111
+
112
+ buffers(): AsyncIterable<Uint8Array> {
113
+ const iter = new MyIter(NoConvertor)
114
+ this.iterators.push(iter)
115
+ return iter
116
+ }
117
+
118
+ streams(): AsyncIterable<AsyncGenerator<Uint8Array>> {
119
+ const iter = new MyIter(StreamConvertor)
120
+ this.iterators.push(iter)
121
+ return iter
122
+ }
123
+
124
+ handleMsg(msg: Message) {
125
+ this.logger.debug(`${this.uri} handling message`)
126
+ console.log(`${this.uri} handling message`)
127
+ for (const iter of this.iterators) {
128
+ iter.push(msg.data)
129
+ }
130
+ }
131
+
132
+ close() {
133
+ for (const iter of this.iterators) {
134
+ iter.close()
135
+ }
136
+ }
137
+
138
+ handleStreamingMessage(msg: StreamMessage) {
139
+ this.logger.debug(`${this.uri} handling streaming message`)
140
+ const chunks = this.client.receiveStreamMessage(msg.id!)
141
+ for (const iter of this.iterators) {
142
+ iter.pushStream(chunks)
143
+ }
144
+ }
149
145
  }
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
@@ -1,8 +1,8 @@
1
1
  import {
2
- OrchestratorMessage,
3
- Processor,
4
- RunnerClient,
5
- RunnerMessage,
2
+ OrchestratorMessage,
3
+ Processor,
4
+ RunnerClient,
5
+ RunnerMessage,
6
6
  } from '@rdfc/proto'
7
7
  import { Reader, ReaderInstance } from './reader'
8
8
  import { Writer, WriterInstance } from './writer'
@@ -11,172 +11,189 @@ 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'
18
17
  import { Quad, Term } from '@rdfjs/types'
19
18
 
20
19
  const RDFL = createUriAndTermNamespace(
21
- 'https://w3id.org/rdf-lens/ontology#',
22
- 'CBD',
23
- 'Path',
24
- 'PathLens',
25
- 'Context',
26
- 'TypedExtract',
27
- 'EnvVariable',
28
- 'envKey',
29
- 'envDefault',
30
- 'datatype',
20
+ 'https://w3id.org/rdf-lens/ontology#',
21
+ 'CBD',
22
+ 'Path',
23
+ 'PathLens',
24
+ 'Context',
25
+ 'TypedExtract',
26
+ 'EnvVariable',
27
+ 'envKey',
28
+ 'envDefault',
29
+ 'datatype',
31
30
  )
32
31
 
33
32
  const RDFC = createNamespace(
34
- 'https://w3id.org/rdf-connect#',
35
- (x) => x,
36
- 'Reader',
37
- 'Writer',
33
+ 'https://w3id.org/rdf-connect#',
34
+ (x) => x,
35
+ 'Reader',
36
+ 'Writer',
38
37
  )
39
38
 
40
39
  export type Writable = (msg: OrchestratorMessage) => Promise<unknown>
41
40
 
42
41
  type ProcessorConfig = {
43
- location: string
44
- file: string
45
- clazz?: string
42
+ location: string
43
+ file: string
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
- private readonly readers: { [uri: string]: ReaderInstance[] } = {}
51
- private readonly writers: { [uri: string]: WriterInstance[] } = {}
52
- private readonly client: RunnerClient
53
- private readonly write: Writable
54
- private readonly logger: Logger
55
- private shapes: Shapes
56
- private quads: Quad[] = []
57
-
58
- private readonly uri: string
59
-
60
- private readonly processors: Proc<unknown>[] = []
61
- private readonly processorTransforms: Promise<unknown>[] = []
62
-
63
- constructor(
64
- client: RunnerClient,
65
- write: Writable,
66
- uri: string,
67
- logger: Logger,
68
- ) {
69
- this.client = client
70
- this.write = write
71
- this.uri = uri
72
- this.logger = logger
50
+ private readonly readers: { [uri: string]: ReaderInstance[] } = {}
51
+ private readonly writers: { [uri: string]: WriterInstance[] } = {}
52
+ private readonly client: RunnerClient
53
+ private readonly write: Writable
54
+ private readonly logger: Logger
55
+ private shapes: Shapes
56
+ private quads: Quad[] = []
57
+
58
+ private readonly uri: string
59
+
60
+ private readonly processors: Proc<unknown>[] = []
61
+ private readonly processorTransforms: Promise<unknown>[] = []
62
+
63
+ constructor(
64
+ client: RunnerClient,
65
+ write: Writable,
66
+ uri: string,
67
+ logger: Logger,
68
+ ) {
69
+ this.client = client
70
+ this.write = write
71
+ this.uri = uri
72
+ this.logger = logger
73
+ }
74
+
75
+ async addProcessor<P extends Proc<unknown>>(
76
+ proc: Processor,
77
+ ): Promise<FullProc<P>> {
78
+ const procLogger = winston.createLogger({
79
+ transports: [
80
+ new RpcTransport({
81
+ entities: [proc.uri, this.uri],
82
+ stream: this.client.logStream(() => { }),
83
+ }),
84
+ ],
85
+ })
86
+
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)
96
+ const args = this.shapes.lenses[RDFL.TypedExtract].execute({
97
+ id: new NamedNode(proc.uri),
98
+ quads: this.quads,
99
+ })
100
+
101
+ const config: ProcessorConfig = JSON.parse(proc.config)
102
+ // const url = new URL(config.location)
103
+ // process.chdir(url.pathname)
104
+ const jsProgram = await import(config.file)
105
+ const clazz = jsProgram[config.clazz || 'default']
106
+ const instance: Proc<unknown> = new clazz(args, procLogger)
107
+ await instance.init()
108
+
109
+ this.logger.info('inited ' + proc.uri + ' type ' + ty)
110
+
111
+ this.processors.push(instance)
112
+ this.processorTransforms.push(instance.transform())
113
+
114
+ await this.write({ init: { uri: proc.uri } })
115
+
116
+ return <FullProc<P>>instance
117
+ }
118
+
119
+ async start() {
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))
73
125
  }
126
+ }
127
+
128
+ createWriter(uri: Term): Writer {
129
+ const ids = uri.value
74
130
 
75
- async addProcessor<P extends Proc<unknown>>(proc: Processor): Promise<FullProc<P>> {
76
- const procLogger = winston.createLogger({
77
- transports: [
78
- new RpcTransport({
79
- entities: [proc.uri, this.uri],
80
- stream: this.client.logStream(() => { }),
81
- }),
82
- ],
83
- })
84
-
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 args = this.shapes.lenses[RDFL.TypedExtract].execute({
88
- id: new NamedNode(proc.uri),
89
- quads: this.quads,
90
- })
91
-
92
- const config: ProcessorConfig = JSON.parse(proc.config)
93
- // const url = new URL(config.location)
94
- // process.chdir(url.pathname)
95
- const jsProgram = await import(config.file)
96
- const clazz = jsProgram[config.clazz || 'default']
97
- const instance: Proc<unknown> = new clazz(args, procLogger)
98
- await instance.init()
99
-
100
- this.logger.info("inited " + proc.uri + " type " + ty)
101
-
102
- this.processors.push(instance)
103
- this.processorTransforms.push(instance.transform())
104
-
105
- await this.write({ init: { uri: proc.uri } })
106
-
107
- return <FullProc<P>>instance;
131
+ if (this.writers[ids] === undefined) {
132
+ this.writers[ids] = []
108
133
  }
134
+ const writer = new WriterInstance(ids, this.client, this.write, this.logger)
135
+ this.writers[ids].push(writer)
136
+ return writer
137
+ }
109
138
 
110
- async start() {
111
- await Promise.all(this.processors.map((x) => x.produce()))
112
- await Promise.all(this.processorTransforms)
139
+ createReader(uri: Term): Reader {
140
+ const ids = uri.value
141
+
142
+ if (this.readers[ids] === undefined) {
143
+ this.readers[ids] = []
144
+ }
145
+ const reader = new ReaderInstance(ids, this.client, this.logger)
146
+ this.readers[ids].push(reader)
147
+ return reader
148
+ }
149
+
150
+ async handleOrchMessage(msg: RunnerMessage) {
151
+ if (msg.msg) {
152
+ this.logger.debug('Handling data msg for ' + msg.msg.channel)
153
+ for (const reader of this.readers[msg.msg.channel] || []) {
154
+ reader.handleMsg(msg.msg)
155
+ }
113
156
  }
114
157
 
115
- createWriter(uri: Term): Writer {
116
- const ids = uri.value;
117
-
118
- if (this.writers[ids] === undefined) {
119
- this.writers[ids] = []
120
- }
121
- const writer = new WriterInstance(
122
- ids,
123
- this.client,
124
- this.write,
125
- this.logger,
126
- )
127
- this.writers[ids].push(writer)
128
- return writer
158
+ if (msg.streamMsg) {
159
+ for (const reader of this.readers[msg.streamMsg.channel] || []) {
160
+ reader.handleStreamingMessage(msg.streamMsg)
161
+ }
129
162
  }
130
163
 
131
- createReader(uri: Term): Reader {
132
- const ids = uri.value;
164
+ if (msg.close) {
165
+ const uri = msg.close.channel
166
+
167
+ for (const reader of this.readers[uri] || []) {
168
+ reader.close()
169
+ }
133
170
 
134
- if (this.readers[ids] === undefined) {
135
- this.readers[ids] = []
136
- }
137
- const reader = new ReaderInstance(ids, this.client, this.logger)
138
- this.readers[ids].push(reader)
139
- return reader
171
+ for (const writer of this.writers[uri] || []) {
172
+ await writer.close(true)
173
+ }
140
174
  }
141
175
 
142
- async handleOrchMessage(msg: RunnerMessage) {
143
- if (msg.msg) {
144
- this.logger.debug('Handling data msg for ' + msg.msg.channel)
145
- for (const reader of this.readers[msg.msg.channel] || []) {
146
- reader.handleMsg(msg.msg)
147
- }
148
- }
149
-
150
- if (msg.streamMsg) {
151
- for (const reader of this.readers[msg.streamMsg.channel] || []) {
152
- reader.handleStreamingMessage(msg.streamMsg)
153
- }
154
- }
155
-
156
- if (msg.close) {
157
- const uri = msg.close.channel
158
-
159
- for (const reader of this.readers[uri] || []) {
160
- reader.close()
161
- }
162
-
163
- for (const writer of this.writers[uri] || []) {
164
- await writer.close(true)
165
- }
166
- }
167
-
168
- if (msg.pipeline) {
169
- // here
170
- const quads = new Parser().parse(msg.pipeline);
171
- this.shapes = extractShapes(quads, {
172
- [RDFC.Reader]: (x: Cont) => this.createReader(x.id),
173
- [RDFC.Writer]: (x: Cont) => this.createWriter(x.id)
174
- }, {
175
- [RDFC.Reader]: empty<Cont>(),
176
- [RDFC.Writer]: empty<Cont>()
177
- });
178
- this.quads = quads;
179
- this.logger.info("extracted shapes " + JSON.stringify(Object.keys(this.shapes.lenses)));
180
- }
176
+ if (msg.pipeline) {
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
+ }
181
197
  }
198
+ }
182
199
  }