@optimystic/reference-peer 0.0.1
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 +265 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +742 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mesh.d.ts +2 -0
- package/dist/src/mesh.d.ts.map +1 -0
- package/dist/src/mesh.js +114 -0
- package/dist/src/mesh.js.map +1 -0
- package/package.json +68 -0
- package/src/cli.ts +811 -0
- package/src/index.ts +1 -0
- package/src/mesh.ts +136 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './cli.js';
|
package/src/mesh.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { spawn } from 'child_process'
|
|
2
|
+
import * as fs from 'fs'
|
|
3
|
+
import * as path from 'path'
|
|
4
|
+
|
|
5
|
+
type NodeInfo = {
|
|
6
|
+
peerId: string
|
|
7
|
+
multiaddrs: string[]
|
|
8
|
+
port: number
|
|
9
|
+
networkName: string
|
|
10
|
+
timestamp: number
|
|
11
|
+
pid: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function waitForFile(file: string, timeoutMs: number) {
|
|
15
|
+
const start = Date.now()
|
|
16
|
+
while (Date.now() - start < timeoutMs) {
|
|
17
|
+
if (fs.existsSync(file)) return
|
|
18
|
+
await new Promise(r => setTimeout(r, 100))
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Timeout waiting for ${file}`)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function startNode({ port, bootstrap, announceFile, extraArgs = [] as string[] }: { port: number, bootstrap?: string, announceFile?: string, extraArgs?: string[] }) {
|
|
24
|
+
const args = [
|
|
25
|
+
'packages/reference-peer/dist/src/cli.js',
|
|
26
|
+
'service',
|
|
27
|
+
'--port', String(port),
|
|
28
|
+
'--network', 'optimystic',
|
|
29
|
+
...(bootstrap ? ['--bootstrap', bootstrap] : []),
|
|
30
|
+
'--storage', 'memory',
|
|
31
|
+
...(announceFile ? ['--announce-file', announceFile] : [])
|
|
32
|
+
].filter(Boolean)
|
|
33
|
+
|
|
34
|
+
const child = spawn('node', args, { stdio: 'inherit' })
|
|
35
|
+
return child
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function readNodeInfo(file: string): Promise<NodeInfo> {
|
|
39
|
+
const text = await fs.promises.readFile(file, 'utf-8')
|
|
40
|
+
return JSON.parse(text)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function main() {
|
|
44
|
+
const n = parseInt(process.env.MESH_NODES || '2', 10)
|
|
45
|
+
const basePort = parseInt(process.env.MESH_BASE_PORT || '8011', 10)
|
|
46
|
+
const workDir = path.join(process.cwd(), '.mesh')
|
|
47
|
+
fs.mkdirSync(workDir, { recursive: true })
|
|
48
|
+
|
|
49
|
+
const files = Array.from({ length: n }, (_, i) => path.join(workDir, `node-${i + 1}.json`))
|
|
50
|
+
const children: ReturnType<typeof spawn>[] = []
|
|
51
|
+
const readyFile = path.join(workDir, 'mesh-ready.json')
|
|
52
|
+
|
|
53
|
+
// Delete old ready file to signal mesh is starting
|
|
54
|
+
if (fs.existsSync(readyFile)) {
|
|
55
|
+
fs.unlinkSync(readyFile)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Check if we should reuse peer IDs (default: false for clean starts)
|
|
59
|
+
const reusePeerIds = process.env.MESH_REUSE_IDS === 'true'
|
|
60
|
+
const existingPeerIds: (string | undefined)[] = []
|
|
61
|
+
|
|
62
|
+
if (reusePeerIds) {
|
|
63
|
+
// Try to load existing peer IDs from previous runs
|
|
64
|
+
for (let i = 0; i < n; i++) {
|
|
65
|
+
const file = files[i]!
|
|
66
|
+
try {
|
|
67
|
+
if (fs.existsSync(file)) {
|
|
68
|
+
const info = await readNodeInfo(file)
|
|
69
|
+
existingPeerIds[i] = info.peerId
|
|
70
|
+
console.log(`Reusing peer ID from ${path.basename(file)}: ${info.peerId}`)
|
|
71
|
+
} else {
|
|
72
|
+
existingPeerIds[i] = undefined
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
existingPeerIds[i] = undefined
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
// Clean start - delete old node files to prevent stale peer ID pollution
|
|
80
|
+
for (let i = 0; i < n; i++) {
|
|
81
|
+
const file = files[i]!
|
|
82
|
+
if (fs.existsSync(file)) {
|
|
83
|
+
fs.unlinkSync(file)
|
|
84
|
+
console.log(`Deleted old ${path.basename(file)} for clean start`)
|
|
85
|
+
}
|
|
86
|
+
existingPeerIds[i] = undefined
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Start nodes sequentially, each bootstrapping to all previous nodes
|
|
91
|
+
const allBootstraps: string[] = []
|
|
92
|
+
|
|
93
|
+
for (let i = 0; i < n; i++) {
|
|
94
|
+
const port = basePort + i
|
|
95
|
+
const file = files[i]!
|
|
96
|
+
const id = existingPeerIds[i]
|
|
97
|
+
|
|
98
|
+
// Use accumulated bootstrap list (empty for first node)
|
|
99
|
+
const bootstrap = allBootstraps.length > 0 ? allBootstraps.join(',') : undefined
|
|
100
|
+
|
|
101
|
+
children.push(startNode({
|
|
102
|
+
port,
|
|
103
|
+
bootstrap,
|
|
104
|
+
announceFile: file,
|
|
105
|
+
extraArgs: id ? ['--id', id] : []
|
|
106
|
+
}))
|
|
107
|
+
await waitForFile(file, 10000)
|
|
108
|
+
|
|
109
|
+
// Read node info and add to bootstrap list for next nodes
|
|
110
|
+
const nodeInfo = await readNodeInfo(file)
|
|
111
|
+
// Prefer localhost for same-machine testing
|
|
112
|
+
const localAddr = nodeInfo.multiaddrs.find(a => a.includes('/ip4/127.0.0.1/'))
|
|
113
|
+
if (localAddr) {
|
|
114
|
+
allBootstraps.push(localAddr)
|
|
115
|
+
} else if (nodeInfo.multiaddrs.length > 0) {
|
|
116
|
+
allBootstraps.push(nodeInfo.multiaddrs[0]!)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Write ready file with all node info for clients to bootstrap from
|
|
121
|
+
const allNodes = await Promise.all(files.map(f => readNodeInfo(f)))
|
|
122
|
+
fs.writeFileSync(readyFile, JSON.stringify({
|
|
123
|
+
ready: true,
|
|
124
|
+
timestamp: Date.now(),
|
|
125
|
+
nodes: allNodes.map(n => ({ peerId: n.peerId, multiaddrs: n.multiaddrs }))
|
|
126
|
+
}, null, 2))
|
|
127
|
+
|
|
128
|
+
console.log('---- Mesh started. Press Ctrl+C to stop.')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
void main().catch(err => {
|
|
132
|
+
console.error(err)
|
|
133
|
+
process.exit(1)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
|