docs: full module READMEs (v0.8.103 platform audit)
This commit is contained in:
@@ -1,28 +1,128 @@
|
||||
# pearcord-guild
|
||||
|
||||
Guild CRUD, member mesh, and protomux gossip.
|
||||
Guild lifecycle, channel tree (including threads and forums), member joins, and the Hyperswarm gossip mesh for server-scoped realtime events.
|
||||
|
||||
Part of **[Pearcord](https://git.ssh.surf/pearcord)** — 100% peer-to-peer community chat on [Pear](https://pear.holepunch.to). No central servers.
|
||||
## Mission
|
||||
|
||||
Create and load guilds in local storage, join peers on `pearcord:guild:{guildId}` topics, fan out RPC gossip (messages, reactions, voice, roles, audit, …), and attach auxiliary protomux channels for attachments, voice media, and screen share.
|
||||
|
||||
## When to use / not
|
||||
|
||||
**Use when:**
|
||||
|
||||
- Implementing server creation, invite joins, channel CRUD, or guild-scoped P2P replication.
|
||||
- Extending gossip handlers (`_onGossip`) or adding new `RPC.*` fanout methods.
|
||||
|
||||
**Do not use when:**
|
||||
|
||||
- You only need a thin channel CRUD helper without mesh — see `pearcord-channel` (minimal; production path is this module).
|
||||
- You need DM conversations — use `pearcord-dm`.
|
||||
- You need the full desktop API — use `pearcord-platform`, which owns `PearcordGuild` instances.
|
||||
|
||||
## Public API
|
||||
|
||||
| Export | Role |
|
||||
|--------|------|
|
||||
| `PearcordGuild` | Main class (`EventEmitter`) |
|
||||
| `PearcordGuild#create({ name, iconHash? })` | New guild + owner member + `general` text + `Voice Lobby` |
|
||||
| `PearcordGuild#joinByInvite(invite, userId)` | Materialize guild/channels from invite; add member; bump invite uses |
|
||||
| `PearcordGuild#setActiveGuild(guild)` | Set `this.guild` for list/create operations |
|
||||
| `PearcordGuild#joinMesh()` / `#leaveMesh()` | Hyperswarm on `topicToBuffer(guild.topic)` |
|
||||
| `PearcordGuild#listChannels()` / `#listMembers()` | DB queries with thread meta attached |
|
||||
| `PearcordGuild#createChannel`, `#createCategory`, `#createThread`, `#createForumThread` | Channel tree |
|
||||
| `PearcordGuild#updateChannel`, `#ingestChannel` | Upsert + thread meta |
|
||||
| `PearcordGuild#setMessageHandler(fn)` | Inbound `RPC.MESSAGE_CREATE` persistence hook (platform sets this) |
|
||||
| `PearcordGuild#gossip*` / `#sendVoiceMedia` / `#sendScreenMedia` | Outbound RPC (see `index.js` for full list) |
|
||||
| `PearcordGuild#simulateGossip(method, payload)` | Bare smoke injection without live peers |
|
||||
| `PearcordGuild#getStats()` | `{ guildId, peers, openGossip, topic }` |
|
||||
| `PearcordGuild#fetchAttachmentFromPeers` | P2P attachment pull via `pearcord-drive` |
|
||||
| `PearcordGuild#setVoiceMediaHub` / `#setScreenShareHub` / `#setAttachmentProvider` | Wire media meshes |
|
||||
| `./mesh` | `attachGossipMesh`, `broadcastGossip`, `GOSSIP_PROTOCOL` |
|
||||
|
||||
## P2P surface
|
||||
|
||||
| Protocol | Transport | Purpose |
|
||||
|----------|-----------|---------|
|
||||
| `pearcord-gossip-v1` | Protomux on Hyperswarm connection | JSON payloads in `encodeRpc` frames; handler `_onGossip` |
|
||||
| Drive attach mesh | `pearcord-drive/attach-mesh` | Binary attachment fetch |
|
||||
| Voice media | `pearcord-voice-media` | Live audio frames |
|
||||
| Screen share | `pearcord-screen-share` | Display frames |
|
||||
|
||||
Topic: `guildTopic(guildId)` → `topicToBuffer` for `swarm.join`. Server and client mode enabled.
|
||||
|
||||
Inbound events emitted include: `message`, `message-delete`, `presence`, `typing`, `reaction`, `channel`, `channel-update`, `member`, `guild-sync`, `voice-state`, `peer`, and many feature-specific events (audit, bots, stickers, …).
|
||||
|
||||
## Storage
|
||||
|
||||
Uses shared `LocalDatabase` (`opts.db` or `opts.dbPath`):
|
||||
|
||||
- `@pearcord/guilds`, `channels`, `members`, `messages`, `invites`, `thread-meta`, `bans`, etc.
|
||||
|
||||
Guild rows include `topic: pearcord:guild:{id}` for swarm discovery.
|
||||
|
||||
## Platform integration
|
||||
|
||||
```javascript
|
||||
const { PearcordGuild } = require('pearcord-guild')
|
||||
|
||||
// createGuild / loadGuild / joinInvite:
|
||||
this.guild = new PearcordGuild({ ownerId, userId, db: this.db })
|
||||
await this.guild.ready()
|
||||
this.guild.setActiveGuild(guildRecord)
|
||||
this._wireGuild(this.guild) // setMessageHandler + event bridges
|
||||
await this.guild.joinMesh()
|
||||
```
|
||||
|
||||
`_wireGuild` connects gossip to platform `emit('message')`, search indexing, bot fanout, and `db.insert`. Outbound sends use `this.guild.gossipMessage(msg)` from `sendMessage` / edits / deletes.
|
||||
|
||||
Channel creation in production uses `guild.createChannel` / `createCategory`, not `pearcord-channel`.
|
||||
|
||||
## UI / IPC
|
||||
|
||||
Indirect only. IPC `create-guild`, `select-guild`, `join-invite`, `send-message`, voice join, etc. all route through platform methods that delegate to `PearcordGuild`.
|
||||
|
||||
## Related docs
|
||||
|
||||
- [GUILD_SYNC.md](../../docs/GUILD_SYNC.md) — history bundle on peer join
|
||||
- [VOICE.md](../../docs/VOICE.md) — `RPC.VOICE_STATE`
|
||||
- [VOICE_MEDIA.md](../../docs/VOICE_MEDIA.md) — media mesh
|
||||
- [ATTACH_MESH_LIVE.md](../../docs/ATTACH_MESH_LIVE.md) — attachment gossip
|
||||
- [MESSAGE_THREADS.md](../../docs/MESSAGE_THREADS.md) — thread channels
|
||||
- [FORUM_CHANNELS.md](../../docs/FORUM_CHANNELS.md) — forum posts
|
||||
- [MODERATION.md](../../docs/MODERATION.md) — bans, kicks, audit RPC
|
||||
- [MODULES.md](../../docs/MODULES.md)
|
||||
- [IPC.md](../../docs/IPC.md)
|
||||
|
||||
## Tests
|
||||
|
||||
- `apps/pearcord`: `npm run test:guild-sync` — `smoke-guild-sync.cjs`
|
||||
- `smoke-guild-settings.cjs`, `smoke-guild-deep-link.cjs`
|
||||
- Many mesh smokes call `platform.guild.simulateGossip(RPC.*, payload)`
|
||||
|
||||
## Code example
|
||||
|
||||
```javascript
|
||||
const { PearcordGuild } = require('pearcord-guild')
|
||||
const { LocalDatabase } = require('pearcord-db')
|
||||
const Hyperswarm = require('hyperswarm')
|
||||
|
||||
const db = new LocalDatabase('./pearcord-storage/db')
|
||||
const guild = new PearcordGuild({ ownerId: 'user-1', userId: 'user-1', db })
|
||||
await guild.ready()
|
||||
|
||||
const { guild: g, channels } = await guild.create({ name: 'My Server' })
|
||||
guild.setMessageHandler(async (msg) => {
|
||||
await db.insert(require('pearcord-shared').COLLECTIONS.MESSAGES, msg)
|
||||
return msg
|
||||
})
|
||||
await guild.joinMesh()
|
||||
guild.gossipTyping({ userId: 'user-1', channelId: channels[0].id, guildId: g.id, at: Date.now() })
|
||||
```
|
||||
|
||||
## Repository
|
||||
|
||||
Part of **[Pearcord](https://git.ssh.surf/pearcord)**.
|
||||
|
||||
- **Org:** [`pearcord`](https://git.ssh.surf/pearcord)
|
||||
- **Clone:** `git clone https://git.ssh.surf/pearcord/pearcord-guild.git`
|
||||
|
||||
## Install (npm)
|
||||
|
||||
```bash
|
||||
npm install git+https://git.ssh.surf/pearcord/pearcord-guild.git#main
|
||||
```
|
||||
|
||||
## Stack
|
||||
|
||||
Hyperswarm · HyperDB · Protomux · Pear / Bare
|
||||
|
||||
## Documentation
|
||||
|
||||
See [`pearcord/pearcord-docs`](https://git.ssh.surf/pearcord/pearcord-docs) for architecture, roadmap, and IPC reference.
|
||||
|
||||
## License
|
||||
|
||||
Pearcord modules are developed for the Pearcord platform. See the org README for contribution guidelines.
|
||||
- **Install:** `npm install git+https://git.ssh.surf/pearcord/pearcord-guild.git#main`
|
||||
|
||||
@@ -338,6 +338,9 @@ class PearcordGuild extends EventEmitter {
|
||||
if (method === RPC.VOICE_MEDIA_LEAVE) {
|
||||
this.emit('voice-media-leave', payload)
|
||||
}
|
||||
if (method === RPC.VOICE_SPEAKING) {
|
||||
this.emit('voice-speaking', payload)
|
||||
}
|
||||
if (method === RPC.SLASH_COMMAND_UPSERT) {
|
||||
this.emit('slash-command', payload)
|
||||
}
|
||||
@@ -683,6 +686,10 @@ class PearcordGuild extends EventEmitter {
|
||||
broadcastGossip(this, RPC.VOICE_MEDIA_LEAVE, payload)
|
||||
}
|
||||
|
||||
gossipVoiceSpeaking (payload) {
|
||||
broadcastGossip(this, RPC.VOICE_SPEAKING, payload)
|
||||
}
|
||||
|
||||
gossipSlashCommand (row) {
|
||||
broadcastGossip(this, RPC.SLASH_COMMAND_UPSERT, row)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user