@aiam/ciba 0.8.2 → 0.8.3

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 (2) hide show
  1. package/ciba.mjs +15 -5
  2. package/package.json +1 -1
package/ciba.mjs CHANGED
@@ -496,10 +496,6 @@ function startDaemon(provider, deviceDoc, privateKey, serverUrl) {
496
496
  dlog(`cache miss; writing requests[${newRid}] attrs=${JSON.stringify(attrs)}`);
497
497
  requests.set(newRid, { ...attrs, status: 'pending', created_at: new Date().toISOString() });
498
498
 
499
- // Watch both token:<newRid> AND resources[requestedResource] for
500
- // the result. resources map updates survive WS reconnects because
501
- // Yjs re-syncs the full doc state; token:<newRid> may be missed
502
- // if the write happened during a reconnect gap.
503
499
  const prevTokenMapName = resourcesMap.get(requestedResource);
504
500
  const newTokenMap = deviceDoc.getMap(`token:${newRid}`);
505
501
 
@@ -512,14 +508,28 @@ function startDaemon(provider, deviceDoc, privateKey, serverUrl) {
512
508
  30_000
513
509
  ).then((newMapName) => {
514
510
  const m = deviceDoc.getMap(newMapName);
515
- // wait for ciphertext to land on the new map (may arrive right after resources update)
516
511
  return firstInYMap(m, (key) => key === 'ciphertext' || key === 'error', 5_000)
517
512
  .then(() => m).catch(() => m);
518
513
  });
519
514
 
515
+ // Poll every 2s — handles updates that arrived during a WS reconnect
516
+ // gap where Yjs observers were missed.
517
+ const viaPoll = new Promise((resolve, reject) => {
518
+ const iv = setInterval(() => {
519
+ const name = resourcesMap.get(requestedResource);
520
+ if (name && name !== prevTokenMapName) {
521
+ const m = deviceDoc.getMap(name);
522
+ if (m.get('ciphertext')) { clearInterval(iv); resolve(m); return; }
523
+ }
524
+ if (newTokenMap.get('ciphertext')) { clearInterval(iv); resolve(newTokenMap); }
525
+ }, 2000);
526
+ setTimeout(() => { clearInterval(iv); reject(new Error('Timeout')); }, 31_000);
527
+ });
528
+
520
529
  Promise.race([
521
530
  viaRid.then((map) => ({ src: 'rid', map })),
522
531
  viaResources.then((map) => ({ src: 'resources', map })),
532
+ viaPoll.then((map) => ({ src: 'poll', map })),
523
533
  ])
524
534
  .then(({ src, map }) => {
525
535
  dlog(`token resolved via ${src} for ${requestedResource}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiam/ciba",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "OAuth 2.0 Device Authorization Grant CLI with cross-device push approval (Yjs sync, ECDH-encrypted token delivery, persistent device id)",
5
5
  "type": "module",
6
6
  "bin": {