npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

pigeonnest

v0.0.2

Published

A Vue 3 framework for PeerPigeon application development

Readme

PigeonNest

A comprehensive Vue 3 component library and framework for building peer-to-peer applications with PeerPigeon.

npm version License: MIT

Overview

PigeonNest provides Vue 3 composables and components that make it easy to build WebRTC-based peer-to-peer applications using the PeerPigeon protocol. It offers:

  • 🎯 Ready-to-use Vue Components - Drop-in UI components for peer connections, file transfers, and status displays
  • 🔧 Powerful Composables - Vue 3 composables for mesh networking, streaming (PigeonFS), and distributed storage
  • 📦 TypeScript Support - Full TypeScript definitions for type safety
  • 🎨 Customizable - Easy to style and extend
  • 📡 Real-time - Built on WebRTC for true peer-to-peer communication

Features

Core Composables

  • usePeerPigeon - Main mesh network management
  • usePeerStreaming - File and data streaming (PigeonFS with readable/writable streams)
  • usePeerStorage - Distributed storage across the mesh

UI Components

  • PeerConnectionStatus - Display connection status and network information
  • PeerList - List and manage connected peers
  • FileUpload - Drag-and-drop file upload with multi-file support
  • StreamProgress - Real-time progress tracking for file transfers

Installation

npm install pigeonnest vue peerpigeon

Quick Start

Basic Setup

<template>
  <div>
    <PeerConnectionStatus :status="status" :is-connected="isConnected" />
    <button @click="initialize">Initialize</button>
    <button @click="connect">Connect</button>
    <PeerList :peers="connectedPeerIds" @select="handlePeerSelect" />
  </div>
</template>

<script setup>
import { usePeerPigeon, PeerConnectionStatus, PeerList } from 'pigeonnest'

const {
  status,
  isConnected,
  connectedPeerIds,
  init,
  connect
} = usePeerPigeon({
  networkName: 'my-app',
  maxPeers: 5
})

const initialize = async () => {
  await init()
}

const connectToHub = async () => {
  await connect('ws://localhost:3000')
}

const handlePeerSelect = (peerId) => {
  console.log('Selected peer:', peerId)
}
</script>

File Streaming (PigeonFS)

<template>
  <div>
    <FileUpload @upload="handleUpload" :target-peer-id="selectedPeer" />
    
    <StreamProgress 
      v-for="stream in activeStreamsArray" 
      :key="stream.streamId"
      :stream="stream"
      @cancel="cancelStream"
    />
  </div>
</template>

<script setup>
import { usePeerPigeon, usePeerStreaming, FileUpload, StreamProgress } from 'pigeonnest'
import { computed } from 'vue'

const { mesh } = usePeerPigeon()
const { 
  activeStreams, 
  sendFile, 
  receiveStream,
  cancelStream 
} = usePeerStreaming()

const selectedPeer = ref(null)

const handleUpload = async (files) => {
  for (const file of files) {
    await sendFile(mesh.value, selectedPeer.value, file)
  }
}

const activeStreamsArray = computed(() => Array.from(activeStreams.value.values()))

// Listen for incoming streams
if (mesh.value) {
  mesh.value.addEventListener('streamReceived', async (event) => {
    const blob = await receiveStream(event)
    // Download the file
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = event.metadata.filename
    a.click()
  })
}
</script>

Advanced Streaming (Low-Level API)

Use the low-level streaming API for custom data sources:

<script setup>
import { usePeerPigeon, usePeerStreaming } from 'pigeonnest'

const { mesh } = usePeerPigeon()
const { sendStream, createStreamToPeer } = usePeerStreaming()

// Example 1: Send custom ReadableStream
const sendCustomData = async (peerId) => {
  // Create a readable stream from any data source
  const stream = new ReadableStream({
    async start(controller) {
      for (let i = 0; i < 10; i++) {
        const data = new TextEncoder().encode(`Chunk ${i}\n`)
        controller.enqueue(data)
        await new Promise(resolve => setTimeout(resolve, 100))
      }
      controller.close()
    }
  })
  
  await sendStream(mesh.value, peerId, stream, {
    filename: 'custom-data.txt',
    mimeType: 'text/plain',
    totalSize: 100
  })
}

// Example 2: Use WritableStream for manual control
const sendWithManualControl = async (peerId) => {
  const writable = createStreamToPeer(mesh.value, peerId, {
    filename: 'manual-data.bin',
    totalSize: 1024
  })
  
  const writer = writable.getWriter()
  
  try {
    await writer.write(new Uint8Array([1, 2, 3, 4]))
    await writer.write(new Uint8Array([5, 6, 7, 8]))
    await writer.close()
  } catch (error) {
    await writer.abort(error)
    throw error
  }
}
</script>

Distributed Storage

<template>
  <div>
    <input v-model="key" placeholder="Key" />
    <input v-model="value" placeholder="Value" />
    <button @click="saveData">Save</button>
    <button @click="loadData">Load</button>
    
    <div v-for="[k, entry] in entries" :key="k">
      {{ k }}: {{ entry.value }}
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { usePeerPigeon, usePeerStorage } from 'pigeonnest'

const { mesh } = usePeerPigeon()
const { entries, set, get, list } = usePeerStorage()

const key = ref('')
const value = ref('')

const saveData = async () => {
  await set(mesh.value, key.value, value.value)
}

const loadData = async () => {
  const data = await get(mesh.value, key.value)
  value.value = data
}
</script>

API Reference

usePeerPigeon(options)

Main composable for managing the PeerPigeon mesh network.

Options:

  • peerId (string) - Custom peer ID
  • networkName (string) - Network namespace for isolation
  • maxPeers (number) - Maximum number of peer connections
  • minPeers (number) - Minimum number of peer connections
  • autoConnect (boolean) - Auto-connect when joining network
  • autoDiscovery (boolean) - Automatic peer discovery

Returns:

  • mesh - PeerPigeonMesh instance
  • status - Current network status
  • isConnected - Connection state
  • isInitialized - Initialization state
  • connectedPeerIds - Array of connected peer IDs
  • discoveredPeers - Array of discovered peers
  • error - Last error
  • init() - Initialize the mesh
  • connect(url) - Connect to signaling server
  • disconnect() - Disconnect from network
  • sendMessage(peerId, message) - Send message to peer
  • broadcast(message) - Broadcast to all peers
  • refreshStatus() - Refresh status information

usePeerStreaming()

Composable for handling file and data streaming (PigeonFS) using readable/writable streams.

Returns:

  • activeStreams - Map of active stream transfers
  • incomingStream - Current incoming stream
  • sendFile(mesh, peerId, file) - Send a File object
  • sendBlob(mesh, peerId, blob, options) - Send a Blob
  • sendStream(mesh, peerId, stream, options) - Send a ReadableStream (low-level API)
  • createStreamToPeer(mesh, peerId, options) - Create a WritableStream to peer (low-level API)
  • receiveStream(event) - Receive and process a stream
  • cancelStream(streamId) - Cancel an active stream

usePeerStorage()

Composable for distributed storage management.

Returns:

  • entries - Map of storage entries
  • loading - Loading state
  • error - Last error
  • set(mesh, key, value, ttl) - Store a value
  • get(mesh, key) - Retrieve a value
  • has(mesh, key) - Check if key exists
  • delete(mesh, key) - Delete a value
  • clear(mesh) - Clear all storage
  • list(mesh) - List all keys
  • refreshEntries(mesh) - Refresh all entries

Components

PeerConnectionStatus

Displays current connection status and network information.

Props:

  • status (PeerStatus | null) - Current peer status
  • isConnected (boolean) - Connection state

PeerList

List and manage connected peers.

Props:

  • peers (Array) - Array of peers or peer IDs
  • title (string) - List title
  • emptyMessage (string) - Message when no peers
  • showTimestamp (boolean) - Show connection time
  • showActions (boolean) - Show action buttons
  • selectedPeerId (string) - Currently selected peer

Events:

  • @select - Peer selected
  • @message - Send message clicked
  • @file - Send file clicked

FileUpload

Drag-and-drop file upload component.

Props:

  • multiple (boolean) - Allow multiple files
  • accept (string) - Accepted file types
  • targetPeerId (string) - Target peer for upload
  • primaryText (string) - Primary instruction text
  • secondaryText (string) - Secondary instruction text

Events:

  • @upload - Files ready to upload
  • @change - File selection changed

StreamProgress

Display progress of file transfers.

Props:

  • stream (StreamProgress) - Stream progress object
  • onCancel (boolean) - Show cancel button
  • onRetry (boolean) - Show retry button
  • onDismiss (boolean) - Show dismiss button

Events:

  • @cancel - Cancel transfer
  • @retry - Retry transfer
  • @dismiss - Dismiss completed transfer

Examples

See the examples/ directory for complete examples:

  • demo.html - Complete demo application showing all features

To run the demo:

# Start a PeerPigeon signaling server
npx peerpigeon hub

# In another terminal, serve the examples
npm run dev

# Open http://localhost:5173/examples/demo.html in multiple browser tabs

PeerPigeon Integration

PigeonNest is built on top of PeerPigeon 1.0.5. Key concepts:

  • PigeonHub - Signaling server for peer discovery (WebSocket-based)
  • PigeonFS - File system operations using readable/writable streams
  • Mesh Network - WebRTC-based peer-to-peer connections
  • Distributed Storage - Shared storage across peers with CRDTs

Browser Support

Requires browsers with:

  • WebRTC support
  • Web Streams API
  • ES2020+

Tested on:

  • Chrome 89+
  • Firefox 102+
  • Safari 14.1+
  • Edge 89+

Development

# Install dependencies
npm install

# Run dev server
npm run dev

# Build library
npm run build

# Run tests
npm test

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT © PeerPigeon Contributors

Links

Support

For issues and questions: