{
  "name": "dignity.js",
  "version": "0.5.2",
  "description": "REST-like object API over peer-to-peer replication",
  "resources": {
    "collections/{collection}/{id}": {
      "create": {
        "method": "create(collection, data, options)",
        "owner": "actor that creates the object",
        "options": {
          "id": "optional stable id",
          "collaborators": "optional peer id list",
          "broadcastScope": "scoped broadcast password namespace",
          "connectToPeers": "optional; defaults to collaborators on PeerJS mesh"
        }
      },
      "read": {
        "method": "read(collection, id)"
      },
      "update": {
        "method": "update(collection, id, patch, options)",
        "authorization": "owner or collaborator",
        "options": {
          "expectedVersion": "optional number; throws VERSION_CONFLICT when mismatched",
          "broadcastScope": "optional scoped broadcast password namespace",
          "collaborators": "owner may replace collaborator list",
          "connectToPeers": "optional; defaults to owner + collaborators"
        }
      },
      "updateWithRetry": {
        "method": "updateWithRetry(collection, id, patchFn, options)",
        "description": "read-modify-write helper with automatic retry on version conflicts"
      },
      "pushRecordSnapshot": {
        "method": "pushRecordSnapshot(collection, id, options)",
        "description": "broadcast full record for late joiners who missed the initial create"
      },
      "getRecordPeerIds": {
        "method": "getRecordPeerIds(collection, id, options)",
        "description": "returns owner + collaborator peer ids for connectToPeers"
      },
      "delete": {
        "method": "remove(collection, id)",
        "authorization": "owner-only"
      }
    },
    "collections/{collection}": {
      "list": {
        "method": "list(collection, options)"
      }
    },
    "peers": {
      "connectToPeer": "open PeerJS data channel to peer id",
      "getConnectionStats": "{ openCount, peerIds }",
      "ensureConnectedToPeers": "connect to many peers before broadcast",
      "joinDiscovery": "scoped presence; options.bootstrapPeerIds connects before announce",
      "broadcastMessage": "custom app messages; options.connectToPeers"
    }
  },
  "events": {
    "change": "object create/update/delete/snapshot applied",
    "conflict": "local or remote version mismatch",
    "warning": "orphan-operation, peer-connect-failed, presence failures",
    "peerdiscovered": "peer joined discovery scope",
    "peerleft": "peer left or timed out",
    "message": "custom decrypted message received"
  },
  "persistence": {
    "IndexedDBPersistence": {
      "method": "attach(node)",
      "options": [
        "dbName",
        "storeName",
        "collections"
      ]
    }
  },
  "react": {
    "entrypoint": "dignity.js/react",
    "hooks": [
      "useDignity",
      "useCollection",
      "useObject",
      "usePeers",
      "useDiscovery",
      "useConnectionStats",
      "useRoom",
      "useMessages"
    ]
  },
  "signaling": {
    "defaults": {
      "cloudflare": "enabled by default",
      "fallback": "enabled"
    },
    "customization": {
      "factory": "createDefaultSignalingPool(options)",
      "override": [
        "cloudflareUrls",
        "fallbackUrls",
        "customProviders"
      ]
    }
  },
  "messageSecurity": {
    "defaults": {
      "signingEnabled": true,
      "encryptionEnabled": true,
      "powEnabled": true,
      "powSteps": 22,
      "powTargetMs": 1000,
      "kdfIterations": 100000,
      "banDurationMs": 172800000
    },
    "broadcast": {
      "encryption": "AES secretbox with PBKDF2-SHA256 derived key",
      "scopePasswords": "broadcastPasswords map keyed by broadcastScope",
      "legacyKdf": "single-hash fallback accepted for older peers"
    },
    "direct": {
      "encryption": "NaCl box (X25519 + XSalsa20-Poly1305) to recipient public key"
    },
    "pow": {
      "algorithm": "Sloth VDF",
      "config": [
        "powTargetMs",
        "powSteps"
      ]
    }
  }
}
