Skip to content

Commit 93bcd81

Browse files
committed
feat: Added JS executor backend
1 parent 8e09e96 commit 93bcd81

2 files changed

Lines changed: 44 additions & 15 deletions

File tree

src/backends.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as childProcess from "child_process"
2-
import {getLogger} from '@stencila/logga'
1+
import * as childProcess from 'child_process'
2+
import { getLogger } from '@stencila/logga'
33
const lps = require('length-prefixed-stream')
44
const { spawn } = require('child_process')
55
const log = getLogger('engine:backends')
@@ -10,7 +10,7 @@ export interface ExecutorBackend {
1010
execute(o: any): Promise<any>
1111
}
1212

13-
export class StencilaPythonBackend implements ExecutorBackend {
13+
abstract class StdioBackend implements ExecutorBackend {
1414
private process?: childProcess.ChildProcess
1515

1616
private stdin: any
@@ -19,9 +19,10 @@ export class StencilaPythonBackend implements ExecutorBackend {
1919

2020
private executionRequestCount: number = 0
2121

22-
setup(): void {
23-
this.process = spawn('python3', ['-m', 'stencila.schema', 'listen'])
24-
if (!this.process) throw new Error('Spawning python3 failed')
22+
protected abstract spawn(): childProcess.ChildProcess
23+
24+
public setup(): void {
25+
this.process = this.spawn()
2526
if (
2627
this.process.stdout === null ||
2728
this.process.stdin === null ||
@@ -42,15 +43,15 @@ export class StencilaPythonBackend implements ExecutorBackend {
4243
this.stdin.pipe(this.process.stdin)
4344
}
4445

45-
receive(json: Buffer, raw: boolean = false) {
46+
private receive(json: Buffer, raw: boolean = false) {
4647
const response = JSON.parse(json.toString())
4748
const resolve = this.executionRequests[response.id]
4849
resolve(response.body)
4950
delete this.executionRequests[response.id]
5051
}
5152

52-
async execute(o: any): Promise<any> {
53-
if (!this.process) {
53+
public async execute(o: any): Promise<any> {
54+
if (this.process === undefined) {
5455
throw new Error('Can not execute before setup')
5556
}
5657

@@ -72,3 +73,25 @@ export class StencilaPythonBackend implements ExecutorBackend {
7273
return promise
7374
}
7475
}
76+
77+
export class StencilaPythonBackend extends StdioBackend {
78+
protected spawn() {
79+
return spawn('python3', ['-m', 'stencila.schema', 'listen'])
80+
}
81+
}
82+
83+
export class StencilaJsBackend extends StdioBackend {
84+
protected spawn() {
85+
return spawn(
86+
'npx',
87+
[
88+
'ts-node',
89+
'/Users/ben/Documents/stencila/schema/ts/interpreter',
90+
'listen'
91+
],
92+
{
93+
cwd: '/Users/ben/Documents/stencila/schema'
94+
}
95+
)
96+
}
97+
}

src/executa.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import { getLogger } from '@stencila/logga'
2-
import { ExecutorBackend, StencilaPythonBackend } from './backends'
2+
import {
3+
ExecutorBackend,
4+
StencilaJsBackend,
5+
StencilaPythonBackend
6+
} from './backends'
37

48
const log = getLogger('engine:serve')
59

610
export default class Executa {
7-
backends: { [key: string]: ExecutorBackend } = {}
11+
private backends: { [key: string]: ExecutorBackend } = {}
812

9-
getBackend(name: string): ExecutorBackend {
13+
private getBackend(name: string): ExecutorBackend {
1014
if (this.backends[name] === undefined) {
1115
switch (name) {
1216
case 'python':
1317
this.backends[name] = new StencilaPythonBackend()
1418
break
19+
case 'javascript':
20+
this.backends[name] = new StencilaJsBackend()
21+
break
1522
default:
1623
throw new Error(`Unknown backend '${name}'`)
1724
}
@@ -21,9 +28,8 @@ export default class Executa {
2128
return this.backends[name]
2229
}
2330

24-
async execute(code: any): Promise<any> {
31+
public async execute(code: any): Promise<any> {
2532
const backend = this.getBackend(code.programmingLanguage)
26-
27-
return await backend.execute(code)
33+
return backend.execute(code)
2834
}
2935
}

0 commit comments

Comments
 (0)