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

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,147 +2,148 @@ 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
13
+ | {
14
+ string: string
15
15
  }
16
- | {
17
- stream: AsyncGenerator<Uint8Array>
16
+ | {
17
+ stream: AsyncGenerator<Uint8Array>
18
18
  }
19
- | {
20
- buffer: Uint8Array
19
+ | {
20
+ buffer: Uint8Array
21
21
  }
22
22
 
23
23
  export interface Reader {
24
- strings(): AsyncIterable<string>
25
- streams(): AsyncIterable<AsyncGenerator<Uint8Array>>
26
- buffers(): AsyncIterable<Uint8Array>
27
- anys(): AsyncIterable<Any>
24
+ readonly uri: string
25
+ strings(): AsyncIterable<string>
26
+ streams(): AsyncIterable<AsyncGenerator<Uint8Array>>
27
+ buffers(): AsyncIterable<Uint8Array>
28
+ anys(): AsyncIterable<Any>
28
29
  }
29
30
 
30
31
  class MyIter<T> implements AsyncIterable<T> {
31
- private convertor: Convertor<T>
32
- private queue: (T | undefined)[] = []
33
- private resolveNext: ((value: T | undefined) => void) | null = null
34
-
35
- constructor(convertor: Convertor<T>) {
36
- this.convertor = convertor
37
- }
38
-
39
- push(buffer: Uint8Array) {
40
- const item = this.convertor.from(buffer)
41
- if (this.resolveNext) {
42
- this.resolveNext(item)
43
- this.resolveNext = null
44
- } else {
45
- this.queue.push(item)
46
- }
47
- }
48
-
49
- close() {
50
- if (this.resolveNext) {
51
- this.resolveNext(undefined)
52
- this.resolveNext = null
53
- } else {
54
- this.queue.push(undefined)
55
- }
56
- }
57
-
58
- async pushStream(chunks: ClientReadableStream<DataChunk>) {
59
- const stream = (async function* (stream) {
60
- for await (const c of stream) {
61
- const chunk: DataChunk = c
62
- yield chunk.data
63
- }
64
- })(chunks)
65
- const item = await this.convertor.fromStream(stream)
66
- if (this.resolveNext) {
67
- this.resolveNext(item)
68
- this.resolveNext = null
69
- } else {
70
- this.queue.push(item)
71
- }
72
- }
73
-
74
- async *[Symbol.asyncIterator]() {
75
- while (true) {
76
- if (this.queue.length > 0) {
77
- const item = this.queue.shift()!
78
- if (item === undefined) break
79
- yield item
80
- } else {
81
- const item = await new Promise<T | undefined>(
82
- (resolve) => (this.resolveNext = resolve),
83
- )
84
- if (item === undefined) break
85
- yield item
86
- }
87
- }
88
- }
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
+ }
89
90
  }
90
91
 
91
92
  export class ReaderInstance implements Reader {
92
- private client: RunnerClient
93
- private uri: string
94
- private logger: winston.Logger
95
-
96
- private iterators: MyIter<unknown>[] = []
97
-
98
- constructor(uri: string, client: RunnerClient, logger: winston.Logger) {
99
- this.uri = uri
100
- this.client = client
101
- this.logger = logger
102
- }
103
-
104
- anys(): AsyncIterable<Any> {
105
- const iter = new MyIter(AnyConvertor)
106
- this.iterators.push(iter)
107
- return iter
108
- }
109
-
110
- strings(): AsyncIterable<string> {
111
- const iter = new MyIter(StringConvertor)
112
- this.iterators.push(iter)
113
- return iter
114
- }
115
-
116
- buffers(): AsyncIterable<Uint8Array> {
117
- const iter = new MyIter(NoConvertor)
118
- this.iterators.push(iter)
119
- return iter
120
- }
121
-
122
- streams(): AsyncIterable<AsyncGenerator<Uint8Array>> {
123
- const iter = new MyIter(StreamConvertor)
124
- this.iterators.push(iter)
125
- return iter
126
- }
127
-
128
- handleMsg(msg: Message) {
129
- this.logger.debug(`${this.uri} handling message`)
130
- for (const iter of this.iterators) {
131
- iter.push(msg.data)
132
- }
133
- }
134
-
135
- close() {
136
- for (const iter of this.iterators) {
137
- iter.close()
138
- }
139
- }
140
-
141
- handleStreamingMessage(msg: StreamMessage) {
142
- this.logger.debug(`${this.uri} handling streaming message`)
143
- const chunks = this.client.receiveStreamMessage(msg.id!)
144
- for (const iter of this.iterators) {
145
- iter.pushStream(chunks)
146
- }
147
- }
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
+ }
148
149
  }
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'
@@ -18,164 +18,165 @@ import { createNamespace, createUriAndTermNamespace, RDF } from '@treecg/types'
18
18
  import { Quad, Term } from '@rdfjs/types'
19
19
 
20
20
  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',
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',
31
31
  )
32
32
 
33
33
  const RDFC = createNamespace(
34
- 'https://w3id.org/rdf-connect/ontology#',
35
- (x) => x,
36
- 'Reader',
37
- 'Writer',
34
+ 'https://w3id.org/rdf-connect#',
35
+ (x) => x,
36
+ 'Reader',
37
+ 'Writer',
38
38
  )
39
39
 
40
40
  export type Writable = (msg: OrchestratorMessage) => Promise<unknown>
41
41
 
42
42
  type ProcessorConfig = {
43
- location: string
44
- file: string
45
- clazz?: string
43
+ location: string
44
+ file: string
45
+ clazz?: string
46
46
  }
47
47
 
48
48
  export type FullProc<C extends Proc<unknown>> = 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
73
- }
74
-
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
- await this.write({ init: { uri: proc.uri } })
102
-
103
- this.processors.push(instance)
104
- this.processorTransforms.push(instance.transform())
105
-
106
- return <FullProc<P>>instance;
107
- }
108
-
109
- async start() {
110
- await Promise.all(this.processors.map((x) => x.produce()))
111
- await Promise.all(this.processorTransforms)
112
- }
113
-
114
- createWriter(uri: Term): Writer {
115
- const ids = uri.value;
116
-
117
- if (this.writers[ids] === undefined) {
118
- this.writers[ids] = []
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
119
73
  }
120
- const writer = new WriterInstance(
121
- ids,
122
- this.client,
123
- this.write,
124
- this.logger,
125
- )
126
- this.writers[ids].push(writer)
127
- return writer
128
- }
129
-
130
- createReader(uri: Term): Reader {
131
- const ids = uri.value;
132
-
133
- if (this.readers[ids] === undefined) {
134
- this.readers[ids] = []
135
- }
136
- const reader = new ReaderInstance(ids, this.client, this.logger)
137
- this.readers[ids].push(reader)
138
- return reader
139
- }
140
-
141
- async handleOrchMessage(msg: RunnerMessage) {
142
- if (msg.msg) {
143
- this.logger.debug('Handling data msg for ' + msg.msg.channel)
144
- for (const reader of this.readers[msg.msg.channel] || []) {
145
- reader.handleMsg(msg.msg)
146
- }
74
+
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;
147
108
  }
148
109
 
149
- if (msg.streamMsg) {
150
- for (const reader of this.readers[msg.streamMsg.channel] || []) {
151
- reader.handleStreamingMessage(msg.streamMsg)
152
- }
110
+ async start() {
111
+ await Promise.all(this.processors.map((x) => x.produce()))
112
+ await Promise.all(this.processorTransforms)
153
113
  }
154
114
 
155
- if (msg.close) {
156
- const uri = msg.close.channel
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
129
+ }
157
130
 
158
- for (const reader of this.readers[uri] || []) {
159
- reader.close()
160
- }
131
+ createReader(uri: Term): Reader {
132
+ const ids = uri.value;
161
133
 
162
- for (const writer of this.writers[uri] || []) {
163
- await writer.close(true)
164
- }
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
165
140
  }
166
141
 
167
- 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)));
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
+ }
179
181
  }
180
- }
181
182
  }
@@ -16,5 +16,5 @@ export class LogProcessor extends Processor<LogArgs> {
16
16
  }
17
17
  }
18
18
 
19
- async produce() {}
19
+ async produce() { }
20
20
  }