chainlesschain 0.143.0 → 0.152.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.
- package/package.json +1 -1
- package/src/commands/a2a.js +196 -28
- package/src/commands/activitypub.js +364 -27
- package/src/commands/agent-network.js +217 -0
- package/src/commands/agent.js +587 -103
- package/src/commands/audit.js +206 -0
- package/src/commands/automation.js +201 -0
- package/src/commands/bi.js +355 -27
- package/src/commands/bm25.js +111 -27
- package/src/commands/browse.js +403 -29
- package/src/commands/ccron.js +128 -28
- package/src/commands/chat.js +207 -0
- package/src/commands/codegen.js +207 -0
- package/src/commands/collab.js +211 -0
- package/src/commands/compliance.js +824 -34
- package/src/commands/compt.js +127 -29
- package/src/commands/consol.js +8 -2
- package/src/commands/cowork.js +783 -34
- package/src/commands/crosschain.js +182 -28
- package/src/commands/dao.js +182 -28
- package/src/commands/dbevo.js +227 -0
- package/src/commands/dev.js +207 -0
- package/src/commands/did-v2.js +217 -0
- package/src/commands/did.js +221 -0
- package/src/commands/dlp.js +385 -27
- package/src/commands/economy.js +205 -50
- package/src/commands/evolution.js +203 -50
- package/src/commands/evomap.js +387 -27
- package/src/commands/export.js +213 -0
- package/src/commands/federation.js +209 -0
- package/src/commands/fflag.js +74 -22
- package/src/commands/fusion.js +205 -0
- package/src/commands/git.js +177 -37
- package/src/commands/governance.js +209 -0
- package/src/commands/hardening.js +209 -0
- package/src/commands/hmemory.js +204 -50
- package/src/commands/hook.js +209 -0
- package/src/commands/import.js +209 -0
- package/src/commands/incentive.js +209 -0
- package/src/commands/inference.js +170 -34
- package/src/commands/infra.js +203 -0
- package/src/commands/instinct.js +209 -0
- package/src/commands/ipfs.js +207 -0
- package/src/commands/itbudget.js +149 -33
- package/src/commands/kg.js +206 -0
- package/src/commands/llm.js +217 -0
- package/src/commands/lowcode.js +195 -38
- package/src/commands/marketplace.js +206 -0
- package/src/commands/matrix.js +386 -27
- package/src/commands/mcp.js +217 -0
- package/src/commands/mcpscaf.js +145 -33
- package/src/commands/meminj.js +145 -33
- package/src/commands/memory.js +209 -0
- package/src/commands/multimodal.js +203 -0
- package/src/commands/nlprog.js +225 -0
- package/src/commands/nostr.js +387 -27
- package/src/commands/note.js +205 -0
- package/src/commands/ops.js +219 -0
- package/src/commands/orchestrate.js +217 -0
- package/src/commands/orchgov.js +144 -33
- package/src/commands/org.js +209 -0
- package/src/commands/p2p.js +209 -0
- package/src/commands/pdfp.js +109 -27
- package/src/commands/perception.js +209 -0
- package/src/commands/perf.js +169 -32
- package/src/commands/perm.js +144 -33
- package/src/commands/permmem.js +203 -0
- package/src/commands/pipeline.js +207 -52
- package/src/commands/planmode.js +141 -32
- package/src/commands/plugin-ecosystem.js +209 -0
- package/src/commands/pqc.js +213 -0
- package/src/commands/privacy.js +203 -0
- package/src/commands/promcomp.js +111 -27
- package/src/commands/quantization.js +207 -0
- package/src/commands/rcache.js +205 -0
- package/src/commands/recommend.js +410 -34
- package/src/commands/reputation.js +208 -0
- package/src/commands/runtime.js +205 -0
- package/src/commands/sandbox.js +206 -0
- package/src/commands/scim.js +209 -0
- package/src/commands/seshhook.js +145 -33
- package/src/commands/seshsearch.js +141 -33
- package/src/commands/seshtail.js +144 -33
- package/src/commands/seshu.js +152 -33
- package/src/commands/session.js +209 -0
- package/src/commands/sganal.js +123 -29
- package/src/commands/siem.js +201 -34
- package/src/commands/skill.js +207 -0
- package/src/commands/sla.js +212 -0
- package/src/commands/slotfill.js +146 -33
- package/src/commands/social.js +358 -32
- package/src/commands/sso.js +209 -0
- package/src/commands/stress.js +206 -0
- package/src/commands/svccont.js +145 -33
- package/src/commands/sync.js +209 -0
- package/src/commands/tech.js +209 -0
- package/src/commands/tenant.js +217 -0
- package/src/commands/terraform.js +206 -0
- package/src/commands/tms.js +171 -33
- package/src/commands/tokens.js +209 -0
- package/src/commands/topiccls.js +146 -33
- package/src/commands/trust.js +217 -0
- package/src/commands/uprof.js +141 -32
- package/src/commands/vcheck.js +122 -28
- package/src/commands/wallet.js +209 -0
- package/src/commands/webfetch.js +141 -32
- package/src/commands/workflow.js +203 -0
- package/src/commands/zkp.js +184 -28
- package/src/index.js +180 -0
- package/src/lib/a2a-protocol.js +319 -51
- package/src/lib/activitypub-bridge.js +622 -50
- package/src/lib/agent-economy.js +304 -51
- package/src/lib/agent-network.js +341 -0
- package/src/lib/aiops.js +346 -0
- package/src/lib/app-builder.js +279 -46
- package/src/lib/audit-logger.js +321 -0
- package/src/lib/automation-engine.js +335 -0
- package/src/lib/autonomous-agent.js +284 -48
- package/src/lib/autonomous-developer.js +332 -0
- package/src/lib/bi-engine.js +616 -49
- package/src/lib/bm25-search.js +301 -49
- package/src/lib/browser-automation.js +630 -49
- package/src/lib/chat-core.js +336 -0
- package/src/lib/claude-code-bridge.js +341 -0
- package/src/lib/code-agent.js +339 -0
- package/src/lib/collaboration-governance.js +334 -0
- package/src/lib/community-governance.js +346 -0
- package/src/lib/compliance-framework-reporter.js +305 -51
- package/src/lib/compliance-manager.js +330 -0
- package/src/lib/compression-telemetry.js +301 -49
- package/src/lib/content-recommendation.js +351 -0
- package/src/lib/content-recommender.js +317 -52
- package/src/lib/cowork-cron.js +298 -49
- package/src/lib/cowork-learning.js +333 -0
- package/src/lib/cowork-share.js +338 -0
- package/src/lib/cowork-task-runner.js +308 -51
- package/src/lib/cowork-workflow.js +327 -0
- package/src/lib/cross-chain.js +311 -51
- package/src/lib/dao-governance.js +280 -46
- package/src/lib/dbevo.js +351 -0
- package/src/lib/decentral-infra.js +330 -0
- package/src/lib/did-manager.js +341 -0
- package/src/lib/did-v2-manager.js +341 -0
- package/src/lib/dlp-engine.js +626 -49
- package/src/lib/evolution-system.js +278 -47
- package/src/lib/evomap-governance.js +334 -0
- package/src/lib/evomap-manager.js +280 -46
- package/src/lib/execution-backend.js +294 -48
- package/src/lib/feature-flags.js +294 -49
- package/src/lib/federation-hardening.js +340 -0
- package/src/lib/git-integration.js +285 -47
- package/src/lib/hardening-manager.js +341 -0
- package/src/lib/hierarchical-memory.js +284 -48
- package/src/lib/hook-manager.js +341 -0
- package/src/lib/inference-network.js +308 -51
- package/src/lib/instinct-manager.js +346 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/iteration-budget.js +302 -50
- package/src/lib/knowledge-exporter.js +341 -0
- package/src/lib/knowledge-graph.js +333 -0
- package/src/lib/knowledge-importer.js +341 -0
- package/src/lib/llm-providers.js +346 -0
- package/src/lib/matrix-bridge.js +620 -47
- package/src/lib/mcp-registry.js +346 -0
- package/src/lib/mcp-scaffold.js +318 -54
- package/src/lib/memory-injection.js +288 -49
- package/src/lib/memory-manager.js +336 -0
- package/src/lib/multimodal.js +330 -0
- package/src/lib/nl-programming.js +341 -0
- package/src/lib/nostr-bridge.js +622 -49
- package/src/lib/note-versioning.js +339 -0
- package/src/lib/orchestrator.js +293 -48
- package/src/lib/org-manager.js +336 -0
- package/src/lib/p2p-manager.js +341 -0
- package/src/lib/pdf-parser.js +298 -49
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +309 -50
- package/src/lib/permanent-memory.js +327 -0
- package/src/lib/permission-engine.js +287 -49
- package/src/lib/pipeline-orchestrator.js +289 -49
- package/src/lib/plan-mode.js +298 -51
- package/src/lib/plugin-ecosystem.js +346 -0
- package/src/lib/pqc-manager.js +346 -0
- package/src/lib/privacy-computing.js +335 -0
- package/src/lib/protocol-fusion.js +338 -0
- package/src/lib/quantization.js +337 -0
- package/src/lib/reputation-optimizer.js +340 -0
- package/src/lib/response-cache.js +333 -0
- package/src/lib/sandbox-v2.js +327 -0
- package/src/lib/scim-manager.js +346 -0
- package/src/lib/service-container.js +313 -52
- package/src/lib/session-consolidator.js +296 -49
- package/src/lib/session-hooks.js +312 -53
- package/src/lib/session-manager.js +334 -0
- package/src/lib/session-search.js +304 -51
- package/src/lib/session-tail.js +288 -49
- package/src/lib/session-usage.js +298 -52
- package/src/lib/siem-exporter.js +298 -51
- package/src/lib/skill-loader.js +334 -0
- package/src/lib/skill-marketplace.js +345 -0
- package/src/lib/sla-manager.js +341 -0
- package/src/lib/slot-filler.js +303 -51
- package/src/lib/social-graph-analytics.js +295 -49
- package/src/lib/social-graph.js +272 -49
- package/src/lib/social-manager.js +330 -0
- package/src/lib/sso-manager.js +340 -0
- package/src/lib/stress-tester.js +342 -0
- package/src/lib/sub-agent-registry.js +302 -53
- package/src/lib/sync-manager.js +336 -0
- package/src/lib/task-model-selector.js +302 -50
- package/src/lib/tech-learning-engine.js +341 -0
- package/src/lib/tenant-saas.js +341 -0
- package/src/lib/terraform-manager.js +333 -0
- package/src/lib/threat-intel.js +330 -0
- package/src/lib/todo-manager.js +281 -47
- package/src/lib/token-incentive.js +341 -0
- package/src/lib/token-tracker.js +336 -0
- package/src/lib/topic-classifier.js +297 -49
- package/src/lib/trust-security.js +343 -0
- package/src/lib/ueba.js +340 -0
- package/src/lib/universal-runtime.js +330 -0
- package/src/lib/user-profile.js +294 -50
- package/src/lib/version-checker.js +304 -50
- package/src/lib/wallet-manager.js +336 -0
- package/src/lib/web-fetch.js +292 -51
- package/src/lib/workflow-engine.js +330 -0
- package/src/lib/zkp-engine.js +286 -49
package/src/lib/nostr-bridge.js
CHANGED
|
@@ -370,25 +370,53 @@ export function _resetState() {
|
|
|
370
370
|
_didMappings.clear();
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
|
|
374
373
|
// ===== V2 Surface: Nostr Bridge governance overlay (CLI v0.134.0) =====
|
|
375
374
|
export const NOSTR_RELAY_MATURITY_V2 = Object.freeze({
|
|
376
|
-
PENDING: "pending",
|
|
375
|
+
PENDING: "pending",
|
|
376
|
+
ACTIVE: "active",
|
|
377
|
+
OFFLINE: "offline",
|
|
378
|
+
RETIRED: "retired",
|
|
377
379
|
});
|
|
378
380
|
export const NOSTR_EVENT_LIFECYCLE_V2 = Object.freeze({
|
|
379
|
-
QUEUED: "queued",
|
|
381
|
+
QUEUED: "queued",
|
|
382
|
+
PUBLISHING: "publishing",
|
|
383
|
+
PUBLISHED: "published",
|
|
384
|
+
FAILED: "failed",
|
|
385
|
+
CANCELLED: "cancelled",
|
|
380
386
|
});
|
|
381
387
|
|
|
382
388
|
const _nsRelayTrans = new Map([
|
|
383
|
-
[
|
|
384
|
-
|
|
385
|
-
|
|
389
|
+
[
|
|
390
|
+
NOSTR_RELAY_MATURITY_V2.PENDING,
|
|
391
|
+
new Set([NOSTR_RELAY_MATURITY_V2.ACTIVE, NOSTR_RELAY_MATURITY_V2.RETIRED]),
|
|
392
|
+
],
|
|
393
|
+
[
|
|
394
|
+
NOSTR_RELAY_MATURITY_V2.ACTIVE,
|
|
395
|
+
new Set([NOSTR_RELAY_MATURITY_V2.OFFLINE, NOSTR_RELAY_MATURITY_V2.RETIRED]),
|
|
396
|
+
],
|
|
397
|
+
[
|
|
398
|
+
NOSTR_RELAY_MATURITY_V2.OFFLINE,
|
|
399
|
+
new Set([NOSTR_RELAY_MATURITY_V2.ACTIVE, NOSTR_RELAY_MATURITY_V2.RETIRED]),
|
|
400
|
+
],
|
|
386
401
|
[NOSTR_RELAY_MATURITY_V2.RETIRED, new Set()],
|
|
387
402
|
]);
|
|
388
403
|
const _nsRelayTerminal = new Set([NOSTR_RELAY_MATURITY_V2.RETIRED]);
|
|
389
404
|
const _nsEventTrans = new Map([
|
|
390
|
-
[
|
|
391
|
-
|
|
405
|
+
[
|
|
406
|
+
NOSTR_EVENT_LIFECYCLE_V2.QUEUED,
|
|
407
|
+
new Set([
|
|
408
|
+
NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING,
|
|
409
|
+
NOSTR_EVENT_LIFECYCLE_V2.CANCELLED,
|
|
410
|
+
]),
|
|
411
|
+
],
|
|
412
|
+
[
|
|
413
|
+
NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING,
|
|
414
|
+
new Set([
|
|
415
|
+
NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED,
|
|
416
|
+
NOSTR_EVENT_LIFECYCLE_V2.FAILED,
|
|
417
|
+
NOSTR_EVENT_LIFECYCLE_V2.CANCELLED,
|
|
418
|
+
]),
|
|
419
|
+
],
|
|
392
420
|
[NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED, new Set()],
|
|
393
421
|
[NOSTR_EVENT_LIFECYCLE_V2.FAILED, new Set()],
|
|
394
422
|
[NOSTR_EVENT_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
@@ -401,76 +429,621 @@ let _nsMaxPendingPerRelay = 30;
|
|
|
401
429
|
let _nsRelayIdleMs = 60 * 60 * 1000;
|
|
402
430
|
let _nsEventStuckMs = 2 * 60 * 1000;
|
|
403
431
|
|
|
404
|
-
function _nsPos(n, lbl) {
|
|
432
|
+
function _nsPos(n, lbl) {
|
|
433
|
+
const v = Math.floor(Number(n));
|
|
434
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
435
|
+
throw new Error(`${lbl} must be positive integer`);
|
|
436
|
+
return v;
|
|
437
|
+
}
|
|
405
438
|
|
|
406
|
-
export function setMaxActiveNostrRelaysPerOwnerV2(n) {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
export function
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
export function
|
|
413
|
-
|
|
439
|
+
export function setMaxActiveNostrRelaysPerOwnerV2(n) {
|
|
440
|
+
_nsMaxActivePerOwner = _nsPos(n, "maxActiveNostrRelaysPerOwner");
|
|
441
|
+
}
|
|
442
|
+
export function getMaxActiveNostrRelaysPerOwnerV2() {
|
|
443
|
+
return _nsMaxActivePerOwner;
|
|
444
|
+
}
|
|
445
|
+
export function setMaxPendingNostrEventsPerRelayV2(n) {
|
|
446
|
+
_nsMaxPendingPerRelay = _nsPos(n, "maxPendingNostrEventsPerRelay");
|
|
447
|
+
}
|
|
448
|
+
export function getMaxPendingNostrEventsPerRelayV2() {
|
|
449
|
+
return _nsMaxPendingPerRelay;
|
|
450
|
+
}
|
|
451
|
+
export function setNostrRelayIdleMsV2(n) {
|
|
452
|
+
_nsRelayIdleMs = _nsPos(n, "nostrRelayIdleMs");
|
|
453
|
+
}
|
|
454
|
+
export function getNostrRelayIdleMsV2() {
|
|
455
|
+
return _nsRelayIdleMs;
|
|
456
|
+
}
|
|
457
|
+
export function setNostrEventStuckMsV2(n) {
|
|
458
|
+
_nsEventStuckMs = _nsPos(n, "nostrEventStuckMs");
|
|
459
|
+
}
|
|
460
|
+
export function getNostrEventStuckMsV2() {
|
|
461
|
+
return _nsEventStuckMs;
|
|
462
|
+
}
|
|
414
463
|
|
|
415
464
|
export function _resetStateNostrBridgeV2() {
|
|
416
|
-
_nsRelays.clear();
|
|
417
|
-
|
|
418
|
-
|
|
465
|
+
_nsRelays.clear();
|
|
466
|
+
_nsEvents.clear();
|
|
467
|
+
_nsMaxActivePerOwner = 10;
|
|
468
|
+
_nsMaxPendingPerRelay = 30;
|
|
469
|
+
_nsRelayIdleMs = 60 * 60 * 1000;
|
|
470
|
+
_nsEventStuckMs = 2 * 60 * 1000;
|
|
419
471
|
}
|
|
420
472
|
|
|
421
473
|
export function registerNostrRelayV2({ id, owner, url, metadata } = {}) {
|
|
422
474
|
if (!id || typeof id !== "string") throw new Error("id is required");
|
|
423
475
|
if (!owner || typeof owner !== "string") throw new Error("owner is required");
|
|
424
|
-
if (_nsRelays.has(id))
|
|
476
|
+
if (_nsRelays.has(id))
|
|
477
|
+
throw new Error(`nostr relay ${id} already registered`);
|
|
425
478
|
const now = Date.now();
|
|
426
|
-
const r = {
|
|
479
|
+
const r = {
|
|
480
|
+
id,
|
|
481
|
+
owner,
|
|
482
|
+
url: url || "",
|
|
483
|
+
status: NOSTR_RELAY_MATURITY_V2.PENDING,
|
|
484
|
+
createdAt: now,
|
|
485
|
+
updatedAt: now,
|
|
486
|
+
activatedAt: null,
|
|
487
|
+
retiredAt: null,
|
|
488
|
+
lastTouchedAt: now,
|
|
489
|
+
metadata: { ...(metadata || {}) },
|
|
490
|
+
};
|
|
427
491
|
_nsRelays.set(id, r);
|
|
428
492
|
return { ...r, metadata: { ...r.metadata } };
|
|
429
493
|
}
|
|
430
|
-
function _nsCheckR(from, to) {
|
|
431
|
-
|
|
494
|
+
function _nsCheckR(from, to) {
|
|
495
|
+
const a = _nsRelayTrans.get(from);
|
|
496
|
+
if (!a || !a.has(to))
|
|
497
|
+
throw new Error(`invalid nostr relay transition ${from} → ${to}`);
|
|
498
|
+
}
|
|
499
|
+
function _nsCountActive(owner) {
|
|
500
|
+
let n = 0;
|
|
501
|
+
for (const r of _nsRelays.values())
|
|
502
|
+
if (r.owner === owner && r.status === NOSTR_RELAY_MATURITY_V2.ACTIVE) n++;
|
|
503
|
+
return n;
|
|
504
|
+
}
|
|
432
505
|
|
|
433
506
|
export function activateNostrRelayV2(id) {
|
|
434
|
-
const r = _nsRelays.get(id);
|
|
507
|
+
const r = _nsRelays.get(id);
|
|
508
|
+
if (!r) throw new Error(`nostr relay ${id} not found`);
|
|
435
509
|
_nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.ACTIVE);
|
|
436
510
|
const recovery = r.status === NOSTR_RELAY_MATURITY_V2.OFFLINE;
|
|
437
|
-
if (!recovery) {
|
|
438
|
-
|
|
511
|
+
if (!recovery) {
|
|
512
|
+
const a = _nsCountActive(r.owner);
|
|
513
|
+
if (a >= _nsMaxActivePerOwner)
|
|
514
|
+
throw new Error(
|
|
515
|
+
`max active nostr relays per owner (${_nsMaxActivePerOwner}) reached for ${r.owner}`,
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
const now = Date.now();
|
|
519
|
+
r.status = NOSTR_RELAY_MATURITY_V2.ACTIVE;
|
|
520
|
+
r.updatedAt = now;
|
|
521
|
+
r.lastTouchedAt = now;
|
|
522
|
+
if (!r.activatedAt) r.activatedAt = now;
|
|
523
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
524
|
+
}
|
|
525
|
+
export function offlineNostrRelayV2(id) {
|
|
526
|
+
const r = _nsRelays.get(id);
|
|
527
|
+
if (!r) throw new Error(`nostr relay ${id} not found`);
|
|
528
|
+
_nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.OFFLINE);
|
|
529
|
+
r.status = NOSTR_RELAY_MATURITY_V2.OFFLINE;
|
|
530
|
+
r.updatedAt = Date.now();
|
|
531
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
532
|
+
}
|
|
533
|
+
export function retireNostrRelayV2(id) {
|
|
534
|
+
const r = _nsRelays.get(id);
|
|
535
|
+
if (!r) throw new Error(`nostr relay ${id} not found`);
|
|
536
|
+
_nsCheckR(r.status, NOSTR_RELAY_MATURITY_V2.RETIRED);
|
|
537
|
+
const now = Date.now();
|
|
538
|
+
r.status = NOSTR_RELAY_MATURITY_V2.RETIRED;
|
|
539
|
+
r.updatedAt = now;
|
|
540
|
+
if (!r.retiredAt) r.retiredAt = now;
|
|
439
541
|
return { ...r, metadata: { ...r.metadata } };
|
|
440
542
|
}
|
|
441
|
-
export function
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
543
|
+
export function touchNostrRelayV2(id) {
|
|
544
|
+
const r = _nsRelays.get(id);
|
|
545
|
+
if (!r) throw new Error(`nostr relay ${id} not found`);
|
|
546
|
+
if (_nsRelayTerminal.has(r.status))
|
|
547
|
+
throw new Error(`cannot touch terminal nostr relay ${id}`);
|
|
548
|
+
const now = Date.now();
|
|
549
|
+
r.lastTouchedAt = now;
|
|
550
|
+
r.updatedAt = now;
|
|
551
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
552
|
+
}
|
|
553
|
+
export function getNostrRelayV2(id) {
|
|
554
|
+
const r = _nsRelays.get(id);
|
|
555
|
+
if (!r) return null;
|
|
556
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
557
|
+
}
|
|
558
|
+
export function listNostrRelaysV2() {
|
|
559
|
+
return [..._nsRelays.values()].map((r) => ({
|
|
560
|
+
...r,
|
|
561
|
+
metadata: { ...r.metadata },
|
|
562
|
+
}));
|
|
563
|
+
}
|
|
446
564
|
|
|
447
|
-
function _nsCountPending(rid) {
|
|
565
|
+
function _nsCountPending(rid) {
|
|
566
|
+
let n = 0;
|
|
567
|
+
for (const e of _nsEvents.values())
|
|
568
|
+
if (
|
|
569
|
+
e.relayId === rid &&
|
|
570
|
+
(e.status === NOSTR_EVENT_LIFECYCLE_V2.QUEUED ||
|
|
571
|
+
e.status === NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING)
|
|
572
|
+
)
|
|
573
|
+
n++;
|
|
574
|
+
return n;
|
|
575
|
+
}
|
|
448
576
|
|
|
449
577
|
export function createNostrEventV2({ id, relayId, kind, metadata } = {}) {
|
|
450
578
|
if (!id || typeof id !== "string") throw new Error("id is required");
|
|
451
|
-
if (!relayId || typeof relayId !== "string")
|
|
579
|
+
if (!relayId || typeof relayId !== "string")
|
|
580
|
+
throw new Error("relayId is required");
|
|
452
581
|
if (_nsEvents.has(id)) throw new Error(`nostr event ${id} already exists`);
|
|
453
|
-
if (!_nsRelays.has(relayId))
|
|
582
|
+
if (!_nsRelays.has(relayId))
|
|
583
|
+
throw new Error(`nostr relay ${relayId} not found`);
|
|
454
584
|
const pending = _nsCountPending(relayId);
|
|
455
|
-
if (pending >= _nsMaxPendingPerRelay)
|
|
585
|
+
if (pending >= _nsMaxPendingPerRelay)
|
|
586
|
+
throw new Error(
|
|
587
|
+
`max pending nostr events per relay (${_nsMaxPendingPerRelay}) reached for ${relayId}`,
|
|
588
|
+
);
|
|
456
589
|
const now = Date.now();
|
|
457
|
-
const e = {
|
|
590
|
+
const e = {
|
|
591
|
+
id,
|
|
592
|
+
relayId,
|
|
593
|
+
kind: typeof kind === "number" ? kind : 1,
|
|
594
|
+
status: NOSTR_EVENT_LIFECYCLE_V2.QUEUED,
|
|
595
|
+
createdAt: now,
|
|
596
|
+
updatedAt: now,
|
|
597
|
+
startedAt: null,
|
|
598
|
+
settledAt: null,
|
|
599
|
+
metadata: { ...(metadata || {}) },
|
|
600
|
+
};
|
|
458
601
|
_nsEvents.set(id, e);
|
|
459
602
|
return { ...e, metadata: { ...e.metadata } };
|
|
460
603
|
}
|
|
461
|
-
function _nsCheckE(from, to) {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
export function
|
|
467
|
-
|
|
604
|
+
function _nsCheckE(from, to) {
|
|
605
|
+
const a = _nsEventTrans.get(from);
|
|
606
|
+
if (!a || !a.has(to))
|
|
607
|
+
throw new Error(`invalid nostr event transition ${from} → ${to}`);
|
|
608
|
+
}
|
|
609
|
+
export function startNostrEventV2(id) {
|
|
610
|
+
const e = _nsEvents.get(id);
|
|
611
|
+
if (!e) throw new Error(`nostr event ${id} not found`);
|
|
612
|
+
_nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING);
|
|
613
|
+
const now = Date.now();
|
|
614
|
+
e.status = NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING;
|
|
615
|
+
e.updatedAt = now;
|
|
616
|
+
if (!e.startedAt) e.startedAt = now;
|
|
617
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
618
|
+
}
|
|
619
|
+
export function publishNostrEventV2(id) {
|
|
620
|
+
const e = _nsEvents.get(id);
|
|
621
|
+
if (!e) throw new Error(`nostr event ${id} not found`);
|
|
622
|
+
_nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED);
|
|
623
|
+
const now = Date.now();
|
|
624
|
+
e.status = NOSTR_EVENT_LIFECYCLE_V2.PUBLISHED;
|
|
625
|
+
e.updatedAt = now;
|
|
626
|
+
if (!e.settledAt) e.settledAt = now;
|
|
627
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
628
|
+
}
|
|
629
|
+
export function failNostrEventV2(id, reason) {
|
|
630
|
+
const e = _nsEvents.get(id);
|
|
631
|
+
if (!e) throw new Error(`nostr event ${id} not found`);
|
|
632
|
+
_nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.FAILED);
|
|
633
|
+
const now = Date.now();
|
|
634
|
+
e.status = NOSTR_EVENT_LIFECYCLE_V2.FAILED;
|
|
635
|
+
e.updatedAt = now;
|
|
636
|
+
if (!e.settledAt) e.settledAt = now;
|
|
637
|
+
if (reason) e.metadata.failReason = String(reason);
|
|
638
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
639
|
+
}
|
|
640
|
+
export function cancelNostrEventV2(id, reason) {
|
|
641
|
+
const e = _nsEvents.get(id);
|
|
642
|
+
if (!e) throw new Error(`nostr event ${id} not found`);
|
|
643
|
+
_nsCheckE(e.status, NOSTR_EVENT_LIFECYCLE_V2.CANCELLED);
|
|
644
|
+
const now = Date.now();
|
|
645
|
+
e.status = NOSTR_EVENT_LIFECYCLE_V2.CANCELLED;
|
|
646
|
+
e.updatedAt = now;
|
|
647
|
+
if (!e.settledAt) e.settledAt = now;
|
|
648
|
+
if (reason) e.metadata.cancelReason = String(reason);
|
|
649
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
650
|
+
}
|
|
651
|
+
export function getNostrEventV2(id) {
|
|
652
|
+
const e = _nsEvents.get(id);
|
|
653
|
+
if (!e) return null;
|
|
654
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
655
|
+
}
|
|
656
|
+
export function listNostrEventsV2() {
|
|
657
|
+
return [..._nsEvents.values()].map((e) => ({
|
|
658
|
+
...e,
|
|
659
|
+
metadata: { ...e.metadata },
|
|
660
|
+
}));
|
|
661
|
+
}
|
|
468
662
|
|
|
469
|
-
export function autoOfflineIdleNostrRelaysV2({ now } = {}) {
|
|
470
|
-
|
|
663
|
+
export function autoOfflineIdleNostrRelaysV2({ now } = {}) {
|
|
664
|
+
const t = now ?? Date.now();
|
|
665
|
+
const flipped = [];
|
|
666
|
+
for (const r of _nsRelays.values())
|
|
667
|
+
if (
|
|
668
|
+
r.status === NOSTR_RELAY_MATURITY_V2.ACTIVE &&
|
|
669
|
+
t - r.lastTouchedAt >= _nsRelayIdleMs
|
|
670
|
+
) {
|
|
671
|
+
r.status = NOSTR_RELAY_MATURITY_V2.OFFLINE;
|
|
672
|
+
r.updatedAt = t;
|
|
673
|
+
flipped.push(r.id);
|
|
674
|
+
}
|
|
675
|
+
return { flipped, count: flipped.length };
|
|
676
|
+
}
|
|
677
|
+
export function autoFailStuckNostrEventsV2({ now } = {}) {
|
|
678
|
+
const t = now ?? Date.now();
|
|
679
|
+
const flipped = [];
|
|
680
|
+
for (const e of _nsEvents.values())
|
|
681
|
+
if (
|
|
682
|
+
e.status === NOSTR_EVENT_LIFECYCLE_V2.PUBLISHING &&
|
|
683
|
+
e.startedAt != null &&
|
|
684
|
+
t - e.startedAt >= _nsEventStuckMs
|
|
685
|
+
) {
|
|
686
|
+
e.status = NOSTR_EVENT_LIFECYCLE_V2.FAILED;
|
|
687
|
+
e.updatedAt = t;
|
|
688
|
+
if (!e.settledAt) e.settledAt = t;
|
|
689
|
+
e.metadata.failReason = "auto-fail-stuck";
|
|
690
|
+
flipped.push(e.id);
|
|
691
|
+
}
|
|
692
|
+
return { flipped, count: flipped.length };
|
|
693
|
+
}
|
|
471
694
|
|
|
472
695
|
export function getNostrBridgeStatsV2() {
|
|
473
|
-
const relaysByStatus = {};
|
|
474
|
-
|
|
475
|
-
|
|
696
|
+
const relaysByStatus = {};
|
|
697
|
+
for (const s of Object.values(NOSTR_RELAY_MATURITY_V2)) relaysByStatus[s] = 0;
|
|
698
|
+
for (const r of _nsRelays.values()) relaysByStatus[r.status]++;
|
|
699
|
+
const eventsByStatus = {};
|
|
700
|
+
for (const s of Object.values(NOSTR_EVENT_LIFECYCLE_V2))
|
|
701
|
+
eventsByStatus[s] = 0;
|
|
702
|
+
for (const e of _nsEvents.values()) eventsByStatus[e.status]++;
|
|
703
|
+
return {
|
|
704
|
+
totalRelaysV2: _nsRelays.size,
|
|
705
|
+
totalEventsV2: _nsEvents.size,
|
|
706
|
+
maxActiveNostrRelaysPerOwner: _nsMaxActivePerOwner,
|
|
707
|
+
maxPendingNostrEventsPerRelay: _nsMaxPendingPerRelay,
|
|
708
|
+
nostrRelayIdleMs: _nsRelayIdleMs,
|
|
709
|
+
nostrEventStuckMs: _nsEventStuckMs,
|
|
710
|
+
relaysByStatus,
|
|
711
|
+
eventsByStatus,
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// =====================================================================
|
|
716
|
+
// nostr-bridge V2 governance overlay (iter21)
|
|
717
|
+
// =====================================================================
|
|
718
|
+
export const NOSGOV_PROFILE_MATURITY_V2 = Object.freeze({
|
|
719
|
+
PENDING: "pending",
|
|
720
|
+
ACTIVE: "active",
|
|
721
|
+
SUSPENDED: "suspended",
|
|
722
|
+
ARCHIVED: "archived",
|
|
723
|
+
});
|
|
724
|
+
export const NOSGOV_PUBLISH_LIFECYCLE_V2 = Object.freeze({
|
|
725
|
+
QUEUED: "queued",
|
|
726
|
+
PUBLISHING: "publishing",
|
|
727
|
+
PUBLISHED: "published",
|
|
728
|
+
FAILED: "failed",
|
|
729
|
+
CANCELLED: "cancelled",
|
|
730
|
+
});
|
|
731
|
+
const _nosgovPTrans = new Map([
|
|
732
|
+
[
|
|
733
|
+
NOSGOV_PROFILE_MATURITY_V2.PENDING,
|
|
734
|
+
new Set([
|
|
735
|
+
NOSGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
736
|
+
NOSGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
737
|
+
]),
|
|
738
|
+
],
|
|
739
|
+
[
|
|
740
|
+
NOSGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
741
|
+
new Set([
|
|
742
|
+
NOSGOV_PROFILE_MATURITY_V2.SUSPENDED,
|
|
743
|
+
NOSGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
744
|
+
]),
|
|
745
|
+
],
|
|
746
|
+
[
|
|
747
|
+
NOSGOV_PROFILE_MATURITY_V2.SUSPENDED,
|
|
748
|
+
new Set([
|
|
749
|
+
NOSGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
750
|
+
NOSGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
751
|
+
]),
|
|
752
|
+
],
|
|
753
|
+
[NOSGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
754
|
+
]);
|
|
755
|
+
const _nosgovPTerminal = new Set([NOSGOV_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
756
|
+
const _nosgovJTrans = new Map([
|
|
757
|
+
[
|
|
758
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.QUEUED,
|
|
759
|
+
new Set([
|
|
760
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING,
|
|
761
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED,
|
|
762
|
+
]),
|
|
763
|
+
],
|
|
764
|
+
[
|
|
765
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING,
|
|
766
|
+
new Set([
|
|
767
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED,
|
|
768
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED,
|
|
769
|
+
NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED,
|
|
770
|
+
]),
|
|
771
|
+
],
|
|
772
|
+
[NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED, new Set()],
|
|
773
|
+
[NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED, new Set()],
|
|
774
|
+
[NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
775
|
+
]);
|
|
776
|
+
const _nosgovPsV2 = new Map();
|
|
777
|
+
const _nosgovJsV2 = new Map();
|
|
778
|
+
let _nosgovMaxActive = 8,
|
|
779
|
+
_nosgovMaxPending = 25,
|
|
780
|
+
_nosgovIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
781
|
+
_nosgovStuckMs = 60 * 1000;
|
|
782
|
+
function _nosgovPos(n, label) {
|
|
783
|
+
const v = Math.floor(Number(n));
|
|
784
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
785
|
+
throw new Error(`${label} must be positive integer`);
|
|
786
|
+
return v;
|
|
787
|
+
}
|
|
788
|
+
function _nosgovCheckP(from, to) {
|
|
789
|
+
const a = _nosgovPTrans.get(from);
|
|
790
|
+
if (!a || !a.has(to))
|
|
791
|
+
throw new Error(`invalid nosgov profile transition ${from} → ${to}`);
|
|
792
|
+
}
|
|
793
|
+
function _nosgovCheckJ(from, to) {
|
|
794
|
+
const a = _nosgovJTrans.get(from);
|
|
795
|
+
if (!a || !a.has(to))
|
|
796
|
+
throw new Error(`invalid nosgov publish transition ${from} → ${to}`);
|
|
797
|
+
}
|
|
798
|
+
function _nosgovCountActive(owner) {
|
|
799
|
+
let c = 0;
|
|
800
|
+
for (const p of _nosgovPsV2.values())
|
|
801
|
+
if (p.owner === owner && p.status === NOSGOV_PROFILE_MATURITY_V2.ACTIVE)
|
|
802
|
+
c++;
|
|
803
|
+
return c;
|
|
804
|
+
}
|
|
805
|
+
function _nosgovCountPending(profileId) {
|
|
806
|
+
let c = 0;
|
|
807
|
+
for (const j of _nosgovJsV2.values())
|
|
808
|
+
if (
|
|
809
|
+
j.profileId === profileId &&
|
|
810
|
+
(j.status === NOSGOV_PUBLISH_LIFECYCLE_V2.QUEUED ||
|
|
811
|
+
j.status === NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING)
|
|
812
|
+
)
|
|
813
|
+
c++;
|
|
814
|
+
return c;
|
|
815
|
+
}
|
|
816
|
+
export function setMaxActiveNosgovProfilesPerOwnerV2(n) {
|
|
817
|
+
_nosgovMaxActive = _nosgovPos(n, "maxActiveNosgovProfilesPerOwner");
|
|
818
|
+
}
|
|
819
|
+
export function getMaxActiveNosgovProfilesPerOwnerV2() {
|
|
820
|
+
return _nosgovMaxActive;
|
|
821
|
+
}
|
|
822
|
+
export function setMaxPendingNosgovPublishsPerProfileV2(n) {
|
|
823
|
+
_nosgovMaxPending = _nosgovPos(n, "maxPendingNosgovPublishsPerProfile");
|
|
824
|
+
}
|
|
825
|
+
export function getMaxPendingNosgovPublishsPerProfileV2() {
|
|
826
|
+
return _nosgovMaxPending;
|
|
827
|
+
}
|
|
828
|
+
export function setNosgovProfileIdleMsV2(n) {
|
|
829
|
+
_nosgovIdleMs = _nosgovPos(n, "nosgovProfileIdleMs");
|
|
830
|
+
}
|
|
831
|
+
export function getNosgovProfileIdleMsV2() {
|
|
832
|
+
return _nosgovIdleMs;
|
|
833
|
+
}
|
|
834
|
+
export function setNosgovPublishStuckMsV2(n) {
|
|
835
|
+
_nosgovStuckMs = _nosgovPos(n, "nosgovPublishStuckMs");
|
|
836
|
+
}
|
|
837
|
+
export function getNosgovPublishStuckMsV2() {
|
|
838
|
+
return _nosgovStuckMs;
|
|
839
|
+
}
|
|
840
|
+
export function _resetStateNostrBridgeGovV2() {
|
|
841
|
+
_nosgovPsV2.clear();
|
|
842
|
+
_nosgovJsV2.clear();
|
|
843
|
+
_nosgovMaxActive = 8;
|
|
844
|
+
_nosgovMaxPending = 25;
|
|
845
|
+
_nosgovIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
846
|
+
_nosgovStuckMs = 60 * 1000;
|
|
847
|
+
}
|
|
848
|
+
export function registerNosgovProfileV2({ id, owner, relay, metadata } = {}) {
|
|
849
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
850
|
+
if (_nosgovPsV2.has(id))
|
|
851
|
+
throw new Error(`nosgov profile ${id} already exists`);
|
|
852
|
+
const now = Date.now();
|
|
853
|
+
const p = {
|
|
854
|
+
id,
|
|
855
|
+
owner,
|
|
856
|
+
relay: relay || "wss://relay.local",
|
|
857
|
+
status: NOSGOV_PROFILE_MATURITY_V2.PENDING,
|
|
858
|
+
createdAt: now,
|
|
859
|
+
updatedAt: now,
|
|
860
|
+
lastTouchedAt: now,
|
|
861
|
+
activatedAt: null,
|
|
862
|
+
archivedAt: null,
|
|
863
|
+
metadata: { ...(metadata || {}) },
|
|
864
|
+
};
|
|
865
|
+
_nosgovPsV2.set(id, p);
|
|
866
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
867
|
+
}
|
|
868
|
+
export function activateNosgovProfileV2(id) {
|
|
869
|
+
const p = _nosgovPsV2.get(id);
|
|
870
|
+
if (!p) throw new Error(`nosgov profile ${id} not found`);
|
|
871
|
+
const isInitial = p.status === NOSGOV_PROFILE_MATURITY_V2.PENDING;
|
|
872
|
+
_nosgovCheckP(p.status, NOSGOV_PROFILE_MATURITY_V2.ACTIVE);
|
|
873
|
+
if (isInitial && _nosgovCountActive(p.owner) >= _nosgovMaxActive)
|
|
874
|
+
throw new Error(`max active nosgov profiles for owner ${p.owner} reached`);
|
|
875
|
+
const now = Date.now();
|
|
876
|
+
p.status = NOSGOV_PROFILE_MATURITY_V2.ACTIVE;
|
|
877
|
+
p.updatedAt = now;
|
|
878
|
+
p.lastTouchedAt = now;
|
|
879
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
880
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
881
|
+
}
|
|
882
|
+
export function suspendNosgovProfileV2(id) {
|
|
883
|
+
const p = _nosgovPsV2.get(id);
|
|
884
|
+
if (!p) throw new Error(`nosgov profile ${id} not found`);
|
|
885
|
+
_nosgovCheckP(p.status, NOSGOV_PROFILE_MATURITY_V2.SUSPENDED);
|
|
886
|
+
p.status = NOSGOV_PROFILE_MATURITY_V2.SUSPENDED;
|
|
887
|
+
p.updatedAt = Date.now();
|
|
888
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
889
|
+
}
|
|
890
|
+
export function archiveNosgovProfileV2(id) {
|
|
891
|
+
const p = _nosgovPsV2.get(id);
|
|
892
|
+
if (!p) throw new Error(`nosgov profile ${id} not found`);
|
|
893
|
+
_nosgovCheckP(p.status, NOSGOV_PROFILE_MATURITY_V2.ARCHIVED);
|
|
894
|
+
const now = Date.now();
|
|
895
|
+
p.status = NOSGOV_PROFILE_MATURITY_V2.ARCHIVED;
|
|
896
|
+
p.updatedAt = now;
|
|
897
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
898
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
899
|
+
}
|
|
900
|
+
export function touchNosgovProfileV2(id) {
|
|
901
|
+
const p = _nosgovPsV2.get(id);
|
|
902
|
+
if (!p) throw new Error(`nosgov profile ${id} not found`);
|
|
903
|
+
if (_nosgovPTerminal.has(p.status))
|
|
904
|
+
throw new Error(`cannot touch terminal nosgov profile ${id}`);
|
|
905
|
+
const now = Date.now();
|
|
906
|
+
p.lastTouchedAt = now;
|
|
907
|
+
p.updatedAt = now;
|
|
908
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
909
|
+
}
|
|
910
|
+
export function getNosgovProfileV2(id) {
|
|
911
|
+
const p = _nosgovPsV2.get(id);
|
|
912
|
+
if (!p) return null;
|
|
913
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
914
|
+
}
|
|
915
|
+
export function listNosgovProfilesV2() {
|
|
916
|
+
return [..._nosgovPsV2.values()].map((p) => ({
|
|
917
|
+
...p,
|
|
918
|
+
metadata: { ...p.metadata },
|
|
919
|
+
}));
|
|
920
|
+
}
|
|
921
|
+
export function createNosgovPublishV2({ id, profileId, kind, metadata } = {}) {
|
|
922
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
923
|
+
if (_nosgovJsV2.has(id))
|
|
924
|
+
throw new Error(`nosgov publish ${id} already exists`);
|
|
925
|
+
if (!_nosgovPsV2.has(profileId))
|
|
926
|
+
throw new Error(`nosgov profile ${profileId} not found`);
|
|
927
|
+
if (_nosgovCountPending(profileId) >= _nosgovMaxPending)
|
|
928
|
+
throw new Error(
|
|
929
|
+
`max pending nosgov publishs for profile ${profileId} reached`,
|
|
930
|
+
);
|
|
931
|
+
const now = Date.now();
|
|
932
|
+
const j = {
|
|
933
|
+
id,
|
|
934
|
+
profileId,
|
|
935
|
+
kind: kind || "",
|
|
936
|
+
status: NOSGOV_PUBLISH_LIFECYCLE_V2.QUEUED,
|
|
937
|
+
createdAt: now,
|
|
938
|
+
updatedAt: now,
|
|
939
|
+
startedAt: null,
|
|
940
|
+
settledAt: null,
|
|
941
|
+
metadata: { ...(metadata || {}) },
|
|
942
|
+
};
|
|
943
|
+
_nosgovJsV2.set(id, j);
|
|
944
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
945
|
+
}
|
|
946
|
+
export function publishingNosgovPublishV2(id) {
|
|
947
|
+
const j = _nosgovJsV2.get(id);
|
|
948
|
+
if (!j) throw new Error(`nosgov publish ${id} not found`);
|
|
949
|
+
_nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING);
|
|
950
|
+
const now = Date.now();
|
|
951
|
+
j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING;
|
|
952
|
+
j.updatedAt = now;
|
|
953
|
+
if (!j.startedAt) j.startedAt = now;
|
|
954
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
955
|
+
}
|
|
956
|
+
export function completePublishNosgovV2(id) {
|
|
957
|
+
const j = _nosgovJsV2.get(id);
|
|
958
|
+
if (!j) throw new Error(`nosgov publish ${id} not found`);
|
|
959
|
+
_nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED);
|
|
960
|
+
const now = Date.now();
|
|
961
|
+
j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHED;
|
|
962
|
+
j.updatedAt = now;
|
|
963
|
+
if (!j.settledAt) j.settledAt = now;
|
|
964
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
965
|
+
}
|
|
966
|
+
export function failNosgovPublishV2(id, reason) {
|
|
967
|
+
const j = _nosgovJsV2.get(id);
|
|
968
|
+
if (!j) throw new Error(`nosgov publish ${id} not found`);
|
|
969
|
+
_nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED);
|
|
970
|
+
const now = Date.now();
|
|
971
|
+
j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED;
|
|
972
|
+
j.updatedAt = now;
|
|
973
|
+
if (!j.settledAt) j.settledAt = now;
|
|
974
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
975
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
976
|
+
}
|
|
977
|
+
export function cancelNosgovPublishV2(id, reason) {
|
|
978
|
+
const j = _nosgovJsV2.get(id);
|
|
979
|
+
if (!j) throw new Error(`nosgov publish ${id} not found`);
|
|
980
|
+
_nosgovCheckJ(j.status, NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED);
|
|
981
|
+
const now = Date.now();
|
|
982
|
+
j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.CANCELLED;
|
|
983
|
+
j.updatedAt = now;
|
|
984
|
+
if (!j.settledAt) j.settledAt = now;
|
|
985
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
986
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
987
|
+
}
|
|
988
|
+
export function getNosgovPublishV2(id) {
|
|
989
|
+
const j = _nosgovJsV2.get(id);
|
|
990
|
+
if (!j) return null;
|
|
991
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
992
|
+
}
|
|
993
|
+
export function listNosgovPublishsV2() {
|
|
994
|
+
return [..._nosgovJsV2.values()].map((j) => ({
|
|
995
|
+
...j,
|
|
996
|
+
metadata: { ...j.metadata },
|
|
997
|
+
}));
|
|
998
|
+
}
|
|
999
|
+
export function autoSuspendIdleNosgovProfilesV2({ now } = {}) {
|
|
1000
|
+
const t = now ?? Date.now();
|
|
1001
|
+
const flipped = [];
|
|
1002
|
+
for (const p of _nosgovPsV2.values())
|
|
1003
|
+
if (
|
|
1004
|
+
p.status === NOSGOV_PROFILE_MATURITY_V2.ACTIVE &&
|
|
1005
|
+
t - p.lastTouchedAt >= _nosgovIdleMs
|
|
1006
|
+
) {
|
|
1007
|
+
p.status = NOSGOV_PROFILE_MATURITY_V2.SUSPENDED;
|
|
1008
|
+
p.updatedAt = t;
|
|
1009
|
+
flipped.push(p.id);
|
|
1010
|
+
}
|
|
1011
|
+
return { flipped, count: flipped.length };
|
|
1012
|
+
}
|
|
1013
|
+
export function autoFailStuckNosgovPublishsV2({ now } = {}) {
|
|
1014
|
+
const t = now ?? Date.now();
|
|
1015
|
+
const flipped = [];
|
|
1016
|
+
for (const j of _nosgovJsV2.values())
|
|
1017
|
+
if (
|
|
1018
|
+
j.status === NOSGOV_PUBLISH_LIFECYCLE_V2.PUBLISHING &&
|
|
1019
|
+
j.startedAt != null &&
|
|
1020
|
+
t - j.startedAt >= _nosgovStuckMs
|
|
1021
|
+
) {
|
|
1022
|
+
j.status = NOSGOV_PUBLISH_LIFECYCLE_V2.FAILED;
|
|
1023
|
+
j.updatedAt = t;
|
|
1024
|
+
if (!j.settledAt) j.settledAt = t;
|
|
1025
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
1026
|
+
flipped.push(j.id);
|
|
1027
|
+
}
|
|
1028
|
+
return { flipped, count: flipped.length };
|
|
1029
|
+
}
|
|
1030
|
+
export function getNostrBridgeGovStatsV2() {
|
|
1031
|
+
const profilesByStatus = {};
|
|
1032
|
+
for (const v of Object.values(NOSGOV_PROFILE_MATURITY_V2))
|
|
1033
|
+
profilesByStatus[v] = 0;
|
|
1034
|
+
for (const p of _nosgovPsV2.values()) profilesByStatus[p.status]++;
|
|
1035
|
+
const publishsByStatus = {};
|
|
1036
|
+
for (const v of Object.values(NOSGOV_PUBLISH_LIFECYCLE_V2))
|
|
1037
|
+
publishsByStatus[v] = 0;
|
|
1038
|
+
for (const j of _nosgovJsV2.values()) publishsByStatus[j.status]++;
|
|
1039
|
+
return {
|
|
1040
|
+
totalNosgovProfilesV2: _nosgovPsV2.size,
|
|
1041
|
+
totalNosgovPublishsV2: _nosgovJsV2.size,
|
|
1042
|
+
maxActiveNosgovProfilesPerOwner: _nosgovMaxActive,
|
|
1043
|
+
maxPendingNosgovPublishsPerProfile: _nosgovMaxPending,
|
|
1044
|
+
nosgovProfileIdleMs: _nosgovIdleMs,
|
|
1045
|
+
nosgovPublishStuckMs: _nosgovStuckMs,
|
|
1046
|
+
profilesByStatus,
|
|
1047
|
+
publishsByStatus,
|
|
1048
|
+
};
|
|
476
1049
|
}
|