update
This commit is contained in:
+278
-13
@@ -1,20 +1,285 @@
|
||||
# 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
|
||||
const Hyperdrive = require('hyperdrive')
|
||||
const mirror = require('mirror-drive')
|
||||
## Installation
|
||||
|
||||
const local = new Hyperdrive(corestore)
|
||||
const remote = new Hyperdrive(corestore2)
|
||||
|
||||
const m = mirror(local, remote)
|
||||
await m.done() // Full sync
|
||||
m.destroy() // Pause
|
||||
```bash
|
||||
npm install mirror-drive
|
||||
```
|
||||
|
||||
**Diff Mirror**:
|
||||
await mirror({start: local.version}, remote)
|
||||
## Basic Usage
|
||||
|
||||
**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
|
||||
const udx = require('udx-native')
|
||||
const socket = udx.createSocket('udp4')
|
||||
socket.bind(0)
|
||||
## Prerequisites
|
||||
|
||||
socket.on('message', msg => console.log(msg))
|
||||
socket.send(targetPort, targetHost, 'hi')
|
||||
```bash
|
||||
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
|
||||
- Drive put: 500k/s
|
||||
## Local Operations
|
||||
|
||||
**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 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 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