@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.
- package/.editorconfig +9 -0
- package/__tests__/channels.test.js +117 -0
- package/examples/echo/.idea/echo.iml +9 -0
- package/examples/echo/.idea/misc.xml +6 -0
- package/examples/echo/.idea/modules.xml +8 -0
- package/examples/echo/.idea/vcs.xml +7 -0
- package/examples/echo/.swls/config.json +1 -0
- package/examples/echo/index.ttl +3 -0
- package/examples/echo/minimal.ttl +90 -0
- package/examples/echo/pipeline.ttl +22 -4
- package/examples/echo/processors.ttl +5 -7
- package/examples/echo/shacl.ttl +9 -0
- package/examples/echo/shape.ttl +1339 -0
- package/examples/echo/src/processors.js +123 -0
- package/examples/echo/src/processors.ts +3 -4
- package/examples/echo/test.ttl +9 -12
- package/file:/home/silvius/Projects/mumo-pipeline/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
- package/index.ttl +28 -20
- package/ldes/http_3A_2F_2Fdata.mumo.be_2Fstreams_2Fnodes_2Fdefault/root/index.trig +3 -0
- package/lib/client.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/jsonld.js +4 -3
- package/lib/reader.d.ts +2 -1
- package/lib/reader.js +8 -16
- package/lib/reexports.d.ts +2 -2
- package/lib/reexports.js +3 -3
- package/lib/runner.js +29 -20
- package/lib/testUtils.js +6 -4
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/writer.d.ts +2 -1
- package/lib/writer.js +1 -1
- package/minimal.ttl +99 -0
- package/package.json +1 -1
- package/src/client.ts +16 -14
- package/src/index.ts +1 -1
- package/src/jsonld.ts +5 -2
- package/src/reader.ts +17 -20
- package/src/reexports.ts +5 -2
- package/src/runner.ts +50 -32
- package/src/testUtils.ts +34 -25
- package/src/writer.ts +2 -1
- 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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
+
logger.error('Stream ended')
|
|
46
|
+
})()
|
|
45
47
|
|
|
46
48
|
await processorsEnded
|
|
47
49
|
|
package/src/index.ts
CHANGED
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
|
|
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
|
-
|
|
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
|
-
|
|
15
|
-
|
|
14
|
+
string: string
|
|
15
|
+
}
|
|
16
16
|
| {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
stream: AsyncGenerator<Uint8Array>
|
|
18
|
+
}
|
|
19
19
|
| {
|
|
20
|
-
|
|
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:
|
|
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(
|
|
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*
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2
|
-
export {
|
|
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
|
|
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>> =
|
|
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>>(
|
|
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(
|
|
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)
|
|
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(
|
|
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
|
-
|
|
114
|
+
await this.write({ init: { uri: proc.uri } })
|
|
115
|
+
|
|
116
|
+
return <FullProc<P>>instance
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
async start() {
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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,
|
|
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(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
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({
|
|
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(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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