bare-stow 0.1.9 → 0.3.0
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 +92 -111
- package/bin.js +142 -53
- package/index.d.ts +318 -82
- package/index.js +163 -207
- package/lib/assets.js +54 -0
- package/lib/fs.js +2 -4
- package/lib/graph.js +94 -0
- package/lib/language/javascript.js +74 -0
- package/lib/language/kotlin.js +139 -0
- package/lib/language/python.js +65 -0
- package/lib/language/swift.js +111 -0
- package/lib/language.js +18 -0
- package/lib/link.js +149 -0
- package/lib/provider.js +33 -0
- package/lib/rpc/bare-rpc.js +147 -15
- package/lib/rpc.js +6 -18
- package/lib/shim.js +24 -31
- package/lib/target/bare-kit.js +238 -0
- package/lib/target/bare-sidecar.js +86 -53
- package/lib/target/bare-worker.js +18 -72
- package/lib/target/javascript.js +63 -0
- package/lib/target/swift.js +57 -0
- package/lib/target.js +43 -12
- package/package.json +20 -36
- package/lib/host.d.ts +0 -64
- package/lib/host.js +0 -114
- package/lib/protocol.d.ts +0 -46
- package/lib/protocol.js +0 -139
- package/lib/runtime.d.ts +0 -29
- package/lib/runtime.js +0 -92
package/lib/rpc/bare-rpc.js
CHANGED
|
@@ -1,24 +1,156 @@
|
|
|
1
1
|
exports.name = 'bare-rpc'
|
|
2
2
|
|
|
3
|
-
exports.
|
|
4
|
-
|
|
3
|
+
exports.languages = {
|
|
4
|
+
javascript: { generate: javascript },
|
|
5
|
+
kotlin: { generate: kotlin },
|
|
6
|
+
python: { generate: python },
|
|
7
|
+
swift: { generate: swift }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function kotlin({ options }) {
|
|
11
|
+
const source = `\
|
|
12
|
+
package ${options.package}
|
|
13
|
+
|
|
14
|
+
import kotlinx.coroutines.CoroutineScope
|
|
15
|
+
import kotlinx.coroutines.Dispatchers
|
|
16
|
+
import to.holepunch.bare.rpc.CommandRouter
|
|
17
|
+
import to.holepunch.bare.rpc.Rpc
|
|
18
|
+
import to.holepunch.bare.rpc.Transport
|
|
19
|
+
import to.holepunch.bare.stow.host.Ipc
|
|
20
|
+
|
|
21
|
+
typealias Handlers = CommandRouter.() -> Unit
|
|
22
|
+
|
|
23
|
+
internal fun attach(ipc: Ipc, handlers: Handlers): Rpc {
|
|
24
|
+
val router = CommandRouter().apply(handlers)
|
|
25
|
+
|
|
26
|
+
return Rpc(
|
|
27
|
+
Transport(ipc.data, ipc::write, ipc::close),
|
|
28
|
+
CoroutineScope(Dispatchers.Default),
|
|
29
|
+
router,
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
`
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
source,
|
|
36
|
+
dependencies: {
|
|
37
|
+
'com.github.holepunchto.bare-rpc-kotlin:bare-rpc-kotlin': 'v0.5.0',
|
|
38
|
+
'com.github.holepunchto.bare-stow-host-kotlin:bare-stow-host-kotlin': 'v0.2.1'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function swift() {
|
|
44
|
+
const source = `\
|
|
45
|
+
import BareRPC
|
|
46
|
+
import BareStowHost
|
|
47
|
+
import Foundation
|
|
5
48
|
|
|
6
|
-
|
|
49
|
+
public typealias Handlers = (CommandRouter) -> Void
|
|
7
50
|
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
source: `\
|
|
11
|
-
${esm ? "const { default: RPC } = await import('bare-rpc')" : "const RPC = require('bare-rpc')"}
|
|
51
|
+
extension BareStowHost.IPC: @retroactive BareRPC.Transport {}
|
|
12
52
|
|
|
13
|
-
|
|
14
|
-
|
|
53
|
+
func attach(_ ipc: IPC, _ handlers: Handlers?) -> RPC {
|
|
54
|
+
let router = CommandRouter()
|
|
15
55
|
|
|
16
|
-
|
|
56
|
+
handlers?(router)
|
|
57
|
+
|
|
58
|
+
return RPC(ipc, handler: router)
|
|
59
|
+
}
|
|
17
60
|
`
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
source,
|
|
64
|
+
dependencies: {
|
|
65
|
+
'bare-rpc-swift': {
|
|
66
|
+
url: 'https://github.com/holepunchto/bare-rpc-swift',
|
|
67
|
+
from: '2.0.0',
|
|
68
|
+
products: ['BareRPC']
|
|
69
|
+
},
|
|
70
|
+
'bare-stow-host-swift': {
|
|
71
|
+
url: 'https://github.com/holepunchto/bare-stow-host-swift',
|
|
72
|
+
from: '0.2.0',
|
|
73
|
+
products: ['BareStowHost']
|
|
74
|
+
}
|
|
22
75
|
}
|
|
23
|
-
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function python() {
|
|
80
|
+
const source = `\
|
|
81
|
+
from collections.abc import Callable
|
|
82
|
+
|
|
83
|
+
from bare_rpc import RPC, CommandRouter
|
|
84
|
+
from bare_stow_host import IPC
|
|
85
|
+
|
|
86
|
+
Handlers = Callable[[CommandRouter], None]
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def attach(ipc: IPC, handlers: Handlers) -> RPC:
|
|
90
|
+
router = CommandRouter()
|
|
91
|
+
|
|
92
|
+
handlers(router)
|
|
93
|
+
|
|
94
|
+
return RPC(ipc, handler=router)
|
|
95
|
+
`
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
source,
|
|
99
|
+
dependencies: {
|
|
100
|
+
'bare-rpc': '~=0.2.0',
|
|
101
|
+
'bare-stow-host': '~=0.2.0'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function javascript({ role, options }) {
|
|
107
|
+
const esm = options.module === 'esm'
|
|
108
|
+
|
|
109
|
+
// The bundle registers its handlers in `start()`, before it signals ready.
|
|
110
|
+
const server = role === 'server'
|
|
111
|
+
|
|
112
|
+
const params = server ? 'ipc' : 'ipc, handlers'
|
|
113
|
+
|
|
114
|
+
const body = server
|
|
115
|
+
? `\
|
|
116
|
+
const router = new RPC.CommandRouter()
|
|
117
|
+
const rpc = new RPC(ipc, router)
|
|
118
|
+
|
|
119
|
+
rpc.respond = router.respond.bind(router)
|
|
120
|
+
|
|
121
|
+
return rpc
|
|
122
|
+
}
|
|
123
|
+
`
|
|
124
|
+
: `\
|
|
125
|
+
const router = new RPC.CommandRouter()
|
|
126
|
+
|
|
127
|
+
handlers(router)
|
|
128
|
+
|
|
129
|
+
return new RPC(ipc, router)
|
|
130
|
+
}
|
|
131
|
+
`
|
|
132
|
+
|
|
133
|
+
const source = esm
|
|
134
|
+
? `\
|
|
135
|
+
import RPC from 'bare-rpc'
|
|
136
|
+
|
|
137
|
+
export function attach(${params}) {
|
|
138
|
+
${body}`
|
|
139
|
+
: `\
|
|
140
|
+
const RPC = require('bare-rpc')
|
|
141
|
+
|
|
142
|
+
exports.attach = function attach(${params}) {
|
|
143
|
+
${body}`
|
|
144
|
+
|
|
145
|
+
const types = server
|
|
146
|
+
? `\
|
|
147
|
+
export function attach(ipc: import('bare-stow-host').IPC): import('bare-rpc')
|
|
148
|
+
`
|
|
149
|
+
: `\
|
|
150
|
+
export type Handlers = (router: import('bare-rpc').CommandRouter) => void
|
|
151
|
+
|
|
152
|
+
export function attach(ipc: import('bare-stow-host').IPC, handlers: Handlers): import('bare-rpc')
|
|
153
|
+
`
|
|
154
|
+
|
|
155
|
+
return { source, types, dependencies: { 'bare-rpc': '^1.5.0' } }
|
|
24
156
|
}
|
package/lib/rpc.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
const registry =
|
|
2
|
-
'bare-rpc': () => require('./rpc/bare-rpc')
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
module.exports = function rpc(name, resolve) {
|
|
6
|
-
if (typeof name !== 'string') return validate(name)
|
|
7
|
-
|
|
8
|
-
const load = registry[name]
|
|
1
|
+
const { registry, validateLanguages } = require('./provider')
|
|
9
2
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (resolve) return validate(resolve(name))
|
|
13
|
-
|
|
14
|
-
throw new Error(`Unknown RPC library '${name}'`)
|
|
3
|
+
const providers = {
|
|
4
|
+
'bare-rpc': () => require('./rpc/bare-rpc')
|
|
15
5
|
}
|
|
16
6
|
|
|
17
|
-
function validate(rpc) {
|
|
18
|
-
|
|
19
|
-
throw new Error('RPC library must provide a generate() function')
|
|
20
|
-
}
|
|
7
|
+
module.exports = registry('RPC library', providers, function validate(rpc) {
|
|
8
|
+
validateLanguages('RPC library', rpc?.languages)
|
|
21
9
|
|
|
22
10
|
return rpc
|
|
23
|
-
}
|
|
11
|
+
})
|
package/lib/shim.js
CHANGED
|
@@ -1,40 +1,33 @@
|
|
|
1
|
-
const
|
|
2
|
-
const {
|
|
1
|
+
const javascript = require('./language/javascript')
|
|
2
|
+
const { select } = require('./provider')
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// decides where the fragment goes.
|
|
8
|
-
const { server = null } = opts
|
|
4
|
+
// The bundle runs in Bare, so its side of every provider is JavaScript.
|
|
5
|
+
module.exports = function shim(entry, isolation, server = null) {
|
|
6
|
+
if (server) server = select('RPC library', server, javascript.name)
|
|
9
7
|
|
|
10
|
-
const
|
|
8
|
+
const dir = new URL('./', entry)
|
|
9
|
+
const url = new URL('__main__.mjs', dir)
|
|
10
|
+
const serverURL = server ? new URL('__server__.mjs', dir) : null
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const modules = new Map()
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (server) {
|
|
15
|
+
modules.set(
|
|
16
|
+
serverURL.href,
|
|
17
|
+
server.generate({ role: 'server', options: { module: 'esm' } }).source
|
|
18
|
+
)
|
|
19
|
+
}
|
|
16
20
|
|
|
21
|
+
modules.set(
|
|
22
|
+
url.href,
|
|
23
|
+
`\
|
|
24
|
+
import runtime from '${isolation === 'process' ? 'bare-stow-runtime/process' : 'bare-stow-runtime'}'
|
|
25
|
+
${server ? `import * as server from ${JSON.stringify(javascript.reference(url, serverURL))}\n` : ''}
|
|
17
26
|
const ipc = runtime.attach(Bare.IPC)
|
|
18
|
-
${server ? '\
|
|
19
|
-
ipc.run(() => import(${JSON.stringify(
|
|
27
|
+
${server ? '\nconst rpc = server.attach(ipc)\n' : ''}
|
|
28
|
+
ipc.run(() => import(${JSON.stringify(javascript.reference(url, entry))}), ${server ? '{ rpc, ipc }' : 'ipc'})
|
|
20
29
|
`
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
exports.url = function url(base) {
|
|
24
|
-
return new URL('__main__.mjs', base)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function relativeSpecifier(from, to) {
|
|
28
|
-
if (from.protocol === 'file:' && to.protocol === 'file:') {
|
|
29
|
-
const fromPath = path.dirname(fileURLToPath(from))
|
|
30
|
-
const toPath = fileURLToPath(to)
|
|
31
|
-
|
|
32
|
-
let relative = path.relative(fromPath, toPath).split(path.sep).join('/')
|
|
33
|
-
|
|
34
|
-
if (!relative.startsWith('.')) relative = './' + relative
|
|
35
|
-
|
|
36
|
-
return relative
|
|
37
|
-
}
|
|
30
|
+
)
|
|
38
31
|
|
|
39
|
-
return
|
|
32
|
+
return { url, modules }
|
|
40
33
|
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const swift = require('./swift')
|
|
3
|
+
|
|
4
|
+
exports.name = 'bare-kit'
|
|
5
|
+
exports.isolation = 'thread'
|
|
6
|
+
exports.linked = (context) => !isJvm(context)
|
|
7
|
+
exports.linking = linking
|
|
8
|
+
exports.offload = isJvm
|
|
9
|
+
exports.format = 'bundle'
|
|
10
|
+
exports.encoding = null
|
|
11
|
+
exports.extension = '.bundle'
|
|
12
|
+
exports.hosts = (context) => (isJvm(context) ? desktop : hosts[context.language])
|
|
13
|
+
|
|
14
|
+
// On the JVM, the harness extracts the bundle from the resources of its module,
|
|
15
|
+
// so the addons and assets of the bundle are offloaded beside it rather than
|
|
16
|
+
// linked.
|
|
17
|
+
function isJvm({ language, options }) {
|
|
18
|
+
return language === 'kotlin' && options.platform === 'jvm'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function linking(context) {
|
|
22
|
+
const { targetOptions } = context
|
|
23
|
+
|
|
24
|
+
if (isJvm(context) && targetOptions.linking === 'app') {
|
|
25
|
+
throw new Error("Option 'linking' must be 'package' for the JVM")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return targetOptions.linking
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Applications with several bundles link their addons once with `link()`.
|
|
32
|
+
exports.options = function options(given = {}) {
|
|
33
|
+
const { linking = 'package', ...unknown } = given
|
|
34
|
+
|
|
35
|
+
for (const option of Object.keys(unknown)) {
|
|
36
|
+
throw new Error(`Unknown option '${option}' for target 'bare-kit'`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (linking !== 'package' && linking !== 'app') {
|
|
40
|
+
throw new Error(`Option 'linking' must be 'package' or 'app', got '${linking}'`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { linking }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const bareKitSwift = {
|
|
47
|
+
url: 'https://github.com/holepunchto/bare-kit-swift',
|
|
48
|
+
from: '2.2.0',
|
|
49
|
+
products: ['BareKit']
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const bareKitKotlin = {
|
|
53
|
+
'com.github.holepunchto.bare-kit-kotlin:bare-kit-kotlin': 'v0.2.2'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const desktop = [
|
|
57
|
+
'darwin-arm64',
|
|
58
|
+
'darwin-x64',
|
|
59
|
+
'linux-arm64',
|
|
60
|
+
'linux-x64',
|
|
61
|
+
'win32-arm64',
|
|
62
|
+
'win32-x64'
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
const hosts = {
|
|
66
|
+
kotlin: ['android-arm64', 'android-arm', 'android-x64', 'android-ia32'],
|
|
67
|
+
swift: ['darwin-arm64', 'darwin-x64', 'ios-arm64', 'ios-arm64-simulator', 'ios-x64-simulator']
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exports.languages = {
|
|
71
|
+
kotlin: {
|
|
72
|
+
generate: kotlin,
|
|
73
|
+
link() {
|
|
74
|
+
return { source: null, dependencies: bareKitKotlin }
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
swift: {
|
|
78
|
+
// Re-exports Bare Kit, so that code linking the module can run worklets.
|
|
79
|
+
link() {
|
|
80
|
+
return {
|
|
81
|
+
source: '@_exported import BareKit\n',
|
|
82
|
+
dependencies: { 'bare-kit-swift': bareKitSwift }
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
generate(context) {
|
|
86
|
+
const start = context.resources
|
|
87
|
+
? `try worklet.start(${JSON.stringify(context.resources + '.bundle')}, source: Data(contentsOf: bundle))`
|
|
88
|
+
: 'try worklet.start(bundle)'
|
|
89
|
+
|
|
90
|
+
return swift(context, {
|
|
91
|
+
module: 'BareKit',
|
|
92
|
+
conformance: 'extension BareKit.IPC: @retroactive BareStowHost.Transport {}',
|
|
93
|
+
fields: { worklet: 'Worklet' },
|
|
94
|
+
params: ['options: Worklet.Options = Worklet.Options()'],
|
|
95
|
+
setup: `\
|
|
96
|
+
let worklet = try Worklet(options: options)
|
|
97
|
+
|
|
98
|
+
let transport = try BareKit.IPC(worklet: worklet)
|
|
99
|
+
|
|
100
|
+
${start}
|
|
101
|
+
|
|
102
|
+
let ipc = BareStowHost.IPC(
|
|
103
|
+
transport, kill: { worklet.terminate() }, timeout: timeout, grace: grace)
|
|
104
|
+
|
|
105
|
+
Task { ipc.exited(code: await worklet.wait()) }`,
|
|
106
|
+
dependencies: { 'bare-kit-swift': bareKitSwift }
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function kotlin(context) {
|
|
113
|
+
const { client, options } = context
|
|
114
|
+
|
|
115
|
+
const platform = options.platform === 'jvm' ? jvm(context) : android(context)
|
|
116
|
+
|
|
117
|
+
const imports = [
|
|
118
|
+
...platform.imports,
|
|
119
|
+
'kotlin.time.Duration',
|
|
120
|
+
'kotlinx.coroutines.CoroutineScope',
|
|
121
|
+
'kotlinx.coroutines.Dispatchers',
|
|
122
|
+
'kotlinx.coroutines.launch',
|
|
123
|
+
'to.holepunch.bare.kit.Ipc as WorkletIpc',
|
|
124
|
+
'to.holepunch.bare.kit.Worklet',
|
|
125
|
+
'to.holepunch.bare.stow.host.Ipc',
|
|
126
|
+
...(client ? ['to.holepunch.bare.rpc.Rpc'] : [])
|
|
127
|
+
].sort()
|
|
128
|
+
|
|
129
|
+
const source = `\
|
|
130
|
+
package ${options.package}
|
|
131
|
+
|
|
132
|
+
${imports.map((name) => 'import ' + name).join('\n')}
|
|
133
|
+
|
|
134
|
+
class Started(val worklet: Worklet, val ipc: Ipc${client ? ', val rpc: Rpc' : ''})
|
|
135
|
+
${platform.declarations}
|
|
136
|
+
suspend fun start(
|
|
137
|
+
${platform.params}\
|
|
138
|
+
options: Worklet.Options = Worklet.Options(),
|
|
139
|
+
timeout: Duration? = null,
|
|
140
|
+
grace: Duration = Ipc.DEFAULT_GRACE,${client ? '\n handlers: Handlers = {},' : ''}
|
|
141
|
+
): Started {
|
|
142
|
+
val worklet = ${platform.worklet}
|
|
143
|
+
|
|
144
|
+
val transport =
|
|
145
|
+
try {
|
|
146
|
+
WorkletIpc(worklet)
|
|
147
|
+
} catch (error: Throwable) {
|
|
148
|
+
worklet.close()
|
|
149
|
+
throw error
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
${platform.start}
|
|
154
|
+
} catch (error: Throwable) {
|
|
155
|
+
transport.close()
|
|
156
|
+
worklet.close()
|
|
157
|
+
throw error
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
val ipc =
|
|
161
|
+
Ipc(
|
|
162
|
+
transport.data,
|
|
163
|
+
transport::write,
|
|
164
|
+
kill = { worklet.terminate() },
|
|
165
|
+
timeout = timeout,
|
|
166
|
+
grace = grace,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
CoroutineScope(Dispatchers.Default).launch {
|
|
170
|
+
ipc.exited(worklet.wait())
|
|
171
|
+
|
|
172
|
+
transport.close()
|
|
173
|
+
worklet.close()
|
|
174
|
+
}
|
|
175
|
+
${client ? '\n val rpc = attach(ipc, handlers)\n' : ''}
|
|
176
|
+
ipc.ready()
|
|
177
|
+
|
|
178
|
+
return Started(worklet, ipc${client ? ', rpc' : ''})
|
|
179
|
+
}
|
|
180
|
+
`
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
source,
|
|
184
|
+
dependencies: {
|
|
185
|
+
...bareKitKotlin,
|
|
186
|
+
'com.github.holepunchto.bare-stow-host-kotlin:bare-stow-host-kotlin': 'v0.2.1'
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function android({ bundle, resources }) {
|
|
192
|
+
return {
|
|
193
|
+
imports: ['android.content.Context'],
|
|
194
|
+
declarations: '',
|
|
195
|
+
params: ' context: Context,\n',
|
|
196
|
+
worklet: 'Worklet(context, options)',
|
|
197
|
+
start: resources
|
|
198
|
+
? `worklet.start(${JSON.stringify(resources + '.bundle')}, context.assets.open(${JSON.stringify(bundle)}).use { it.readBytes() })`
|
|
199
|
+
: `worklet.start(${JSON.stringify(bundle)})`
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// The bundle and the files listed beside it are extracted once per process, to
|
|
204
|
+
// a directory of its own that is removed on exit.
|
|
205
|
+
function jvm({ bundle }) {
|
|
206
|
+
const dir = path.posix.dirname(bundle)
|
|
207
|
+
const name = '/' + path.posix.basename(bundle)
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
imports: ['java.io.File', 'java.nio.file.Files', 'kotlinx.coroutines.withContext'],
|
|
211
|
+
declarations: `
|
|
212
|
+
private val bundle: File by lazy {
|
|
213
|
+
val dir = Files.createTempDirectory("bare-stow").toFile()
|
|
214
|
+
|
|
215
|
+
Runtime.getRuntime().addShutdownHook(Thread { dir.deleteRecursively() })
|
|
216
|
+
|
|
217
|
+
val loader = Started::class.java.classLoader
|
|
218
|
+
|
|
219
|
+
fun open(name: String) = loader.getResourceAsStream(${JSON.stringify(dir)} + name)!!
|
|
220
|
+
|
|
221
|
+
val listed = open(${JSON.stringify(name + '.files')}).bufferedReader().use { it.readLines() }
|
|
222
|
+
|
|
223
|
+
for (name in listOf(${JSON.stringify(name)}) + listed) {
|
|
224
|
+
val file = File(dir, name)
|
|
225
|
+
|
|
226
|
+
file.parentFile.mkdirs()
|
|
227
|
+
|
|
228
|
+
open(name).use { input -> file.outputStream().use { input.copyTo(it) } }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
File(dir, ${JSON.stringify(name)})
|
|
232
|
+
}
|
|
233
|
+
`,
|
|
234
|
+
params: '',
|
|
235
|
+
worklet: 'Worklet(options)',
|
|
236
|
+
start: 'worklet.start(withContext(Dispatchers.IO) { bundle }.path)'
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
const harness = require('./javascript')
|
|
2
|
+
const swift = require('./swift')
|
|
3
|
+
|
|
1
4
|
exports.name = 'bare-sidecar'
|
|
5
|
+
exports.isolation = 'process'
|
|
2
6
|
exports.linked = false
|
|
3
7
|
exports.offload = true
|
|
4
8
|
exports.format = 'bundle'
|
|
@@ -13,74 +17,103 @@ exports.hosts = [
|
|
|
13
17
|
'win32-x64'
|
|
14
18
|
]
|
|
15
19
|
|
|
16
|
-
exports.
|
|
17
|
-
|
|
20
|
+
exports.languages = {
|
|
21
|
+
javascript: {
|
|
22
|
+
generate(context) {
|
|
23
|
+
return harness(context, {
|
|
24
|
+
name: 'bare-sidecar',
|
|
25
|
+
version: '^0.5.15',
|
|
26
|
+
binding: 'Sidecar',
|
|
27
|
+
url: true,
|
|
28
|
+
setup: `\
|
|
29
|
+
const sidecar = new Sidecar(bundle, { stdio: 'inherit', ...opts })
|
|
30
|
+
|
|
31
|
+
const ipc = stow.wrap(sidecar, { kill: () => sidecar.kill('SIGKILL'), timeout, grace })
|
|
32
|
+
|
|
33
|
+
sidecar.on('exit', (code, signal) => ipc.exited(code, signal))`,
|
|
34
|
+
types: "import('bare-sidecar').SidecarOptions"
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
python: { generate: python },
|
|
39
|
+
swift: {
|
|
40
|
+
generate(context) {
|
|
41
|
+
return swift(context, {
|
|
42
|
+
module: 'BareSidecar',
|
|
43
|
+
conformance: 'extension Sidecar: @retroactive BareStowHost.Transport {}',
|
|
44
|
+
setup: `\
|
|
45
|
+
let sidecar = try await Sidecar.spawn(bundle)
|
|
46
|
+
|
|
47
|
+
let ipc = BareStowHost.IPC(sidecar, kill: { sidecar.kill() }, timeout: timeout, grace: grace)
|
|
48
|
+
|
|
49
|
+
Task {
|
|
50
|
+
switch await sidecar.wait() {
|
|
51
|
+
case .exit(let code): ipc.exited(code: code)
|
|
52
|
+
case .signal(let signal): ipc.exited(code: nil, signal: signal)
|
|
53
|
+
}
|
|
54
|
+
}`,
|
|
55
|
+
dependencies: {
|
|
56
|
+
'bare-sidecar-swift': {
|
|
57
|
+
url: 'https://github.com/holepunchto/bare-sidecar-swift',
|
|
58
|
+
from: '0.1.2',
|
|
59
|
+
products: ['BareSidecar']
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
18
66
|
|
|
19
|
-
|
|
67
|
+
function python({ bundle, client }) {
|
|
68
|
+
const source = `\
|
|
69
|
+
import asyncio
|
|
70
|
+
from pathlib import Path
|
|
71
|
+
from typing import NamedTuple
|
|
20
72
|
|
|
21
|
-
|
|
73
|
+
${client ? 'from bare_rpc import RPC\n' : ''}from bare_sidecar import spawn
|
|
74
|
+
from bare_stow_host import DEFAULT_GRACE, IPC, wrap
|
|
75
|
+
${client ? `\nfrom ${client} import Handlers, attach\n` : ''}
|
|
76
|
+
bundle = Path(__file__).parent / ${JSON.stringify(bundle)}
|
|
22
77
|
|
|
23
|
-
|
|
24
|
-
? `{ ${ipc}: import('bare-stow/host').IPC; ${rpc}: ${client.type} }`
|
|
25
|
-
: `{ ${ipc}: import('bare-stow/host').IPC }`
|
|
78
|
+
_watching = set()
|
|
26
79
|
|
|
27
|
-
const source = esm
|
|
28
|
-
? `\
|
|
29
|
-
import Sidecar from 'bare-sidecar'
|
|
30
|
-
import stow from 'bare-stow/host'
|
|
31
80
|
|
|
32
|
-
|
|
81
|
+
class Started(NamedTuple):
|
|
82
|
+
ipc: IPC${client ? '\n rpc: RPC' : ''}
|
|
33
83
|
|
|
34
|
-
export async function start({ timeout, grace, ...opts } = {}) {
|
|
35
|
-
const sidecar = new Sidecar(bundle, { stdio: 'inherit', ...opts })
|
|
36
84
|
|
|
37
|
-
|
|
85
|
+
async def start(
|
|
86
|
+
*,
|
|
87
|
+
timeout=None,
|
|
88
|
+
grace=DEFAULT_GRACE,${client ? '\n handlers: Handlers = lambda router: None,' : ''}
|
|
89
|
+
**opts,
|
|
90
|
+
) -> Started:
|
|
91
|
+
sidecar = await spawn(bundle, **opts)
|
|
38
92
|
|
|
39
|
-
|
|
40
|
-
${client ? '\n' + indent(client.source, 2) : ''}
|
|
41
|
-
await ${ipc}.ready
|
|
93
|
+
ipc = wrap(sidecar, kill=sidecar.kill, timeout=timeout, grace=grace)
|
|
42
94
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
:
|
|
47
|
-
|
|
48
|
-
const stow = require('bare-stow/host')
|
|
95
|
+
watching = asyncio.ensure_future(_watch(sidecar, ipc))
|
|
96
|
+
_watching.add(watching)
|
|
97
|
+
watching.add_done_callback(_watching.discard)
|
|
98
|
+
${client ? '\n rpc = attach(ipc, handlers)\n' : ''}
|
|
99
|
+
await ipc.ready
|
|
49
100
|
|
|
50
|
-
|
|
101
|
+
return Started(ipc${client ? ', rpc' : ''})
|
|
51
102
|
|
|
52
|
-
module.exports = {
|
|
53
|
-
async start({ timeout, grace, ...opts } = {}) {
|
|
54
|
-
const sidecar = new Sidecar(bundle, { stdio: 'inherit', ...opts })
|
|
55
103
|
|
|
56
|
-
|
|
104
|
+
async def _watch(sidecar, ipc):
|
|
105
|
+
await sidecar.wait()
|
|
57
106
|
|
|
58
|
-
|
|
59
|
-
${client ? '\n' + indent(client.source, 4) : ''}
|
|
60
|
-
await ${ipc}.ready
|
|
107
|
+
ipc.exited(sidecar.exit_code, sidecar.signal_code)
|
|
61
108
|
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
}
|
|
109
|
+
await sidecar.close()
|
|
65
110
|
`
|
|
66
111
|
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
export function start(
|
|
73
|
-
opts?: import('bare-sidecar').SidecarOptions & Omit<import('bare-stow/host').IPCOptions, 'kill'>
|
|
74
|
-
): Promise<${handle}>
|
|
75
|
-
`
|
|
112
|
+
return {
|
|
113
|
+
source,
|
|
114
|
+
dependencies: {
|
|
115
|
+
'bare-sidecar': '~=0.1.3',
|
|
116
|
+
'bare-stow-host': '~=0.2.0'
|
|
76
117
|
}
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function indent(source, spaces) {
|
|
81
|
-
const pad = ' '.repeat(spaces)
|
|
82
|
-
return source
|
|
83
|
-
.split('\n')
|
|
84
|
-
.map((line) => (line.length === 0 ? line : pad + line))
|
|
85
|
-
.join('\n')
|
|
118
|
+
}
|
|
86
119
|
}
|