Skip to content

Commit cda0389

Browse files
committed
Add simulator command to CLI
1 parent 1b44853 commit cda0389

File tree

2 files changed

+77
-22
lines changed

2 files changed

+77
-22
lines changed

bin.js

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ const p = require('path')
33
const os = require('os')
44
const fs = require('fs').promises
55
const repl = require('repl')
6-
const { Server, Client } = require('./')
6+
const { spawn } = require('child_process')
77
const minimist = require('minimist')
8+
const ram = require('random-access-memory')
9+
10+
const { Server, Client } = require('./')
811
const { migrate: migrateFromDaemon, isMigrated } = require('@hyperspace/migration-tool')
12+
const getNetworkOptions = require('@hyperspace/rpc/socket')
913

1014
// TODO: Default paths are duplicated here because we need to do the async migration check.
1115
const HYPERSPACE_STORAGE_DIR = p.join(os.homedir(), '.hyperspace', 'storage')
@@ -30,16 +34,19 @@ const version = `hyperspace/${require('./package.json').version} ${process.platf
3034
const help = `Hypercore, batteries included.
3135
${version}
3236
33-
Usage: hyperspace [options]
34-
35-
--host, -h Set unix socket name
36-
--port -p Set the port (will use TCP)
37-
--storage, -s Overwrite storage folder
38-
--bootstrap, -b Overwrite DHT bootstrap servers
39-
--memory-only Run all storage in memory
40-
--no-announce Disable all network annoucnes
41-
--repl Run a debug repl
42-
--no-migrate Disable the Hyperdrive Daemon migration
37+
Usage: hyperspace [command] [options]
38+
Commands:
39+
simulator <script.js> Run script.js using an in-memory Hyperspace instance
40+
41+
Flags:
42+
--host, -h Set unix socket name
43+
--port -p Set the port (will use TCP)
44+
--storage, -s Overwrite storage folder
45+
--bootstrap, -b Overwrite DHT bootstrap servers
46+
--memory-only Run all storage in memory
47+
--no-announce Disable all network annoucnes
48+
--repl Run a debug repl
49+
--no-migrate Disable the Hyperdrive Daemon migration
4350
`
4451

4552
if (argv.help) {
@@ -50,6 +57,10 @@ if (argv.help) {
5057
main().catch(onerror)
5158

5259
async function main () {
60+
if (argv._[0] === 'simulator') {
61+
return simulator()
62+
}
63+
5364
console.log('Running ' + version)
5465

5566
// Note: This will be removed in future releases of Hyperspace.
@@ -68,15 +79,7 @@ async function main () {
6879
// Else, use ~/.hyperspace/storage
6980
const storage = argv.storage ? argv.storage : await getStoragePath()
7081

71-
const s = new Server({
72-
host: argv.host,
73-
port: argv.port,
74-
storage,
75-
network: argv.bootstrap ? { bootstrap: [].concat(argv.bootstrap) } : null,
76-
memoryOnly: argv['memory-only'],
77-
noAnnounce: !argv.announce,
78-
noMigrate: !argv.migrate
79-
})
82+
const s = createServer(storage, argv)
8083
global.hyperspace = s
8184

8285
if (!argv.repl) {
@@ -133,6 +136,58 @@ async function main () {
133136
}
134137
}
135138

139+
function createServer (storage, opts) {
140+
return new Server({
141+
host: opts.host,
142+
port: opts.port,
143+
storage,
144+
network: opts.bootstrap ? { bootstrap: [].concat(opts.bootstrap) } : null,
145+
noAnnounce: !opts.announce,
146+
noMigrate: !opts.migrate
147+
})
148+
}
149+
150+
async function simulator () {
151+
if (argv._.length === 1) throw new Error('Must provide a script for the simulator to run.')
152+
const scriptPath = p.resolve(argv._[1])
153+
const simulatorId = await getUnusedSocket()
154+
process.env['HYPERSPACE_HOST'] = simulatorId
155+
156+
const server = createServer(ram, {
157+
...argv,
158+
host: simulatorId
159+
})
160+
await server.open()
161+
162+
process.once('SIGINT', close)
163+
process.once('SIGTERM', close)
164+
165+
const child = spawn(process.execPath, [scriptPath], {
166+
env: {
167+
'HYPERSPACE_HOST': simulatorId
168+
},
169+
stdio: 'inherit'
170+
})
171+
child.on('close', close)
172+
173+
async function close () {
174+
console.log('Shutting down simulator...')
175+
server.close().catch(onerror)
176+
}
177+
178+
async function getUnusedSocket () {
179+
const host = `hyperspace-simulator-${(Math.floor(Math.random() * 1e9)).toString(16)}`
180+
const socketPath = getNetworkOptions({ host })
181+
try {
182+
await fs.stat(socketPath)
183+
return getUnusedSocket()
184+
} catch (err) {
185+
if (err.code !== 'ENOENT') throw err
186+
return host
187+
}
188+
}
189+
}
190+
136191
async function getStoragePath () {
137192
try {
138193
// If this dir exists, use it.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@
4040
"hypertrie": "^5.1.1",
4141
"inspect-custom-symbol": "^1.1.1",
4242
"minimist": "^1.2.5",
43-
"nanoresource-promise": "^1.2.2"
43+
"nanoresource-promise": "^1.2.2",
44+
"random-access-memory": "^3.1.1"
4445
},
4546
"devDependencies": {
4647
"@hyperswarm/dht": "^4.0.1",
4748
"compare": "^2.0.0",
4849
"hypercore-byte-stream": "^1.0.12",
4950
"hyperdrive": "^10.17.2",
5051
"protocol-buffers": "^4.2.0",
51-
"random-access-memory": "^3.1.1",
5252
"standard": "^14.3.4",
5353
"stream-collector": "^1.0.1",
5454
"tape": "^5.0.1",

0 commit comments

Comments
 (0)