@aiam/ciba 0.8.1 → 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.
- package/ciba.mjs +22 -7
- 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}`);
|
|
@@ -752,9 +762,14 @@ const logoutCmd = defineCommand({
|
|
|
752
762
|
const stopCmd = defineCommand({
|
|
753
763
|
meta: { description: 'Stop daemon and clear session' },
|
|
754
764
|
args: {},
|
|
755
|
-
run() {
|
|
756
|
-
const cfg = loadConfig();
|
|
765
|
+
async run() {
|
|
757
766
|
if (cfg.pid) { try { process.kill(parseInt(cfg.pid)); } catch {} }
|
|
767
|
+
// Kill all orphaned ciba daemon processes (previous --persist runs that
|
|
768
|
+
// were never approved or whose parent exited without storing the PID).
|
|
769
|
+
try {
|
|
770
|
+
const { execFileSync } = await import('node:child_process');
|
|
771
|
+
execFileSync('pkill', ['-f', 'ciba login --daemon'], { stdio: 'ignore' });
|
|
772
|
+
} catch { /* pkill not found or no matching processes */ }
|
|
758
773
|
if (existsSync(SOCKET_PATH)) unlinkSync(SOCKET_PATH);
|
|
759
774
|
const sessionFile = join(CONFIG_DIR, 'session');
|
|
760
775
|
if (existsSync(sessionFile)) unlinkSync(sessionFile);
|
package/package.json
CHANGED