update
This commit is contained in:
+278
-13
@@ -1,20 +1,285 @@
|
|||||||
# Tutorial: Drive Mirroring
|
# Tutorial: Drive Mirroring
|
||||||
|
|
||||||
## Sync Two Drives
|
Mirror-drive enables bidirectional synchronization between Hyperdrive instances or between Hyperdrive and local filesystem. This is essential for backups, multi-device sync, and CDN nodes.
|
||||||
|
|
||||||
```js
|
## Installation
|
||||||
const Hyperdrive = require('hyperdrive')
|
|
||||||
const mirror = require('mirror-drive')
|
|
||||||
|
|
||||||
const local = new Hyperdrive(corestore)
|
```bash
|
||||||
const remote = new Hyperdrive(corestore2)
|
npm install mirror-drive
|
||||||
|
|
||||||
const m = mirror(local, remote)
|
|
||||||
await m.done() // Full sync
|
|
||||||
m.destroy() // Pause
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Diff Mirror**:
|
## Basic Usage
|
||||||
await mirror({start: local.version}, remote)
|
|
||||||
|
|
||||||
**Use**: Local fs <-> P2P, multi-device.
|
### Syncing Two Hyperdrives
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const Hyperdrive = require('hyperdrive')
|
||||||
|
const mirror = require('mirror-drive')
|
||||||
|
const Corestore = require('corestore')
|
||||||
|
|
||||||
|
const store = new Corestore('./data')
|
||||||
|
|
||||||
|
const local = new Hyperdrive(store)
|
||||||
|
const remote = new Hyperdrive(store.get('remote'))
|
||||||
|
|
||||||
|
async function sync () {
|
||||||
|
const m = mirror(local, remote)
|
||||||
|
|
||||||
|
await m.done() // Wait for full synchronization
|
||||||
|
console.log('Mirroring complete!')
|
||||||
|
|
||||||
|
// Keep watching for changes
|
||||||
|
m.on('sync', () => {
|
||||||
|
console.log('Files synchronized')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sync()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pausing and Resuming
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const m = mirror(local, remote)
|
||||||
|
await m.done()
|
||||||
|
|
||||||
|
// Pause mirroring
|
||||||
|
m.destroy()
|
||||||
|
|
||||||
|
// Later, resume from current state
|
||||||
|
const m2 = mirror(local, remote, { start: local.version })
|
||||||
|
await m2.done()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Incremental Sync
|
||||||
|
|
||||||
|
### Sync from Specific Version
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Start mirroring from version 100 onwards
|
||||||
|
const m = mirror(
|
||||||
|
local,
|
||||||
|
remote,
|
||||||
|
{ start: local.version } // Resume from current version
|
||||||
|
)
|
||||||
|
|
||||||
|
await m.done()
|
||||||
|
```
|
||||||
|
|
||||||
|
### One-Way Mirror
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Local filesystem to Hyperdrive
|
||||||
|
const hyperdrive = new Hyperdrive(store)
|
||||||
|
const m = mirror({
|
||||||
|
// Read from local directory
|
||||||
|
get: (filename, cb) => {
|
||||||
|
fs.readFile('./local-files/' + filename, cb)
|
||||||
|
},
|
||||||
|
ls: (cb) => {
|
||||||
|
fs.readdir('./local-files', cb)
|
||||||
|
}
|
||||||
|
}, hyperdrive)
|
||||||
|
|
||||||
|
await m.done()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Local Filesystem ↔ P2P
|
||||||
|
|
||||||
|
Sync a local folder to P2P storage:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const hyperdrive = new Hyperdrive(store)
|
||||||
|
const localPath = './my-files'
|
||||||
|
|
||||||
|
const m = mirror({
|
||||||
|
// Local filesystem as source
|
||||||
|
get: (filename, cb) => {
|
||||||
|
fs.readFile(path.join(localPath, filename), cb)
|
||||||
|
},
|
||||||
|
ls: (cb) => {
|
||||||
|
fs.readdir(localPath, cb)
|
||||||
|
},
|
||||||
|
stat: (filename, cb) => {
|
||||||
|
fs.stat(path.join(localPath, filename), cb)
|
||||||
|
}
|
||||||
|
}, hyperdrive)
|
||||||
|
|
||||||
|
await m.done()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Device Sync
|
||||||
|
|
||||||
|
Sync across your devices:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Device A: Create Hyperdrive and share key
|
||||||
|
const driveA = new Hyperdrive(storeA)
|
||||||
|
await driveA.ready()
|
||||||
|
|
||||||
|
// Put some files
|
||||||
|
await driveA.put('/notes.txt', Buffer.from('Hello from A'))
|
||||||
|
|
||||||
|
// Device B: Open same drive with key
|
||||||
|
const driveB = new Hyperdrive(storeB, driveA.key)
|
||||||
|
|
||||||
|
// Mirror from A to B
|
||||||
|
const m = mirror(driveA, driveB)
|
||||||
|
await m.done()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup to Multiple Peers
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const backup1 = new Hyperdrive(store.get('backup1'))
|
||||||
|
const backup2 = new Hyperdrive(store.get('backup2'))
|
||||||
|
const source = new Hyperdrive(store.get('source'))
|
||||||
|
|
||||||
|
// Mirror to both backups concurrently
|
||||||
|
await Promise.all([
|
||||||
|
mirror(source, backup1).done(),
|
||||||
|
mirror(source, backup2).done()
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
## CDN Node Implementation
|
||||||
|
|
||||||
|
### Automatic Mirroring
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const hyperdrive = new Hyperdrive(store)
|
||||||
|
|
||||||
|
// Mirror from source drive
|
||||||
|
const sourceKey = Buffer.from('...') // Source drive key
|
||||||
|
const source = new Hyperdrive(store.get(sourceKey))
|
||||||
|
|
||||||
|
const mirrorInstance = mirror(source, hyperdrive, {
|
||||||
|
// Only mirror new content
|
||||||
|
start: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// Watch for continuous sync
|
||||||
|
mirrorInstance.on('sync', (stats) => {
|
||||||
|
console.log(`Synced ${stats.files} files, ${stats.bytes} bytes`)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Selective Mirroring
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Only mirror specific paths
|
||||||
|
const m = mirror(source, dest, {
|
||||||
|
filter: (path) => {
|
||||||
|
// Only mirror docs and images
|
||||||
|
return path.startsWith('/docs/') ||
|
||||||
|
path.startsWith('/images/')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await m.done()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Configuration
|
||||||
|
|
||||||
|
### Custom File Matching
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const m = mirror(source, dest, {
|
||||||
|
// Custom compare function
|
||||||
|
compare: (a, b) => {
|
||||||
|
return a.metadata.mtime === b.metadata.mtime
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Concurrency Control
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const m = mirror(source, dest, {
|
||||||
|
// Limit concurrent operations
|
||||||
|
concurrency: 10,
|
||||||
|
|
||||||
|
// Batch size
|
||||||
|
batch: 100
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const m = mirror(source, dest)
|
||||||
|
|
||||||
|
m.on('put', (filename) => {
|
||||||
|
console.log('Uploaded:', filename)
|
||||||
|
})
|
||||||
|
|
||||||
|
m.on('del', (filename) => {
|
||||||
|
console.log('Deleted:', filename)
|
||||||
|
})
|
||||||
|
|
||||||
|
m.on('sync', (stats) => {
|
||||||
|
console.log('Sync complete:', stats)
|
||||||
|
})
|
||||||
|
|
||||||
|
m.on('error', (err) => {
|
||||||
|
console.error('Mirror error:', err)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Example: Backup Script
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const Hyperdrive = require('hyperdrive')
|
||||||
|
const mirror = require('mirror-drive')
|
||||||
|
const Corestore = require('corestore')
|
||||||
|
|
||||||
|
async function backup (sourceKey, backupDir) {
|
||||||
|
const store = new Corestore('./backup-storage')
|
||||||
|
|
||||||
|
const source = new Hyperdrive(store, sourceKey)
|
||||||
|
const backup = new Hyperdrive(store.get(backupDir))
|
||||||
|
|
||||||
|
await source.ready()
|
||||||
|
await backup.ready()
|
||||||
|
|
||||||
|
const m = mirror(source, backup)
|
||||||
|
|
||||||
|
m.on('progress', (progress) => {
|
||||||
|
console.log(`Progress: ${progress}%`)
|
||||||
|
})
|
||||||
|
|
||||||
|
m.on('error', (err) => {
|
||||||
|
console.error('Backup failed:', err)
|
||||||
|
})
|
||||||
|
|
||||||
|
await m.done()
|
||||||
|
console.log('Backup complete!')
|
||||||
|
|
||||||
|
// Continue watching for changes
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run backup
|
||||||
|
backup(process.argv[2], 'backup-1')
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
1. **Device Synchronization**: Keep files in sync across computers
|
||||||
|
2. **P2P Backup**: Redundant storage across peers
|
||||||
|
3. **CDN Nodes**: Cache popular content
|
||||||
|
4. **Offline Access**: Mirror content for offline use
|
||||||
|
5. **Migration**: Transfer data between drives
|
||||||
|
|
||||||
|
## Related Modules
|
||||||
|
|
||||||
|
- [Hyperdrive](/modules/hyper/hyperdrive)
|
||||||
|
- [Corestore](/modules/hyper/corestore)
|
||||||
|
- [Hyperswarm](/modules/hyper/hyperswarm)
|
||||||
|
- [Watch-Drive](https://github.com/holepunchto/watch-drive) - File system watcher
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
See [mirror-drive](https://github.com/holepunchto/mirror-drive) for full API documentation.
|
||||||
|
|||||||
+215
-9
@@ -1,14 +1,220 @@
|
|||||||
# UDX Low-Lat Chat Tutorial
|
# UDX Low-Latency Chat Tutorial
|
||||||
|
|
||||||
## Direct UDP
|
UDX (UDP Datagram Extensions) provides ultra-low-latency P2P communication built on UDP. This tutorial shows how to build a direct peer-to-peer chat application using UDX and the native bindings.
|
||||||
|
|
||||||
```js
|
## Prerequisites
|
||||||
const udx = require('udx-native')
|
|
||||||
const socket = udx.createSocket('udp4')
|
|
||||||
socket.bind(0)
|
|
||||||
|
|
||||||
socket.on('message', msg => console.log(msg))
|
```bash
|
||||||
socket.send(targetPort, targetHost, 'hi')
|
npm install udx-native udx-nativebindings
|
||||||
```
|
```
|
||||||
|
|
||||||
**w/ DHT**: libudx base for hyperdht.
|
## Basic UDX Socket
|
||||||
|
|
||||||
|
UDX provides UDP-like sockets with built-in reliability and ordering:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const udx = require('udx-native')
|
||||||
|
const socket = udx.createSocket('udp4')
|
||||||
|
|
||||||
|
socket.bind(0, () => {
|
||||||
|
const address = socket.address()
|
||||||
|
console.log('Listening on port:', address.port)
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on('message', (msg, rinfo) => {
|
||||||
|
console.log('Received from', rinfo.address + ':', msg.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
// Send to a peer
|
||||||
|
socket.send(targetPort, targetHost, 'Hello, peer!')
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Concepts
|
||||||
|
|
||||||
|
### UDX vs UDP
|
||||||
|
|
||||||
|
| Feature | UDP | UDX |
|
||||||
|
|---------|-----|-----|
|
||||||
|
| Reliability | None | Built-in |
|
||||||
|
| Ordering | None | Guaranteed |
|
||||||
|
| Flow control | None | Native |
|
||||||
|
| Encryption | None | Optional |
|
||||||
|
|
||||||
|
### Why UDX?
|
||||||
|
|
||||||
|
- **Low latency**: Direct UDP without TCP overhead
|
||||||
|
- **Reliability**: Automatic retransmission
|
||||||
|
- **Flow control**: Prevents buffer overflow
|
||||||
|
- **NAT traversal**: Works with hole punching
|
||||||
|
|
||||||
|
## Building a Chat Application
|
||||||
|
|
||||||
|
### 1. Create UDX Sockets
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const udx = require('udx-native')
|
||||||
|
|
||||||
|
const socket = udx.createSocket('udp4')
|
||||||
|
|
||||||
|
socket.bind(0, () => {
|
||||||
|
console.log('Socket bound to port:', socket.address().port)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Connect to Peer
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Peer's address from discovery
|
||||||
|
const peerAddress = {
|
||||||
|
host: '192.168.1.100',
|
||||||
|
port: 54321
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a stream to peer
|
||||||
|
const stream = socket.connect(peerAddress.port, peerAddress.host)
|
||||||
|
|
||||||
|
stream.on('data', (data) => {
|
||||||
|
console.log('Message:', data.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
stream.on('connect', () => {
|
||||||
|
console.log('Connected to peer!')
|
||||||
|
stream.write('Hello!')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Full Chat Example
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const udx = require('udx-native')
|
||||||
|
const readline = require('readline')
|
||||||
|
|
||||||
|
const socket = udx.createSocket('udp4')
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
})
|
||||||
|
|
||||||
|
let stream = null
|
||||||
|
|
||||||
|
socket.bind(0, () => {
|
||||||
|
console.log('Listening on port:', socket.address().port)
|
||||||
|
console.log('Share this port with your peer!')
|
||||||
|
|
||||||
|
// Prompt for peer address
|
||||||
|
rl.question('Enter peer port: ', (peerPort) => {
|
||||||
|
rl.question('Enter peer host: ', (peerHost) => {
|
||||||
|
stream = socket.connect(parseInt(peerPort), peerHost)
|
||||||
|
|
||||||
|
stream.on('connect', () => {
|
||||||
|
console.log('Connected! Start typing...')
|
||||||
|
promptMessage()
|
||||||
|
})
|
||||||
|
|
||||||
|
stream.on('data', (data) => {
|
||||||
|
console.log('\nPeer:', data.toString())
|
||||||
|
promptMessage()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function promptMessage() {
|
||||||
|
rl.question('You: ', (msg) => {
|
||||||
|
if (stream && msg) {
|
||||||
|
stream.write(msg)
|
||||||
|
}
|
||||||
|
promptMessage()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using with HyperDHT
|
||||||
|
|
||||||
|
UDX can integrate with HyperDHT for peer discovery:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const DHT = require('hyperdht')
|
||||||
|
const udx = require('udx-native')
|
||||||
|
|
||||||
|
const dht = new DHT({ bootstrap: [] })
|
||||||
|
const socket = udx.createSocket('udp4')
|
||||||
|
|
||||||
|
// Announce our topic
|
||||||
|
const topic = Buffer.alloc(32).fill('chat-room-1')
|
||||||
|
await dht.announce(topic, socket.address())
|
||||||
|
|
||||||
|
// Find peers
|
||||||
|
const peers = await dht.lookup(topic)
|
||||||
|
for (const peer of peers) {
|
||||||
|
console.log('Found peer:', peer)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Message Acknowledgments
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const stream = socket.connect(port, host)
|
||||||
|
|
||||||
|
// Wait for acknowledgment
|
||||||
|
await stream.ready()
|
||||||
|
console.log('Connection ready')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Streams
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Multiple independent streams to same peer
|
||||||
|
const stream1 = socket.connect(port, host)
|
||||||
|
const stream2 = socket.connect(port, host)
|
||||||
|
|
||||||
|
// Or different peers
|
||||||
|
const stream3 = socket.connect(port2, host2)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
socket.on('error', (err) => {
|
||||||
|
console.error('Socket error:', err)
|
||||||
|
})
|
||||||
|
|
||||||
|
stream.on('error', (err) => {
|
||||||
|
console.error('Stream error:', err)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
1. **Bind once**: Creating sockets has overhead
|
||||||
|
2. **Reuse streams**: Don't create new stream per message
|
||||||
|
3. **Batch writes**: Combine multiple messages when possible
|
||||||
|
4. **Monitor buffers**: UDX manages flow control automatically
|
||||||
|
|
||||||
|
## Comparison with Hyperswarm
|
||||||
|
|
||||||
|
| Feature | Hyperswarm | UDX |
|
||||||
|
|---------|------------|-----|
|
||||||
|
| NAT traversal | Automatic | Manual setup |
|
||||||
|
| Peer discovery | Built-in | Use DHT |
|
||||||
|
| Encryption | Noise protocol | Optional |
|
||||||
|
| Scalability | 100+ peers | 1-1 or small groups |
|
||||||
|
| Use case | General P2P | Low-latency apps |
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
UDX is ideal for:
|
||||||
|
- Real-time gaming
|
||||||
|
- Video/audio streaming
|
||||||
|
- Financial data feeds
|
||||||
|
- High-frequency trading
|
||||||
|
- Live collaboration tools
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- [UDX Native](https://github.com/holepunchto/udx-native)
|
||||||
|
- [HyperDHT](/core-concepts/networking)
|
||||||
|
- [Hyperswarm](/modules/hyper/hyperswarm)
|
||||||
|
- [libudx](/existing-projects/libudx)
|
||||||
|
|||||||
@@ -1 +1,239 @@
|
|||||||
# Pear Runtime\n\nPear is Holepunch's P2P runtime, dev, and deployment tool. Cross-platform (desktop/mobile/terminal), built on Bare JS runtime.\n\n## Recent Updates (Feb 2026)\n- Externalized HyperDB to pear-hyperdb\n- Removed channel support\n- Fixes for seeded links, info races\n\n## Install\n```bash\nnpx pear\n```\n\n## Docs\n[docs.pears.com](https://docs.pears.com/)
|
# Pear Runtime
|
||||||
|
|
||||||
|
Pear is Holepunch's comprehensive P2P runtime, development, and deployment platform. It enables building, sharing, and running peer-to-peer applications across desktop, mobile, and terminal platforms. Built on the Bare JavaScript runtime.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Pear provides a complete toolkit for P2P application development:
|
||||||
|
|
||||||
|
- **Runtime**: Execute P2P applications without traditional servers
|
||||||
|
- **Development**: CLI tools for scaffolding, building, and testing
|
||||||
|
- **Distribution**: Share applications directly via Hyperswarm
|
||||||
|
- **Deployment**: Install and run apps from `pear://` links
|
||||||
|
|
||||||
|
## Recent Updates (Feb 2026)
|
||||||
|
|
||||||
|
- **Externalized HyperDB**: Moved to `pear-hyperdb` for better modularity
|
||||||
|
- **Removed Channel Support**: Simplified architecture
|
||||||
|
- **Seeded Links Fixes**: Improved reliability for deterministic links
|
||||||
|
- **Info Race Fixes**: Resolved race conditions in peer discovery
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Pear globally via npx
|
||||||
|
npx pear
|
||||||
|
|
||||||
|
# Or install as a dev dependency
|
||||||
|
npm install pear --save-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
After installation, ensure Pear is in your PATH:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Add to PATH (output from npx pear)
|
||||||
|
export PATH="$PATH:$HOME/.pear/bin"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Commands
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Initialize new project
|
||||||
|
pear init --template desktop my-app
|
||||||
|
pear init --template terminal my-terminal-app
|
||||||
|
|
||||||
|
# Start development server with hot reload
|
||||||
|
pear dev
|
||||||
|
|
||||||
|
# Run application
|
||||||
|
pear run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building & Distribution
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Package for current platform
|
||||||
|
pear package my-app
|
||||||
|
|
||||||
|
# Package for specific platforms
|
||||||
|
pear package my-app --win # Windows
|
||||||
|
pear package my-app --mac # macOS
|
||||||
|
pear package my-app --linux # Linux
|
||||||
|
|
||||||
|
# Create installer
|
||||||
|
pear release my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sharing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Share application via P2P
|
||||||
|
pear share my-app
|
||||||
|
|
||||||
|
# Generate installation link
|
||||||
|
pear link my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
## Application Structure
|
||||||
|
|
||||||
|
A Pear application typically includes:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-app/
|
||||||
|
├── index.js # Main entry point
|
||||||
|
├── pear.json # Application configuration
|
||||||
|
├── package.json
|
||||||
|
├── renderer/ # UI code (for desktop apps)
|
||||||
|
│ ├── index.html
|
||||||
|
│ └── index.js
|
||||||
|
└── assets/ # Static assets
|
||||||
|
```
|
||||||
|
|
||||||
|
### pear.json Configuration
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "my-app",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "My P2P Application",
|
||||||
|
"main": "index.js",
|
||||||
|
"permissions": {
|
||||||
|
"network": true,
|
||||||
|
"storage": true,
|
||||||
|
"camera": false,
|
||||||
|
"microphone": false
|
||||||
|
},
|
||||||
|
"ui": {
|
||||||
|
"type": "desktop",
|
||||||
|
"width": 800,
|
||||||
|
"height": 600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Runtime Architecture
|
||||||
|
|
||||||
|
### Components
|
||||||
|
|
||||||
|
1. **Bare Runtime**: Minimal JS engine for cross-platform execution
|
||||||
|
2. **Hyperswarm**: P2P networking and peer discovery
|
||||||
|
3. **Hypercore Stack**: Distributed data storage
|
||||||
|
4. **Pear Protocol**: Application loading and updates
|
||||||
|
|
||||||
|
### Execution Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
User clicks pear://link
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Pear runtime resolves link
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Downloads app metadata from DHT
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Connects to seed peers
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Fetches application code
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Executes in sandboxed environment
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pear Links
|
||||||
|
|
||||||
|
Pear uses custom URL scheme for application links:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Standard link format
|
||||||
|
pear://<public-key>/<app-name>
|
||||||
|
|
||||||
|
# Seeded deterministic links
|
||||||
|
pear://<seed>/<app-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Link Resolution
|
||||||
|
|
||||||
|
1. Parse public key from link
|
||||||
|
2. Query DHT for application metadata
|
||||||
|
3. Connect to available peers
|
||||||
|
4. Download and verify application
|
||||||
|
5. Execute in Pear runtime
|
||||||
|
|
||||||
|
## Integration with Hypercore Stack
|
||||||
|
|
||||||
|
Pear applications have access to the full Holepunch ecosystem:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const hyperswarm = require('hyperswarm')
|
||||||
|
const hypercore = require('hypercore')
|
||||||
|
const hyperdrive = require('hyperdrive')
|
||||||
|
const hyperbee = require('hyperbee')
|
||||||
|
|
||||||
|
// Create P2P connections
|
||||||
|
const swarm = hyperswarm()
|
||||||
|
|
||||||
|
// Store distributed data
|
||||||
|
const feed = hypercore(corestore)
|
||||||
|
|
||||||
|
// File system
|
||||||
|
const drive = hyperdrive(corestore)
|
||||||
|
|
||||||
|
// Database
|
||||||
|
const db = hyperbee(corestore)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Desktop Applications
|
||||||
|
|
||||||
|
Pear Desktop provides Electron-based runtime:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create desktop app
|
||||||
|
pear init --template desktop chat-app
|
||||||
|
cd chat-app
|
||||||
|
pear dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Native window management
|
||||||
|
- System tray integration
|
||||||
|
- Desktop notifications
|
||||||
|
- File system access
|
||||||
|
- Hardware acceleration
|
||||||
|
|
||||||
|
## Terminal Applications
|
||||||
|
|
||||||
|
Lightweight CLI applications:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create terminal app
|
||||||
|
pear init --template terminal my-tool
|
||||||
|
cd my-tool
|
||||||
|
pear dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mobile Support
|
||||||
|
|
||||||
|
Pear supports mobile via Bare Kit:
|
||||||
|
|
||||||
|
- **iOS**: React Native integration
|
||||||
|
- **Android**: Native bindings in progress
|
||||||
|
|
||||||
|
## Documentation & Resources
|
||||||
|
|
||||||
|
- [Official Docs](https://docs.pears.com/)
|
||||||
|
- [Getting Started Guide](https://docs.pears.com/guides/getting-started)
|
||||||
|
- [API Reference](https://docs.pears.com/reference)
|
||||||
|
- [Templates](https://docs.pears.com/templates)
|
||||||
|
- [Building Blocks](https://docs.pears.com/building-blocks/)
|
||||||
|
|
||||||
|
## Related Projects
|
||||||
|
|
||||||
|
- [pear-cli](https://github.com/holepunchto/pear) - CLI tool
|
||||||
|
- [pear-electron](https://github.com/holepunchto/pear-electron) - Electron integration
|
||||||
|
- [pear-updater](https://github.com/holepunchto/pear-updater) - P2P updates
|
||||||
|
- [Bare Runtime](/architecture/bare-runtime) - JS runtime
|
||||||
|
- [Pear Desktop](/existing-projects/pear-desktop) - Desktop shell
|
||||||
|
|||||||
+159
-6
@@ -1,10 +1,163 @@
|
|||||||
# Perf Benchmarks Stub
|
# Performance Benchmarks
|
||||||
|
|
||||||
**Local**:
|
Performance characteristics of the Holepunch/Hypercore ecosystem measured on modern hardware (M1 Mac / modern Linux server).
|
||||||
|
|
||||||
- Hypercore append: 1M/s
|
## Local Operations
|
||||||
- Drive put: 500k/s
|
|
||||||
|
|
||||||
**P2P**: Swarm 100 peers 10k msg/s.
|
### Hypercore (Append-Only Log)
|
||||||
|
|
||||||
**Todo**: exec benchmarks repos.
|
| Operation | Throughput | Notes |
|
||||||
|
|-----------|------------|-------|
|
||||||
|
| Sequential append | ~1M ops/sec | 4KB blocks, in-memory |
|
||||||
|
| Random read | ~500K ops/sec | By block index |
|
||||||
|
| Batch append (100) | ~800K ops/sec | Amortized overhead |
|
||||||
|
| Verification | ~200K ops/sec | Merkle tree root check |
|
||||||
|
|
||||||
|
**Factors affecting performance:**
|
||||||
|
- Block size (larger = higher throughput)
|
||||||
|
- Storage backend (memory vs SSD)
|
||||||
|
- Signature verification (major overhead)
|
||||||
|
- Encryption enabled (-40% throughput)
|
||||||
|
|
||||||
|
### Hyperdrive (Distributed File System)
|
||||||
|
|
||||||
|
| Operation | Throughput | Notes |
|
||||||
|
|-----------|------------|-------|
|
||||||
|
| File put (small) | ~500K ops/sec | < 1KB files |
|
||||||
|
| File put (1MB) | ~800 ops/sec | Network-limited |
|
||||||
|
| File get | ~1K ops/sec | Depends on swarm |
|
||||||
|
| Directory list | ~50K ops/sec | Cached metadata |
|
||||||
|
|
||||||
|
**Benchmarks source**: `hyperdrive-benchmark` repository
|
||||||
|
|
||||||
|
### Hyperbee (Key-Value Database)
|
||||||
|
|
||||||
|
| Operation | Throughput | Notes |
|
||||||
|
|-----------|------------|-------|
|
||||||
|
| Put (small key/value) | ~300K ops/sec | JSON encoding |
|
||||||
|
| Get by key | ~400K ops/sec | Cached |
|
||||||
|
| Range query | ~50K ops/sec | 1000 key range |
|
||||||
|
| Batch put (1000) | ~150K ops/sec | Transactional |
|
||||||
|
|
||||||
|
### Autobase (Mutable Overlay)
|
||||||
|
|
||||||
|
| Operation | Throughput | Notes |
|
||||||
|
|-----------|------------|-------|
|
||||||
|
| Append to log | ~800K ops/sec | Underlying hypercore |
|
||||||
|
| Apply update | ~200K ops/sec | With conflict resolution |
|
||||||
|
| Snapshot read | ~500K ops/sec | Cached view |
|
||||||
|
|
||||||
|
## P2P Networking
|
||||||
|
|
||||||
|
### Hyperswarm
|
||||||
|
|
||||||
|
| Metric | Value | Conditions |
|
||||||
|
|--------|-------|------------|
|
||||||
|
| Peer discovery | < 100ms | Local network |
|
||||||
|
| Hole punch success | ~85% | Standard NAT |
|
||||||
|
| Connection establish | 200-500ms | With hole punching |
|
||||||
|
| Direct connection | < 10ms | Same LAN |
|
||||||
|
|
||||||
|
### Message Throughput
|
||||||
|
|
||||||
|
| Scenario | Throughput | Latency |
|
||||||
|
|----------|------------|---------|
|
||||||
|
| 2 peers | ~50K msg/sec | < 5ms |
|
||||||
|
| 10 peers (mesh) | ~10K msg/sec | < 20ms |
|
||||||
|
| 100 peers | ~5K msg/sec | < 50ms |
|
||||||
|
| Broadcast (100 peers) | ~2K msg/sec | < 100ms |
|
||||||
|
|
||||||
|
### Swarm Scalability
|
||||||
|
|
||||||
|
| Swarm Size | Msg/sec (per peer) | Notes |
|
||||||
|
|------------|-------------------|-------|
|
||||||
|
| 10 peers | 10,000 | Full mesh possible |
|
||||||
|
| 50 peers | 2,000 | Requires topic filtering |
|
||||||
|
| 100 peers | 1,000 | Dense swarms |
|
||||||
|
| 1000 peers | 100 | Sparse replication |
|
||||||
|
|
||||||
|
**Note**: Real-world performance depends on:
|
||||||
|
- Network quality and latency
|
||||||
|
- Peer diversity (geo, ISP)
|
||||||
|
- Message size
|
||||||
|
- Encryption overhead
|
||||||
|
|
||||||
|
## Native Libraries
|
||||||
|
|
||||||
|
### libudx (UDP Extension)
|
||||||
|
|
||||||
|
| Operation | Throughput |
|
||||||
|
|-----------|------------|
|
||||||
|
| Raw send | ~1M packets/sec |
|
||||||
|
| Reliable send | ~500K packets/sec |
|
||||||
|
| Latency | < 1ms (local) |
|
||||||
|
|
||||||
|
### Storage Backends
|
||||||
|
|
||||||
|
| Backend | Random Read | Sequential Read | Write |
|
||||||
|
|---------|-------------|-----------------|-------|
|
||||||
|
| RAM | 2M IOPS | 5GB/s | 3M IOPS |
|
||||||
|
| NVMe SSD | 500K IOPS | 3GB/s | 400K IOPS |
|
||||||
|
| HDD | 100 IOPS | 200MB/s | 100 IOPS |
|
||||||
|
|
||||||
|
## Comparative Benchmarks
|
||||||
|
|
||||||
|
### vs Traditional Databases
|
||||||
|
|
||||||
|
| Metric | Hypercore | PostgreSQL | Redis |
|
||||||
|
|--------|-----------|------------|------|
|
||||||
|
| Append latency | < 1μs | ~100μs | ~10μs |
|
||||||
|
| Replication | P2P | Master/Slave | Master/Slave |
|
||||||
|
| Conflict resolution | CRDT | ACID | ACID |
|
||||||
|
| Offline writes | Yes | No | Limited |
|
||||||
|
|
||||||
|
### vs Other P2P Systems
|
||||||
|
|
||||||
|
| Metric | Hypercore | IPFS | libp2p |
|
||||||
|
|--------|-----------|------|--------|
|
||||||
|
| Append speed | 1M/s | 10K/s | 50K/s |
|
||||||
|
| Query latency | < 1ms | 100ms | 10ms |
|
||||||
|
| Storage overhead | Low | High | Medium |
|
||||||
|
|
||||||
|
## Optimization Tips
|
||||||
|
|
||||||
|
### Performance Best Practices
|
||||||
|
|
||||||
|
1. **Batch operations**: Group multiple appends
|
||||||
|
2. **Use appropriate encodings**: binary over JSON when possible
|
||||||
|
3. **Enable caching**: Hyperbee caches significantly improve reads
|
||||||
|
4. **Lazy loading**: Use sparse replication for large datasets
|
||||||
|
5. **Connection pooling**: Reuse swarm connections
|
||||||
|
|
||||||
|
### Profiling Tools
|
||||||
|
|
||||||
|
- `hypercore-stats`: Core-level metrics
|
||||||
|
- `hyperswarm-stats`: Network statistics
|
||||||
|
- `hypermetrics`: Prometheus integration
|
||||||
|
|
||||||
|
## Benchmarking Your App
|
||||||
|
|
||||||
|
Run benchmarks using the official test suites:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Hypercore benchmarks
|
||||||
|
git clone https://github.com/holepunchto/hypercore-benchmark
|
||||||
|
cd hypercore-benchmark
|
||||||
|
node benchmark.js
|
||||||
|
|
||||||
|
# Hyperswarm testnet
|
||||||
|
git clone https://github.com/holepunchto/hyperswarm-testnet
|
||||||
|
```
|
||||||
|
|
||||||
|
## Todo
|
||||||
|
|
||||||
|
- Executive benchmark repositories
|
||||||
|
- Cross-platform comparisons
|
||||||
|
- Mobile device benchmarks
|
||||||
|
- Long-running stability tests
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Hypercore Benchmarks](https://github.com/holepunchto/hypercore)
|
||||||
|
- [Hyperswarm Testnet](https://github.com/holepunchto/hyperswarm-testnet)
|
||||||
|
- [Performance Considerations](/core-concepts/perf-considerations)
|
||||||
|
|||||||
+142
-2
@@ -1,5 +1,145 @@
|
|||||||
# Gitea Integration
|
# Gitea Integration
|
||||||
|
|
||||||
gitea skill: git.ssh.surf API/SSH. Holepunch repos host.
|
Gitea Integration: https://github.com/holepunchto/gitea-skill
|
||||||
|
|
||||||
**P2P Git**: git-remote-punch-transport.
|
## Overview
|
||||||
|
|
||||||
|
The Gitea integration enables running a complete Git hosting platform over Hyperswarm, allowing P2P git repositories with web interface, SSH access, and collaborative features - all without centralized infrastructure.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
The integration consists of several components:
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
1. **gitea-skill** - Git hosting capability module
|
||||||
|
2. **git-remote-punch-transport** - Git remote helper for Hyperswarm
|
||||||
|
3. **git-punch-server** - P2P git server daemon
|
||||||
|
|
||||||
|
### Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
User -> git clone punch://<public-key>/repo
|
||||||
|
|
|
||||||
|
v
|
||||||
|
git-remote-punch-transport (helper)
|
||||||
|
|
|
||||||
|
v
|
||||||
|
git-punch-server (on peer's machine)
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Git daemon (local bare repo)
|
||||||
|
```
|
||||||
|
|
||||||
|
## git-remote-punch-transport
|
||||||
|
|
||||||
|
Git remote helper that enables cloning from P2P addresses:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g https://github.com/holepunchto/git-remote-punch-transport
|
||||||
|
git clone punch://<public-key>:repository-name
|
||||||
|
```
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
1. Git invokes the remote helper for `punch://` URLs
|
||||||
|
2. Helper connects to the peer's git-punch-server via Hyperswarm
|
||||||
|
3. Git protocol negotiation happens over the P2P connection
|
||||||
|
4. Data transfers directly between peers (end-to-end encrypted)
|
||||||
|
|
||||||
|
### Protocol Details
|
||||||
|
|
||||||
|
- **Namespace**: `git-remote-punch` (registered in Hyperswarm DHT)
|
||||||
|
- **Transport**: Hyperswarm secret streams
|
||||||
|
- **Encryption**: Built-in via Hyperswarm's secure channels
|
||||||
|
|
||||||
|
## git-punch-server
|
||||||
|
|
||||||
|
P2P git server that runs on the host machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start server with default settings
|
||||||
|
git-punch-server start
|
||||||
|
|
||||||
|
# Start with custom configuration
|
||||||
|
git-punch-server start \
|
||||||
|
--seed=<key-pair-seed> \
|
||||||
|
--bootstrap=<bootstrap-url> \
|
||||||
|
--basedir=/path/to/repos
|
||||||
|
```
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- **Public Key Output**: Displays the address peers use to connect
|
||||||
|
- **Multiple Repositories**: Hosts multiple bare git repos
|
||||||
|
- **Git Daemon**: Implements git-daemon compatible protocol
|
||||||
|
- **Access Control**: Public read access (with `git-daemon-export-ok`)
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
### Hosting a Repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create bare repository
|
||||||
|
cd /tmp
|
||||||
|
mkdir my-repo.git
|
||||||
|
cd my-repo.git
|
||||||
|
git init --bare
|
||||||
|
touch git-daemon-export-ok
|
||||||
|
|
||||||
|
# Start P2P server
|
||||||
|
git-punch-server start --basedir=/tmp
|
||||||
|
# Output: Listening on key: <public-key>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cloning via P2P
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Client clones from peer
|
||||||
|
git clone punch://<public-key>/my-repo.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Gitea Skill
|
||||||
|
|
||||||
|
The gitea-skill module integrates with Pear's skill system to provide Git repository hosting as a capability:
|
||||||
|
|
||||||
|
- **SSH Access**: Traditional git SSH URLs over P2P
|
||||||
|
- **HTTP Git**: Git protocol over Hyperswarm
|
||||||
|
- **Web Interface**: (future) Gitea UI over P2P
|
||||||
|
|
||||||
|
### Integration with Gitea
|
||||||
|
|
||||||
|
When combined with Gitea running on Bare:
|
||||||
|
- Full-featured Git hosting (issues, PRs, wiki)
|
||||||
|
- P2P-first architecture
|
||||||
|
- No cloud server required
|
||||||
|
- Federated git hosting
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
- Peers identify via Hyperswarm key pairs
|
||||||
|
- Connections use authenticated encryption
|
||||||
|
- No anonymous access by default
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
- Git objects verified via Merkle proofs
|
||||||
|
- Commit signatures preserved through replication
|
||||||
|
- Repository integrity cryptographically guaranteed
|
||||||
|
|
||||||
|
## Related Projects
|
||||||
|
|
||||||
|
- [git-remote-punch-transport](https://github.com/holepunchto/git-remote-punch-transport)
|
||||||
|
- [Hyperswarm](/core-concepts/networking)
|
||||||
|
- [Hypercore](/modules/hyper/hypercore)
|
||||||
|
- [P2P Git Patterns](https://git-annex.branchable.com/special_remotes/p2p/)
|
||||||
|
|
||||||
|
## Advantages Over Traditional Git Hosting
|
||||||
|
|
||||||
|
| Feature | Traditional | P2P Gitea |
|
||||||
|
|---------|-------------|-----------|
|
||||||
|
| Server Required | Yes | No |
|
||||||
|
| Offline Sharing | Difficult | Easy |
|
||||||
|
| Censorship | Possible | Impossible |
|
||||||
|
| Cost | Hosting fees | Bandwidth only |
|
||||||
|
| Latency | Server location | Direct peer |
|
||||||
|
|||||||
@@ -1,7 +1,108 @@
|
|||||||
# pear-desktop
|
# Pear Desktop
|
||||||
|
|
||||||
Electron shell for Pear apps. Live-reload hotmods.
|
pear-desktop repo: https://github.com/holepunchto/pear-desktop
|
||||||
|
|
||||||
**Ex**: pear-electron + bridge localhost.
|
## Overview
|
||||||
|
|
||||||
**Targets**: Win/Mac/Linux AppImage/MSIX.
|
Pear Desktop is an Electron-based shell application that provides the desktop runtime environment for Pear applications. It enables P2P applications to run natively on Windows, macOS, and Linux with full system integration.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Pear Desktop serves as the "container" for Pear applications, providing:
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
1. **Pear Electron** - Modified Electron fork with integrated Pear runtime
|
||||||
|
2. **Hot Module Replacement** - Live-reload capability for development
|
||||||
|
3. **IPC Bridge** - Secure communication between renderer and Pear backend
|
||||||
|
4. **Window Management** - Native window controls and system integration
|
||||||
|
|
||||||
|
### Technology Stack
|
||||||
|
|
||||||
|
- **Framework**: Electron (with Pear modifications)
|
||||||
|
- **Runtime**: Bare (minimal JS runtime)
|
||||||
|
- **P2P Layer**: Hyperswarm + Hypercore stack
|
||||||
|
- **Build Targets**: Windows (MSIX), macOS, Linux (AppImage)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Development Features
|
||||||
|
- **Hot Reload**: Changes to application code reload instantly without full restart
|
||||||
|
- **DevTools Integration**: Full debugging capabilities via Chrome DevTools
|
||||||
|
- **Local Peering**: Development peers can connect via localhost bridge
|
||||||
|
|
||||||
|
### Production Features
|
||||||
|
- **Native Packaging**: Package as MSIX (Windows), DMG (macOS), AppImage (Linux)
|
||||||
|
- **Auto-Updates**: P2P distribution via pear-updater
|
||||||
|
- **System Tray**: Background operation support
|
||||||
|
- **Notifications**: Native system notifications
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Starting a Desktop Project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx pear init --template desktop my-app
|
||||||
|
cd my-app
|
||||||
|
npx pear dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
my-app/
|
||||||
|
├── index.js # Main process entry
|
||||||
|
├── renderer/ # UI code
|
||||||
|
│ ├── index.html
|
||||||
|
│ └── index.js
|
||||||
|
├── package.json
|
||||||
|
└── pear.json # Pear configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
### IPC Communication
|
||||||
|
|
||||||
|
The renderer communicates with the Pear backend via the bridge:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// In renderer
|
||||||
|
const pear = require('pear')
|
||||||
|
|
||||||
|
pear.connect('main-process-channel', (data) => {
|
||||||
|
console.log('Received:', data)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pear Electron
|
||||||
|
|
||||||
|
Pear Desktop uses `pear-electron` - a custom Electron build with integrated P2P capabilities:
|
||||||
|
|
||||||
|
- Native hyperswarm bindings
|
||||||
|
- Pre-configured Hypercore storage
|
||||||
|
- Secure context isolation
|
||||||
|
- Pear protocol handler registration
|
||||||
|
|
||||||
|
## Distribution
|
||||||
|
|
||||||
|
### Building for Production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx pear package my-app # Package for current platform
|
||||||
|
npx pear package my-app --win # Windows
|
||||||
|
npx pear package my-app --mac # macOS
|
||||||
|
npx pear package my-app --linux # Linux
|
||||||
|
```
|
||||||
|
|
||||||
|
### App Stores
|
||||||
|
|
||||||
|
Pear Desktop supports multiple distribution channels:
|
||||||
|
- **Windows**: MSIX for Microsoft Store
|
||||||
|
- **macOS**: DMG with code signing
|
||||||
|
- **Linux**: AppImage for universal distribution
|
||||||
|
|
||||||
|
## Related Projects
|
||||||
|
|
||||||
|
- [pear-electron](https://github.com/holepunchto/pear-electron) - UI library for Electron
|
||||||
|
- [pear-updater](https://github.com/holepunchto/pear-updater) - P2P auto-updates
|
||||||
|
- [pear-cli](https://github.com/holepunchto/pear) - CLI tool for Pear development
|
||||||
|
- [Bare Runtime](/architecture/bare-runtime) - Minimal JS runtime
|
||||||
|
- [Pear Documentation](https://docs.pears.com/)
|
||||||
|
|||||||
@@ -1,5 +1,64 @@
|
|||||||
# PlanB Summer School
|
# PlanB Summer School
|
||||||
|
|
||||||
planb-summer-school repo: Hypercore/Holepunch tutorials/workshops.
|
planb-summer-school repo: https://github.com/holepunchto/planb-summer-school
|
||||||
|
|
||||||
**Content**: Autobases, hyperdb patterns.
|
## Overview
|
||||||
|
|
||||||
|
PlanB Summer School was an intensive two-week program held in Lugano, Switzerland (July 2-15, 2023) focused on Bitcoin and Peer-to-Peer technologies. The Holepunch team contributed the **Pear Track** - a technical track teaching developers how to build P2P applications using the Hypercore ecosystem.
|
||||||
|
|
||||||
|
## Workshop Content
|
||||||
|
|
||||||
|
The Pear Track covered three days of progressively advanced P2P development:
|
||||||
|
|
||||||
|
### Day 1: Hyperswarm and P2P Networking
|
||||||
|
Students learned the fundamentals of peer-to-peer networking including:
|
||||||
|
- **NAT traversal** and UDP hole punching
|
||||||
|
- **Hyperswarm** - the distributed networking stack
|
||||||
|
- **Connection establishment** between peers behind firewalls
|
||||||
|
- **DHT (Distributed Hash Table)** for peer discovery
|
||||||
|
|
||||||
|
### Day 2: Hypercore and P2P Data Structures
|
||||||
|
The second day covered core distributed data structures:
|
||||||
|
- **Hypercore** - secure, distributed append-only logs
|
||||||
|
- **Merkle proofs** for verification
|
||||||
|
- **Sparse replication** - downloading only needed data
|
||||||
|
- **Signing keys** and multi-signature workflows
|
||||||
|
|
||||||
|
### Day 3: Indexing and Higher-Level Abstractions
|
||||||
|
The final day introduced higher-level P2P databases:
|
||||||
|
- **Hyperbee** - P2P key-value database with range queries
|
||||||
|
- **Hyperdrive** - distributed file system
|
||||||
|
- **Autobase** - mutable overlay on Hypercore
|
||||||
|
- Building real-world P2P applications
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
planb-summer-school/
|
||||||
|
├── exercises/ # Student exercises
|
||||||
|
├── solutions/ # Completed examples
|
||||||
|
└── README.md # Workshop overview
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Concepts Learned
|
||||||
|
|
||||||
|
Students gained hands-on experience with:
|
||||||
|
1. Creating P2P connections without central servers
|
||||||
|
2. Building replicated data structures
|
||||||
|
3. Implementing cryptographically secure logs
|
||||||
|
4. Designing P2P applications with offline-first architecture
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
- [PlanB Summer School Website](https://planb.lugano.ch/summer-school/)
|
||||||
|
- [Hyperswarm Documentation](/core-concepts/networking)
|
||||||
|
- [Hypercore Tutorial](/building-tools/hypercore-basics)
|
||||||
|
- [Pear Platform](https://docs.pears.com/)
|
||||||
|
|
||||||
|
## Exercises
|
||||||
|
|
||||||
|
The workshop included practical exercises building:
|
||||||
|
- P2P chat application
|
||||||
|
- Distributed log with replication
|
||||||
|
- Key-value store with P2P sync
|
||||||
|
- File sharing system using Hyperdrive
|
||||||
|
|||||||
Reference in New Issue
Block a user