Compare commits

...

6 Commits

7 changed files with 126 additions and 13 deletions

6
app/package-lock.json generated
View File

@ -191,6 +191,12 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"builtin-modules": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
"integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
"dev": true
},
"cacheable-request": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",

View File

@ -11,6 +11,8 @@
"@snowpack/plugin-svelte": "^3.5.2",
"@snowpack/plugin-typescript": "^1.2.1",
"@tsconfig/svelte": "^1.0.10",
"@types/node": "^14.14.28",
"builtin-modules": "^3.2.0",
"concurrently": "^5.3.0",
"cross-env": "^7.0.3",
"electron": "^11.2.3",

View File

@ -1,4 +1,6 @@
/** @type {import("snowpack").SnowpackUserConfig } */
const builtinModules = require('builtin-modules')
module.exports = {
mount: {
/* ... */
@ -22,6 +24,7 @@ module.exports = {
},
packageOptions: {
/* ... */
external: [...builtinModules.filter((external) => external !== 'process'), 'electron'],
},
devOptions: {
/* ... */

View File

@ -1,14 +1,17 @@
<script>
import { onMount } from 'svelte'
const { spawn } = require('child_process')
import { createServiceBroker, ServiceBroker } from './service/spawner'
import AppHeader from './components/AppHeader.svelte'
let count: number = 0
let serviceBroker: ServiceBroker
onMount(() => {
onMount(async () => {
const interval = setInterval(() => count++, 1000)
serviceBroker = await createServiceBroker("../../service/service")
// TODO: Spin up service
return () => {
serviceBroker.close()
clearInterval(interval)
// TODO: Close service
}

View File

@ -0,0 +1,59 @@
let { TransformOptions, Transform, Readable, Writable } = require('stream')
//import { TransformOptions, Transform, Readable, Writable } from 'stream'
class JSONReader extends Transform {
constructor(options: typeof TransformOptions) {
super(options)
}
_transform(data: string, encoding: string, cb: (chunk:any, err?:any) => void) {
try {
cb(null, JSON.parse(data))
} catch(err) {
// Silently fail as this means the stream presumably hasn't finished writing yet.
}
}
}
export class ServiceBroker {
protected jsonWriter: typeof Transform = new Transform({
objectMode: true,
})
protected errorReader: typeof Transform = new Transform({ })
protected jsonReader: JSONReader = new JSONReader({
objectMode: true,
})
constructor(input: typeof Readable, output: typeof Writable, error: typeof Readable) {
// Set up our reader callback.
this.jsonReader.on("data", (json: any) => {
// TODO: Something with our object
console.log("got json data: ", json)
})
// Pipe the input(process's stdout) to our JSONReader.
input.pipe(this.jsonReader)
// Send our immediate message to enable JSON mode.
output.write(JSON.stringify({enableJSON: true}))
//this.jsonWriter.pipe(output)
//error.pipe(this.errorReader)
/*this.errorReader.on("data", (chunk) => {
console.log("got error data: ", chunk)
})*/
input.once('close', () => {
// ...
})
output.once('close', () => {
this.close()
})
// stdinCb: (arg0: string) => void, StdoutCb: (arg0: string) => void, StderrCb: (arg0: string) => void) {
}
onInput(d: string): void {
}
close(): void {
console.log('should close')
}
}

View File

@ -0,0 +1,43 @@
let { spawn } = require('child_process')
let os = require('os')
/*import { spawn } from 'child_process'
import os from 'os'*/
//import path from 'path'
let path = require('path')
import { ServiceBroker } from './ServiceBroker'
export async function createServiceBroker(exe = "service" + (os.platform()==='win32'?'.exe':'')): Promise<ServiceBroker> {
return new Promise((resolve, reject) => {
let broker: ServiceBroker
let process = spawn(exe, {
cwd: '',
})
// We're keeping track of if an error happened so we can check if the process actually spawned...
let hadError: Error
process.once('error', (err: Error) => {
hadError = err
if (broker) {
broker.close()
}
reject(err)
})
// FIXME: This timeout is super-hacky, but Electron uses node 12 which does not provide the 'spawn' event for the ChildProcess type.
setTimeout(() => {
if (hadError) {
reject(hadError)
} else {
process.once('close', (code: number) => {
if (broker) {
broker.close()
}
})
broker = new ServiceBroker(process.stdout, process.stdin, process.stderr)
resolve(broker)
}
}, 100)
})
}
export { ServiceBroker }

View File

@ -1,21 +1,18 @@
{
"include": ["src", "types"],
"extends": "@tsconfig/svelte/tsconfig.json",
"include": [
"./src/**/*.ts",
"types",
"node_modules/@types",
],
"compilerOptions": {
"module": "esnext",
"target": "esnext",
"moduleResolution": "node",
"jsx": "preserve",
"baseUrl": "./",
"paths": {
},
"noEmit": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"useDefineForClassFields": true,
"allowSyntheticDefaultImports": true,
"importsNotUsedAsValues": "error"
},
"extends": "@tsconfig/svelte/tsconfig.json"
"importsNotUsedAsValues": "error",
}
}