dignity.js 0.7.0 → 0.7.1

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.
@@ -144,8 +144,10 @@ const bob = new DignityP2P({ nodeId: 'bob', networkAdapter: new InMemoryNetworkA
144
144
  helpers.track(alice, bob);
145
145
 
146
146
  let received = null;
147
- bob.on('directmessage', (event) => {
148
- received = event.payload;
147
+ bob.on('message', (event) => {
148
+ if (event.senderId === 'alice' && event.type === 'chat') {
149
+ received = event.payload;
150
+ }
149
151
  });
150
152
 
151
153
  await alice.start();
@@ -321,11 +323,13 @@ const rotationResult = await revokeAndRotateIdentity({
321
323
  await alice.start();
322
324
  await bob.start();
323
325
 
326
+ await alice.adoptDerivedIdentityKeyPair(gen1, { generation: 1 });
324
327
  bob.registerPeerPublicKey('alice', keyPairToPublicBundle(gen1), { generation: 1 });
325
328
  log('bob gen before:', bob.getPeerIdentityGeneration('alice'));
326
329
 
327
- await alice.adoptDerivedIdentityKeyPair(rotationResult.nextKeyPair, { generation: 2 });
330
+ // Broadcast while alice still signs with gen-1 keys; then adopt gen-2 locally.
328
331
  await alice.broadcastIdentityRotation(rotationResult.rotation, { broadcastScope: 'identity:alice' });
332
+ await alice.adoptDerivedIdentityKeyPair(rotationResult.nextKeyPair, { generation: 2 });
329
333
  await helpers.sleep(50);
330
334
 
331
335
  log('bob gen after:', bob.getPeerIdentityGeneration('alice'));
@@ -155,20 +155,68 @@
155
155
  color: #cf222e;
156
156
  }
157
157
 
158
- #code-editor {
158
+ .playground-editor-wrap {
159
+ position: relative;
159
160
  flex: 1;
161
+ min-height: 360px;
162
+ overflow: hidden;
163
+ display: grid;
164
+ background: var(--bg);
165
+ }
166
+
167
+ .playground-editor-highlight,
168
+ #code-editor {
169
+ grid-area: 1 / 1;
160
170
  width: 100%;
171
+ height: 100%;
161
172
  min-height: 360px;
162
173
  margin: 0;
163
174
  padding: 16px;
164
175
  border: 0;
165
- resize: none;
166
176
  font-family: var(--font-mono);
167
177
  font-size: 0.875rem;
168
178
  line-height: 1.55;
169
- color: var(--text);
170
- background: var(--bg);
171
179
  tab-size: 2;
180
+ overflow: auto;
181
+ white-space: pre;
182
+ word-wrap: normal;
183
+ overflow-wrap: normal;
184
+ box-sizing: border-box;
185
+ }
186
+
187
+ .playground-editor-highlight {
188
+ pointer-events: none;
189
+ z-index: 0;
190
+ background: var(--bg);
191
+ color: var(--text);
192
+ }
193
+
194
+ .playground-editor-highlight code {
195
+ display: block;
196
+ min-height: calc(100% - 32px);
197
+ padding: 0;
198
+ margin: 0;
199
+ font: inherit;
200
+ line-height: inherit;
201
+ background: transparent !important;
202
+ border: 0 !important;
203
+ border-radius: 0 !important;
204
+ color: inherit;
205
+ }
206
+
207
+ .playground-editor-highlight code.hljs {
208
+ padding: 0 !important;
209
+ border: 0 !important;
210
+ border-left: 0 !important;
211
+ }
212
+
213
+ #code-editor {
214
+ resize: none;
215
+ z-index: 1;
216
+ color: transparent !important;
217
+ -webkit-text-fill-color: transparent !important;
218
+ caret-color: var(--text);
219
+ background: transparent;
172
220
  }
173
221
 
174
222
  #code-editor:focus {
@@ -176,6 +224,24 @@
176
224
  box-shadow: inset 0 0 0 2px var(--accent-soft);
177
225
  }
178
226
 
227
+ #code-editor::selection {
228
+ background: rgba(91, 127, 255, 0.35);
229
+ color: transparent;
230
+ -webkit-text-fill-color: transparent;
231
+ }
232
+
233
+ @media (prefers-color-scheme: dark) {
234
+ .playground-editor-wrap,
235
+ .playground-editor-highlight {
236
+ background: #0d1117;
237
+ color: #e6edf3;
238
+ }
239
+
240
+ #code-editor {
241
+ caret-color: #e6edf3;
242
+ }
243
+ }
244
+
179
245
  #output {
180
246
  flex: 1;
181
247
  min-height: 360px;
@@ -6,6 +6,8 @@ const els = {
6
6
  featureSelect: document.getElementById('feature-select'),
7
7
  featureDesc: document.getElementById('feature-desc'),
8
8
  editor: document.getElementById('code-editor'),
9
+ highlightCode: document.getElementById('code-highlight'),
10
+ highlightPre: document.querySelector('.playground-editor-highlight'),
9
11
  runBtn: document.getElementById('run-btn'),
10
12
  resetBtn: document.getElementById('reset-btn'),
11
13
  clearBtn: document.getElementById('clear-btn'),
@@ -13,6 +15,8 @@ const els = {
13
15
  status: document.getElementById('run-status')
14
16
  };
15
17
 
18
+ let highlightTimer = null;
19
+
16
20
  let activeCleanup = null;
17
21
  let running = false;
18
22
 
@@ -26,10 +30,48 @@ function populateFeatureSelect() {
26
30
  ).join('');
27
31
  }
28
32
 
33
+ function syncEditorScroll() {
34
+ if (!els.highlightPre) {
35
+ return;
36
+ }
37
+ els.highlightPre.scrollTop = els.editor.scrollTop;
38
+ els.highlightPre.scrollLeft = els.editor.scrollLeft;
39
+ }
40
+
41
+ function updateHighlight() {
42
+ if (!els.highlightCode || typeof hljs === 'undefined') {
43
+ return;
44
+ }
45
+
46
+ const source = els.editor.value;
47
+ els.highlightCode.textContent = source.endsWith('\n') ? source : `${source}\n`;
48
+
49
+ if (typeof hljs.highlight === 'function') {
50
+ const { value } = hljs.highlight(source, { language: 'javascript' });
51
+ els.highlightCode.innerHTML = value;
52
+ els.highlightCode.classList.add('hljs', 'language-javascript');
53
+ } else {
54
+ hljs.highlightElement(els.highlightCode);
55
+ }
56
+
57
+ syncEditorScroll();
58
+ }
59
+
60
+ function scheduleHighlight() {
61
+ if (highlightTimer) {
62
+ cancelAnimationFrame(highlightTimer);
63
+ }
64
+ highlightTimer = requestAnimationFrame(() => {
65
+ highlightTimer = null;
66
+ updateHighlight();
67
+ });
68
+ }
69
+
29
70
  function loadDemo(demo, { pushHash = true } = {}) {
30
71
  els.featureSelect.value = demo.id;
31
72
  els.featureDesc.textContent = demo.description;
32
73
  els.editor.value = demo.code;
74
+ scheduleHighlight();
33
75
  if (pushHash) {
34
76
  history.replaceState(null, '', `#${demo.id}`);
35
77
  }
@@ -151,7 +193,10 @@ async function runCode() {
151
193
  }
152
194
  }
153
195
 
154
- function initEditorTabs() {
196
+ function initEditor() {
197
+ els.editor.addEventListener('input', scheduleHighlight);
198
+ els.editor.addEventListener('scroll', syncEditorScroll);
199
+
155
200
  els.editor.addEventListener('keydown', (event) => {
156
201
  if (event.key !== 'Tab') {
157
202
  return;
@@ -161,6 +206,7 @@ function initEditorTabs() {
161
206
  const next = `${value.slice(0, selectionStart)} ${value.slice(selectionEnd)}`;
162
207
  els.editor.value = next;
163
208
  els.editor.selectionStart = els.editor.selectionEnd = selectionStart + 2;
209
+ scheduleHighlight();
164
210
  });
165
211
  }
166
212
 
@@ -172,7 +218,8 @@ function initFromHash() {
172
218
 
173
219
  populateFeatureSelect();
174
220
  initFromHash();
175
- initEditorTabs();
221
+ initEditor();
222
+ updateHighlight();
176
223
 
177
224
  els.featureSelect.addEventListener('change', () => {
178
225
  loadDemo(getDemoById(els.featureSelect.value));
@@ -14,7 +14,7 @@
14
14
  --green: #1a7f37;
15
15
  --green-bg: #dafbe1;
16
16
  --sidebar-width: 280px;
17
- --header-height: 56px;
17
+ --header-height: 64px;
18
18
  --content-max: 920px;
19
19
  --radius: 8px;
20
20
  --shadow: 0 1px 3px rgba(27, 31, 36, 0.08);
@@ -135,7 +135,7 @@ pre code.hljs {
135
135
  }
136
136
 
137
137
  .site-header__brand img {
138
- height: 40px;
138
+ height: 54px;
139
139
  width: auto;
140
140
  }
141
141
 
package/docs/index.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta name="description" content="dignity.js v0.6.0 — REST-like P2P object API for decentralized JavaScript applications." />
6
+ <meta name="description" content="dignity.js v0.7.1 — REST-like P2P object API for decentralized JavaScript applications." />
7
7
  <title>dignity.js · Documentation</title>
8
8
  <link rel="icon" href="./assets/favicon.svg" type="image/svg+xml" />
9
9
  <link rel="icon" href="./favicon.ico" sizes="32x32" />
@@ -16,7 +16,7 @@
16
16
  <a class="site-header__brand" href="#overview">
17
17
  <img src="./assets/dignity-logo.svg" alt="" width="344" height="80" />
18
18
  <!-- <span>dignity.js</span> -->
19
- <span class="site-header__version">v0.6.0</span>
19
+ <span class="site-header__version">v0.7.1</span>
20
20
  </a>
21
21
  <div class="site-header__links">
22
22
  <a href="https://www.npmjs.com/package/dignity.js" target="_blank" rel="noopener noreferrer">npm</a>
@@ -591,6 +591,8 @@ node.getPeerGroupStats();
591
591
  </div>
592
592
 
593
593
  <h3>Roadmap</h3>
594
+ <p><strong>v0.7.1 (current)</strong> — live docs playground, demo fixes, syntax highlighting.</p>
595
+ <p><strong>v0.7.0 (shipped)</strong> — credential-derived keys, identity rotation, PeerGroup hardening, stress harness.</p>
594
596
  <p><strong>v0.6.0 (shipped)</strong> — core gossip, chess spectators, unit + e2e tests.</p>
595
597
  <p><strong>v0.6.x polish</strong> — <code>subscribeObjectFeed</code> wrapper, connection LRU trim, IndexedDB joined-group persistence, React <code>usePeerGroup</code> hook, 50+ node integration test.</p>
596
598
  <p><strong>Future</strong> — publisher rate limits, partial snapshot / delta feeds, cross-group fan-in metrics.</p>
@@ -983,7 +985,7 @@ npm run example:chess</code></pre>
983
985
 
984
986
  <footer class="site-footer">
985
987
  <p>
986
- dignity.js v0.6.0 ·
988
+ dignity.js v0.7.1 ·
987
989
  <a href="https://github.com/jose-compu/dignity.js/blob/main/LICENSE">Apache 2.0</a> ·
988
990
  <a href="https://github.com/jose-compu/dignity.js">GitHub</a> ·
989
991
  <a href="https://www.npmjs.com/package/dignity.js">npm</a>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dignity.js",
3
- "version": "0.5.4",
3
+ "version": "0.7.1",
4
4
  "description": "REST-like object API over peer-to-peer replication",
5
5
  "resources": {
6
6
  "collections/{collection}/{id}": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dignity.js",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "P2P object API for decentralized JavaScript applications",
5
5
  "homepage": "https://jose-compu.github.io/dignity.js/",
6
6
  "repository": {