bare-stow 0.3.0 → 0.3.2
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/README.md +16 -0
- package/lib/shim.js +8 -6
- package/lib/target/bare-sidecar.js +16 -7
- package/lib/target/bare-worker.js +3 -3
- package/lib/target/javascript.js +28 -11
- package/lib/target/swift.js +65 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,6 +69,22 @@ The bundle imports `bare-stow-runtime`, and the RPC library if a `server` is req
|
|
|
69
69
|
|
|
70
70
|
`start()` accepts `timeout`, how long to wait in milliseconds for the bundle to signal ready, and `grace`, how long a terminating bundle gets to run `stop()` and exit before it's killed. `timeout` defaults to waiting indefinitely and `grace` to 5 seconds. On Windows, a sidecar is killed along with its host, so `stop()` only runs when the host terminates it.
|
|
71
71
|
|
|
72
|
+
For `bare-sidecar` and `bare-worker`, the harness also exports `connect()`, which takes a sidecar or worker that the host started itself, such as one running a development entry with arguments, and resolves like `start()`. It accepts the same options, except those of the sidecar or worker. As the entry doesn't go through `stow()`, it attaches to the IPC itself, as described in <https://github.com/holepunchto/bare-stow-runtime>:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
const runtime = require('bare-stow-runtime/process')
|
|
76
|
+
|
|
77
|
+
const ipc = runtime.attach(Bare.IPC)
|
|
78
|
+
|
|
79
|
+
ipc.run(() => import('./core.js'), ipc)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
const sidecar = new Sidecar('./dev.js', ['--verbose'], { stdio: 'inherit' })
|
|
84
|
+
|
|
85
|
+
const { ipc } = await harness.connect(sidecar)
|
|
86
|
+
```
|
|
87
|
+
|
|
72
88
|
`stow()` and `link()` read the module graph from disk by default. To read it from elsewhere, such as modules that aren't written to disk, pass `readModule`, `listPrefix`, and `resolveModule`. Generated files are still written to disk. A `readModule` that changes the type of a module also passes `aliases`, as for <https://github.com/holepunchto/bare-pack>, such as `{ '.mjs': '.js' }` to have ES modules converted to CommonJS loaded as such. They're merged over the aliases that `bare-stow` uses for TypeScript.
|
|
73
89
|
|
|
74
90
|
## Targets
|
package/lib/shim.js
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
const javascript = require('./language/javascript')
|
|
2
2
|
const { select } = require('./provider')
|
|
3
3
|
|
|
4
|
-
// The bundle runs in Bare, so its side of every provider is JavaScript.
|
|
4
|
+
// The bundle runs in Bare, so its side of every provider is JavaScript. The
|
|
5
|
+
// shims are CommonJS, which loads in any graph, such as one whose ES modules are
|
|
6
|
+
// converted to CommonJS.
|
|
5
7
|
module.exports = function shim(entry, isolation, server = null) {
|
|
6
8
|
if (server) server = select('RPC library', server, javascript.name)
|
|
7
9
|
|
|
8
10
|
const dir = new URL('./', entry)
|
|
9
|
-
const url = new URL('__main__.
|
|
10
|
-
const serverURL = server ? new URL('__server__.
|
|
11
|
+
const url = new URL('__main__.cjs', dir)
|
|
12
|
+
const serverURL = server ? new URL('__server__.cjs', dir) : null
|
|
11
13
|
|
|
12
14
|
const modules = new Map()
|
|
13
15
|
|
|
14
16
|
if (server) {
|
|
15
17
|
modules.set(
|
|
16
18
|
serverURL.href,
|
|
17
|
-
server.generate({ role: 'server', options: { module: '
|
|
19
|
+
server.generate({ role: 'server', options: { module: 'cjs' } }).source
|
|
18
20
|
)
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
modules.set(
|
|
22
24
|
url.href,
|
|
23
25
|
`\
|
|
24
|
-
|
|
25
|
-
${server ? `
|
|
26
|
+
const runtime = require('${isolation === 'process' ? 'bare-stow-runtime/process' : 'bare-stow-runtime'}')
|
|
27
|
+
${server ? `const server = require(${JSON.stringify(javascript.reference(url, serverURL))})\n` : ''}
|
|
26
28
|
const ipc = runtime.attach(Bare.IPC)
|
|
27
29
|
${server ? '\nconst rpc = server.attach(ipc)\n' : ''}
|
|
28
30
|
ipc.run(() => import(${JSON.stringify(javascript.reference(url, entry))}), ${server ? '{ rpc, ipc }' : 'ipc'})
|
|
@@ -25,9 +25,9 @@ exports.languages = {
|
|
|
25
25
|
version: '^0.5.15',
|
|
26
26
|
binding: 'Sidecar',
|
|
27
27
|
url: true,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
handle: 'sidecar',
|
|
29
|
+
spawn: "new Sidecar(bundle, { stdio: 'inherit', ...opts })",
|
|
30
|
+
connect: `\
|
|
31
31
|
const ipc = stow.wrap(sidecar, { kill: () => sidecar.kill('SIGKILL'), timeout, grace })
|
|
32
32
|
|
|
33
33
|
sidecar.on('exit', (code, signal) => ipc.exited(code, signal))`,
|
|
@@ -41,9 +41,9 @@ sidecar.on('exit', (code, signal) => ipc.exited(code, signal))`,
|
|
|
41
41
|
return swift(context, {
|
|
42
42
|
module: 'BareSidecar',
|
|
43
43
|
conformance: 'extension Sidecar: @retroactive BareStowHost.Transport {}',
|
|
44
|
+
handle: { name: 'sidecar', type: 'Sidecar' },
|
|
45
|
+
spawn: 'try await Sidecar.spawn(bundle)',
|
|
44
46
|
setup: `\
|
|
45
|
-
let sidecar = try await Sidecar.spawn(bundle)
|
|
46
|
-
|
|
47
47
|
let ipc = BareStowHost.IPC(sidecar, kill: { sidecar.kill() }, timeout: timeout, grace: grace)
|
|
48
48
|
|
|
49
49
|
Task {
|
|
@@ -55,7 +55,7 @@ Task {
|
|
|
55
55
|
dependencies: {
|
|
56
56
|
'bare-sidecar-swift': {
|
|
57
57
|
url: 'https://github.com/holepunchto/bare-sidecar-swift',
|
|
58
|
-
from: '0.1.
|
|
58
|
+
from: '0.1.3',
|
|
59
59
|
products: ['BareSidecar']
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -70,7 +70,7 @@ import asyncio
|
|
|
70
70
|
from pathlib import Path
|
|
71
71
|
from typing import NamedTuple
|
|
72
72
|
|
|
73
|
-
${client ? 'from bare_rpc import RPC\n' : ''}from bare_sidecar import spawn
|
|
73
|
+
${client ? 'from bare_rpc import RPC\n' : ''}from bare_sidecar import Sidecar, spawn
|
|
74
74
|
from bare_stow_host import DEFAULT_GRACE, IPC, wrap
|
|
75
75
|
${client ? `\nfrom ${client} import Handlers, attach\n` : ''}
|
|
76
76
|
bundle = Path(__file__).parent / ${JSON.stringify(bundle)}
|
|
@@ -90,6 +90,15 @@ async def start(
|
|
|
90
90
|
) -> Started:
|
|
91
91
|
sidecar = await spawn(bundle, **opts)
|
|
92
92
|
|
|
93
|
+
return await connect(sidecar, timeout=timeout, grace=grace${client ? ', handlers=handlers' : ''})
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
async def connect(
|
|
97
|
+
sidecar: Sidecar,
|
|
98
|
+
*,
|
|
99
|
+
timeout=None,
|
|
100
|
+
grace=DEFAULT_GRACE,${client ? '\n handlers: Handlers = lambda router: None,' : ''}
|
|
101
|
+
) -> Started:
|
|
93
102
|
ipc = wrap(sidecar, kill=sidecar.kill, timeout=timeout, grace=grace)
|
|
94
103
|
|
|
95
104
|
watching = asyncio.ensure_future(_watch(sidecar, ipc))
|
|
@@ -23,9 +23,9 @@ exports.languages = {
|
|
|
23
23
|
name: 'bare-worker',
|
|
24
24
|
version: '^4.5.3',
|
|
25
25
|
binding: 'Worker',
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
handle: 'worker',
|
|
27
|
+
spawn: 'new Worker(bundle, opts)',
|
|
28
|
+
connect: `\
|
|
29
29
|
const ipc = stow.wrap(worker.IPC, { kill: () => worker.terminate(), timeout, grace })
|
|
30
30
|
|
|
31
31
|
worker.IPC.on('end', () => worker.IPC.destroy())
|
package/lib/target/javascript.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
module.exports = function harness(context, target) {
|
|
2
2
|
const { bundle, client, options } = context
|
|
3
|
-
const { name, version, binding, url = false,
|
|
3
|
+
const { name, version, binding, url = false, handle, spawn, connect, types } = target
|
|
4
4
|
|
|
5
5
|
const esm = options.module === 'esm'
|
|
6
6
|
|
|
7
|
+
const params = `{ timeout, grace${client ? ', handlers = () => {}' : ''} } = {}`
|
|
8
|
+
|
|
9
|
+
const start = `\
|
|
10
|
+
const ${handle} = ${spawn}
|
|
11
|
+
|
|
12
|
+
return await connect(${handle}, { timeout, grace${client ? ', handlers' : ''} })`
|
|
13
|
+
|
|
7
14
|
const body = `\
|
|
8
|
-
${
|
|
15
|
+
${connect}
|
|
9
16
|
${client ? '\nconst rpc = client.attach(ipc, handlers)\n' : ''}
|
|
10
17
|
await ipc.ready
|
|
11
18
|
|
|
@@ -18,7 +25,11 @@ import stow from 'bare-stow-host'
|
|
|
18
25
|
${client ? `import * as client from ${JSON.stringify(client)}\n` : ''}
|
|
19
26
|
const bundle = ${url ? `new URL(import.meta.resolve(${JSON.stringify(bundle)}))` : `import.meta.resolve(${JSON.stringify(bundle)})`}
|
|
20
27
|
|
|
21
|
-
export async function start({ timeout, grace, ${client ? 'handlers
|
|
28
|
+
export async function start({ timeout, grace, ${client ? 'handlers, ' : ''}...opts } = {}) {
|
|
29
|
+
${indent(start, 2)}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function connect(${handle}, ${params}) {
|
|
22
33
|
${indent(body, 2)}
|
|
23
34
|
}
|
|
24
35
|
`
|
|
@@ -28,14 +39,18 @@ const stow = require('bare-stow-host')
|
|
|
28
39
|
${client ? `const client = require(${JSON.stringify(client)})\n` : ''}
|
|
29
40
|
const bundle = require.resolve(${JSON.stringify(bundle)})
|
|
30
41
|
|
|
31
|
-
module.exports = {
|
|
32
|
-
|
|
33
|
-
${
|
|
34
|
-
|
|
42
|
+
module.exports = { start, connect }
|
|
43
|
+
|
|
44
|
+
async function start({ timeout, grace, ${client ? 'handlers, ' : ''}...opts } = {}) {
|
|
45
|
+
${indent(start, 2)}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function connect(${handle}, ${params}) {
|
|
49
|
+
${indent(body, 2)}
|
|
35
50
|
}
|
|
36
51
|
`
|
|
37
52
|
|
|
38
|
-
const
|
|
53
|
+
const started = client
|
|
39
54
|
? `{ ipc: import('bare-stow-host').IPC; rpc: ReturnType<typeof import(${JSON.stringify(client)}).attach> }`
|
|
40
55
|
: `{ ipc: import('bare-stow-host').IPC }`
|
|
41
56
|
|
|
@@ -46,9 +61,11 @@ ${indent(body, 4)}
|
|
|
46
61
|
'bare-stow-host': '^0.2.0'
|
|
47
62
|
},
|
|
48
63
|
types: `\
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
): Promise<${
|
|
64
|
+
type ConnectOptions = Omit<import('bare-stow-host').IPCOptions, 'kill'>${client ? ` & { handlers?: import(${JSON.stringify(client)}).Handlers }` : ''}
|
|
65
|
+
|
|
66
|
+
export function start(opts?: ${types} & ConnectOptions): Promise<${started}>
|
|
67
|
+
|
|
68
|
+
export function connect(${handle}: import('${name}'), opts?: ConnectOptions): Promise<${started}>
|
|
52
69
|
`
|
|
53
70
|
}
|
|
54
71
|
}
|
package/lib/target/swift.js
CHANGED
|
@@ -2,12 +2,59 @@
|
|
|
2
2
|
// an `IPC` of their own.
|
|
3
3
|
module.exports = function harness(context, target) {
|
|
4
4
|
const { bundle, client } = context
|
|
5
|
-
const {
|
|
5
|
+
const {
|
|
6
|
+
module,
|
|
7
|
+
conformance,
|
|
8
|
+
fields = {},
|
|
9
|
+
params = [],
|
|
10
|
+
handle,
|
|
11
|
+
spawn,
|
|
12
|
+
setup,
|
|
13
|
+
dependencies
|
|
14
|
+
} = target
|
|
6
15
|
|
|
7
16
|
const started = { ...fields, ipc: 'BareStowHost.IPC' }
|
|
8
17
|
|
|
9
18
|
if (client) started.rpc = 'RPC'
|
|
10
19
|
|
|
20
|
+
const options = [
|
|
21
|
+
'timeout: TimeInterval? = nil',
|
|
22
|
+
'grace: TimeInterval = BareStowHost.IPC.defaultGrace',
|
|
23
|
+
...(client ? ['handlers: Handlers? = nil'] : [])
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
const forwarded = ['timeout', 'grace', ...(client ? ['handlers'] : [])].map(
|
|
27
|
+
(name) => `${name}: ${name}`
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const body = `\
|
|
31
|
+
${setup}
|
|
32
|
+
${client ? '\nlet rpc = attach(ipc, handlers)\n' : ''}
|
|
33
|
+
try await ipc.ready()
|
|
34
|
+
|
|
35
|
+
return Started(${Object.keys(started)
|
|
36
|
+
.map((name) => `${name}: ${name}`)
|
|
37
|
+
.join(', ')})`
|
|
38
|
+
|
|
39
|
+
const resource = `let bundle = Bundle.module.url(forResource: ${JSON.stringify(bundle)}, withExtension: nil)!`
|
|
40
|
+
|
|
41
|
+
// Targets that spawn the bundle let hosts connect to one they spawned, such
|
|
42
|
+
// as from another entry.
|
|
43
|
+
const start = handle
|
|
44
|
+
? `\
|
|
45
|
+
${resource}
|
|
46
|
+
|
|
47
|
+
let ${handle.name} = ${spawn}
|
|
48
|
+
|
|
49
|
+
return try await connect(${[handle.name, ...forwarded].join(', ')})`
|
|
50
|
+
: `${resource}\n\n${body}`
|
|
51
|
+
|
|
52
|
+
const functions = [func('start', [...params, ...options], start)]
|
|
53
|
+
|
|
54
|
+
if (handle) {
|
|
55
|
+
functions.push(func('connect', [`_ ${handle.name}: ${handle.type}`, ...options], body))
|
|
56
|
+
}
|
|
57
|
+
|
|
11
58
|
const source = `\
|
|
12
59
|
import ${module}
|
|
13
60
|
${client ? 'import BareRPC\n' : ''}import BareStowHost
|
|
@@ -21,26 +68,7 @@ ${Object.entries(started)
|
|
|
21
68
|
.join('\n')}
|
|
22
69
|
}
|
|
23
70
|
|
|
24
|
-
|
|
25
|
-
${[
|
|
26
|
-
...params,
|
|
27
|
-
'timeout: TimeInterval? = nil',
|
|
28
|
-
'grace: TimeInterval = BareStowHost.IPC.defaultGrace',
|
|
29
|
-
...(client ? ['handlers: Handlers? = nil'] : [])
|
|
30
|
-
]
|
|
31
|
-
.map((param) => ' ' + param)
|
|
32
|
-
.join(',\n')}
|
|
33
|
-
) async throws -> Started {
|
|
34
|
-
let bundle = Bundle.module.url(forResource: ${JSON.stringify(bundle)}, withExtension: nil)!
|
|
35
|
-
|
|
36
|
-
${setup.replace(/^(?=.)/gm, ' ')}
|
|
37
|
-
${client ? '\n let rpc = attach(ipc, handlers)\n' : ''}
|
|
38
|
-
try await ipc.ready()
|
|
39
|
-
|
|
40
|
-
return Started(${Object.keys(started)
|
|
41
|
-
.map((name) => `${name}: ${name}`)
|
|
42
|
-
.join(', ')})
|
|
43
|
-
}
|
|
71
|
+
${functions.join('\n\n')}
|
|
44
72
|
`
|
|
45
73
|
|
|
46
74
|
return {
|
|
@@ -55,3 +83,19 @@ ${client ? '\n let rpc = attach(ipc, handlers)\n' : ''}
|
|
|
55
83
|
}
|
|
56
84
|
}
|
|
57
85
|
}
|
|
86
|
+
|
|
87
|
+
function func(name, params, body) {
|
|
88
|
+
return `\
|
|
89
|
+
public func ${name}(
|
|
90
|
+
${params.map((param) => ' ' + param).join(',\n')}
|
|
91
|
+
) async throws -> Started {
|
|
92
|
+
${indent(body)}
|
|
93
|
+
}`
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function indent(source) {
|
|
97
|
+
return source
|
|
98
|
+
.split('\n')
|
|
99
|
+
.map((line) => (line.length === 0 ? line : ' ' + line))
|
|
100
|
+
.join('\n')
|
|
101
|
+
}
|