dignity.js 0.1.0

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.
@@ -0,0 +1,112 @@
1
+ const { DignityP2P, InMemoryNetworkHub, InMemoryNetworkAdapter } = require('../src');
2
+
3
+ function printBoard(cells) {
4
+ const safe = cells.map((v) => (v === null ? ' ' : v));
5
+ console.log(`\n ${safe[0]} | ${safe[1]} | ${safe[2]} `);
6
+ console.log('---+---+---');
7
+ console.log(` ${safe[3]} | ${safe[4]} | ${safe[5]} `);
8
+ console.log('---+---+---');
9
+ console.log(` ${safe[6]} | ${safe[7]} | ${safe[8]} `);
10
+ }
11
+
12
+ async function runDemo() {
13
+ const hub = new InMemoryNetworkHub();
14
+
15
+ const alice = new DignityP2P({
16
+ nodeId: 'alice',
17
+ networkAdapter: new InMemoryNetworkAdapter(hub),
18
+ security: {
19
+ appPassword: 'demo-shared-password',
20
+ powTargetMs: 100
21
+ }
22
+ });
23
+
24
+ const bob = new DignityP2P({
25
+ nodeId: 'bob',
26
+ networkAdapter: new InMemoryNetworkAdapter(hub),
27
+ security: {
28
+ appPassword: 'demo-shared-password',
29
+ powTargetMs: 100
30
+ }
31
+ });
32
+
33
+ await alice.start();
34
+ await bob.start();
35
+ await alice.joinDiscovery('room:tictactoe', {
36
+ metadata: { nickname: 'alice', role: 'host' },
37
+ heartbeatIntervalMs: 100000,
38
+ ttlMs: 30000
39
+ });
40
+ await bob.joinDiscovery('room:tictactoe', {
41
+ metadata: { nickname: 'bob', role: 'guest' },
42
+ heartbeatIntervalMs: 100000,
43
+ ttlMs: 30000
44
+ });
45
+
46
+ console.log(
47
+ '\nPeers visible from Alice in room:tictactoe:',
48
+ alice.listPeers('room:tictactoe', { includeSelf: false }).map((peer) => peer.peerId)
49
+ );
50
+
51
+ await alice.create(
52
+ 'games',
53
+ {
54
+ type: 'tictactoe',
55
+ board: Array(9).fill(null),
56
+ nextPlayer: 'alice',
57
+ players: ['alice', 'bob']
58
+ },
59
+ { id: 'ttt-1', broadcastScope: 'room:tictactoe' }
60
+ );
61
+
62
+ // Owner-updated canonical state for v0.1.0:
63
+ // participants can propose moves, while owner commits official updates.
64
+ const moves = [
65
+ { actor: alice, playerId: 'alice', index: 0, mark: 'X' },
66
+ { actor: alice, playerId: 'alice', index: 4, mark: 'O' },
67
+ { actor: alice, playerId: 'alice', index: 8, mark: 'X' }
68
+ ];
69
+
70
+ for (const move of moves) {
71
+ const game = move.actor.read('games', 'ttt-1');
72
+ const board = [...game.data.board];
73
+ board[move.index] = move.mark;
74
+
75
+ const nextPlayer = move.playerId === 'alice' ? 'bob' : 'alice';
76
+ await move.actor.update(
77
+ 'games',
78
+ 'ttt-1',
79
+ {
80
+ board,
81
+ nextPlayer,
82
+ lastMove: { by: move.playerId, index: move.index, mark: move.mark }
83
+ },
84
+ { broadcastScope: 'room:tictactoe' }
85
+ );
86
+ }
87
+
88
+ try {
89
+ await bob.update('games', 'ttt-1', { illegal: true });
90
+ } catch (error) {
91
+ console.log('\\nExpected owner rule:', error.message);
92
+ }
93
+
94
+ const finalFromAlice = alice.read('games', 'ttt-1');
95
+ const finalFromBob = bob.read('games', 'ttt-1');
96
+
97
+ console.log('\nFinal board from Alice node:');
98
+ printBoard(finalFromAlice.data.board);
99
+
100
+ console.log('\nReplicated board from Bob node:');
101
+ printBoard(finalFromBob.data.board);
102
+
103
+ await alice.leaveDiscovery('room:tictactoe');
104
+ await bob.leaveDiscovery('room:tictactoe');
105
+ await alice.stop();
106
+ await bob.stop();
107
+ }
108
+
109
+ runDemo().catch((error) => {
110
+ console.error(error);
111
+ process.exitCode = 1;
112
+ });
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "dignity.js",
3
+ "version": "0.1.0",
4
+ "description": "P2P object API for decentralized JavaScript applications",
5
+ "main": "dist/dignity.cjs.js",
6
+ "module": "dist/dignity.esm.js",
7
+ "browser": "dist/dignity.esm.js",
8
+ "unpkg": "dist/dignity.min.js",
9
+ "jsdelivr": "dist/dignity.min.js",
10
+ "exports": {
11
+ ".": {
12
+ "require": "./dist/dignity.cjs.js",
13
+ "import": "./dist/dignity.esm.js",
14
+ "default": "./dist/dignity.esm.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "src",
20
+ "docs",
21
+ "examples"
22
+ ],
23
+ "scripts": {
24
+ "test": "jest --coverage",
25
+ "test:unit": "jest tests/unit --runInBand",
26
+ "test:pow-calibrate": "jest tests/unit/sloth-vdf-timing.test.js --runInBand",
27
+ "build": "node scripts/build.js",
28
+ "docs:serve": "npx http-server docs -p 4173 -o",
29
+ "docs:check": "node -e \"require('fs').accessSync('docs/index.html')\"",
30
+ "example:tictactoe": "node examples/decentralized-tictactoe.js",
31
+ "example:chess": "node examples/decentralized-chess-lite.js",
32
+ "prepublishOnly": "npm test && npm run build"
33
+ },
34
+ "keywords": [
35
+ "p2p",
36
+ "webrtc",
37
+ "decentralized",
38
+ "rest",
39
+ "objects"
40
+ ],
41
+ "license": "MIT",
42
+ "devDependencies": {
43
+ "esbuild": "^0.28.0",
44
+ "jest": "^29.7.0"
45
+ },
46
+ "dependencies": {
47
+ "tweetnacl": "^1.0.3",
48
+ "tweetnacl-util": "^0.15.1"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ }
53
+ }