dignity.js 0.4.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +83 -2
  2. package/dist/dignity.cjs.js +542 -21
  3. package/dist/dignity.cjs.js.map +4 -4
  4. package/dist/dignity.esm.js +542 -21
  5. package/dist/dignity.esm.js.map +3 -3
  6. package/dist/dignity.min.js +18 -18
  7. package/docs/assets/dignity.esm.js +11205 -0
  8. package/docs/assets/favicon.svg +8 -0
  9. package/docs/chess/assets/chess-app.js +58022 -0
  10. package/docs/chess/assets/chess-app.js.map +7 -0
  11. package/docs/chess/assets/chess.css +584 -0
  12. package/docs/chess/favicon.ico +0 -0
  13. package/docs/chess/index.html +16 -0
  14. package/docs/chess/src/App.jsx +128 -0
  15. package/docs/chess/src/components/Board3D.jsx +364 -0
  16. package/docs/chess/src/components/GameView.jsx +847 -0
  17. package/docs/chess/src/components/JoinGate.jsx +68 -0
  18. package/docs/chess/src/components/LinkPanel.jsx +132 -0
  19. package/docs/chess/src/components/Lobby.jsx +154 -0
  20. package/docs/chess/src/components/MovePanel.jsx +123 -0
  21. package/docs/chess/src/lib/audio.js +50 -0
  22. package/docs/chess/src/lib/dignitySetup.js +42 -0
  23. package/docs/chess/src/lib/links.js +124 -0
  24. package/docs/chess/src/lib/localGames.js +160 -0
  25. package/docs/chess/src/lib/p2pDebug.js +192 -0
  26. package/docs/chess/src/main.jsx +5 -0
  27. package/docs/favicon.ico +0 -0
  28. package/docs/index.html +7 -3
  29. package/docs/openapi-like.json +35 -6
  30. package/examples/decentralized-chess-lite.js +52 -30
  31. package/package.json +13 -5
  32. package/src/core/dignity-p2p.js +388 -16
  33. package/src/index.js +6 -0
  34. package/src/network/peerjs-network.js +234 -0
  35. package/src/persistence/indexeddb-persistence.js +2 -0
  36. package/src/react/index.js +143 -1
  37. package/src/signaling/parse-peerjs-url.js +24 -0
  38. package/src/signaling/peerjs-signaling-provider.js +2 -8
package/README.md CHANGED
@@ -37,6 +37,9 @@ REST-like P2P object API for decentralized JavaScript applications.
37
37
  - automatic peer ban on invalid signature/PoW (`48h` default)
38
38
  - Team/subapp scoped broadcast passwords (`broadcastScope` + `broadcastPasswords`)
39
39
  - Optimistic concurrency helpers (`expectedVersion`, `updateWithRetry`, `conflict` events)
40
+ - PeerJS mesh bootstrap: connect before announce/broadcast, auto `publicKey` in presence
41
+ - Late-joiner sync via `pushRecordSnapshot` (full record catch-up when create was missed)
42
+ - Auto `connectToPeers` on create/update/delete replication (owner + collaborators)
40
43
  - Optional IndexedDB persistence for browser reload survival
41
44
  - Optional React hooks via `dignity.js/react`
42
45
  - Browser-first: published npm package includes IIFE, ESM, and CJS builds
@@ -238,21 +241,99 @@ Compatibility note:
238
241
  - `dignity.js` now includes a dedicated `PeerJSSignalingProvider` backed by the official `peerjs` client for PeerJS protocol compatibility.
239
242
  - In non-WebRTC runtimes (for example Node test runners), it automatically falls back to WebSocket transport checks for connectivity testing.
240
243
 
244
+ ### PeerJS mesh bootstrap
245
+
246
+ Unlike the in-memory test adapter (which fan-outs to every registered node), **PeerJS only delivers messages over open data channels**. Discovery broadcasts do not reach anyone until at least one side has connected.
247
+
248
+ For browser apps (see the bundled 3D chess demo), pass a known peer id from your invite link:
249
+
250
+ ```js
251
+ await node.joinDiscovery('room:my-game', {
252
+ metadata: { nickname: 'alice', role: 'host' },
253
+ bootstrapPeerIds: ['host-peer-id-from-link']
254
+ });
255
+
256
+ await node.broadcastMessage('claim-seat', payload, {
257
+ broadcastScope: 'room:my-game',
258
+ connectToPeers: ['host-peer-id-from-link']
259
+ });
260
+ ```
261
+
262
+ Library helpers:
263
+
264
+ - `node.connectToPeer(peerId)` — open a PeerJS data channel
265
+ - `node.getConnectionStats()` — `{ openCount, peerIds }`
266
+ - `node.getRecordPeerIds(collection, id)` — owner + collaborators (for custom broadcasts)
267
+ - `node.joinDiscovery(scope, { bootstrapPeerIds })` — connect before the first presence announce
268
+ - `broadcastMessage(..., { connectToPeers })` — connect, then broadcast
269
+ - `node.pushRecordSnapshot(collection, id, options)` — send full record state to late joiners
270
+ - `create` / `update` / `remove` auto-connect to record peers when `connectToPeers` is omitted
271
+ - Presence metadata automatically includes `publicKey`; remote keys are trusted from presence and message envelopes (direct messages work without manual `registerPeerPublicKey`)
272
+
273
+ React: `useRoom(node, scope, options)` combines discovery, peers, and connection stats.
274
+
275
+ ### Late joiners (missed create)
276
+
277
+ On PeerJS, a peer that comes online **after** the host creates an object never receives the initial `create` operation. Later `update` operations are ignored until that peer has a local copy of the record.
278
+
279
+ After accepting a joiner (or on `orphan-operation` warnings), push a full snapshot:
280
+
281
+ ```js
282
+ node.on('warning', (event) => {
283
+ if (event.type === 'orphan-operation') {
284
+ // optional: request resync from owner
285
+ }
286
+ });
287
+
288
+ await host.update('chess-matches', gameId, { blackPlayerId: joinerId, status: 'playing' }, {
289
+ collaborators: [hostId, joinerId],
290
+ broadcastScope: scope
291
+ });
292
+
293
+ await host.pushRecordSnapshot('chess-matches', gameId, {
294
+ broadcastScope: scope,
295
+ connectToPeers: [joinerId]
296
+ });
297
+ ```
298
+
299
+ The joiner applies the snapshot via `restoreRecord`, then subsequent move updates replicate normally.
300
+
241
301
  ## Development
242
302
 
243
303
  ```bash
244
304
  npm test
245
305
  npm run build
246
- npm run docs:serve
306
+ npm run docs:dev # docs + 3D chess at http://127.0.0.1:4173/
307
+ npm run docs:build # rebuild chess bundle only
247
308
  npm run example:tictactoe
248
309
  npm run example:chess
249
310
  npm run test:pow-calibrate
250
311
  ```
251
312
 
313
+ Local docs (auto-builds chess if `docs/chess/assets/chess-app.js` is missing):
314
+
315
+ ```bash
316
+ npm run docs:dev
317
+ # Docs: http://127.0.0.1:4173/
318
+ # Chess: http://127.0.0.1:4173/chess/
319
+ ```
320
+
321
+ Use `DOCS_NO_OPEN=1 npm run docs:dev` to skip opening the browser, or `DOCS_PORT=8080` for another port.
322
+
323
+ If port 4173 is stuck from an old session:
324
+
325
+ ```bash
326
+ npm run docs:stop
327
+ npm run docs:dev
328
+ ```
329
+
330
+ If 4173 is busy, `docs:dev` auto-picks the next free port (4174, 4175, …) and prints the URLs.
331
+
252
332
  ## Docs and Examples
253
333
 
254
334
  - **Documentation:** [jose-compu.github.io/dignity.js](https://jose-compu.github.io/dignity.js/)
255
- - Docs site source: `docs/index.html` (serve locally with `npm run docs:serve`)
335
+ - Docs site source: `docs/index.html` (local: `npm run docs:dev`)
336
+ - **3D Chess demo:** `docs/chess/` → [local chess demo](http://127.0.0.1:4173/chess/) when `docs:dev` is running
256
337
  - API metadata: `docs/openapi-like.json`
257
338
  - Minimal demos:
258
339
  - `examples/decentralized-tictactoe.js`