@wovin/core 0.3.3 → 0.3.4

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 (46) hide show
  1. package/dist/applog/applog-utils.d.ts +12 -1
  2. package/dist/applog/applog-utils.d.ts.map +1 -1
  3. package/dist/applog.js +5 -1
  4. package/dist/{chunk-N5QPZNKD.js → chunk-523IW54O.js} +3 -3
  5. package/dist/{chunk-4MKPGQIM.js → chunk-7VHIXHNF.js} +97 -62
  6. package/dist/chunk-7VHIXHNF.js.map +1 -0
  7. package/dist/{chunk-H4YVJKB7.js → chunk-ERVSWD63.js} +2 -2
  8. package/dist/{chunk-N7SEGHU4.js → chunk-GQDLPZEZ.js} +33 -24
  9. package/dist/chunk-GQDLPZEZ.js.map +1 -0
  10. package/dist/{chunk-6CSJTSQP.js → chunk-OB7M55WA.js} +3 -3
  11. package/dist/{chunk-H3JNNTVP.js → chunk-PTZJ7LVV.js} +27 -6
  12. package/dist/chunk-PTZJ7LVV.js.map +1 -0
  13. package/dist/{chunk-BIYQEX3N.js → chunk-XEUQDEA4.js} +2 -2
  14. package/dist/index.js +11 -7
  15. package/dist/ipfs.js +4 -4
  16. package/dist/ipns/ipns-record.d.ts.map +1 -1
  17. package/dist/ipns/ipns-watcher.d.ts.map +1 -1
  18. package/dist/ipns.js +6 -8
  19. package/dist/ipns.js.map +1 -1
  20. package/dist/pubsub/snap-push.d.ts.map +1 -1
  21. package/dist/pubsub.js +4 -4
  22. package/dist/query/basic.d.ts.map +1 -1
  23. package/dist/query.js +3 -3
  24. package/dist/retrieve.js +4 -4
  25. package/dist/thread/basic.d.ts.map +1 -1
  26. package/dist/thread/mapped.d.ts.map +1 -1
  27. package/dist/thread/utils.d.ts.map +1 -1
  28. package/dist/thread.js +1 -1
  29. package/dist/viewmodel/index.js +2 -2
  30. package/package.json +1 -1
  31. package/src/applog/applog-utils.ts +33 -1
  32. package/src/ipns/ipns-record.test.ts +72 -0
  33. package/src/ipns/ipns-record.ts +23 -8
  34. package/src/ipns/ipns-watcher.ts +10 -11
  35. package/src/pubsub/snap-push.ts +25 -3
  36. package/src/query/basic.ts +124 -81
  37. package/src/thread/basic.ts +21 -2
  38. package/src/thread/mapped.ts +12 -4
  39. package/src/thread/utils.ts +5 -5
  40. package/dist/chunk-4MKPGQIM.js.map +0 -1
  41. package/dist/chunk-H3JNNTVP.js.map +0 -1
  42. package/dist/chunk-N7SEGHU4.js.map +0 -1
  43. /package/dist/{chunk-N5QPZNKD.js.map → chunk-523IW54O.js.map} +0 -0
  44. /package/dist/{chunk-H4YVJKB7.js.map → chunk-ERVSWD63.js.map} +0 -0
  45. /package/dist/{chunk-6CSJTSQP.js.map → chunk-OB7M55WA.js.map} +0 -0
  46. /package/dist/{chunk-BIYQEX3N.js.map → chunk-XEUQDEA4.js.map} +0 -0
package/dist/ipns.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ipns/gateway-resolver.ts","../src/ipns/ipns-record.ts","../src/ipns/ipns-w3name.ts","../src/ipns/ipns-watcher.ts"],"sourcesContent":["import { CID } from 'multiformats/cid'\nimport { Logger } from 'besonders-logger'\n\nconst { WARN, LOG, DEBUG } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars\n\n/**\n * Resolve an IPNS name to a CID using a public IPFS gateway's HTTP HEAD response.\n *\n * Mechanism: per the IPFS HTTP Gateway spec, `HEAD <gateway>/ipns/<name>/` returns the\n * IPNS-resolved root CID in the `X-Ipfs-Roots` response header (space-separated, ordered\n * from root to leaf). The first entry is the IPNS-resolved CID.\n *\n * This works against any gateway that follows the spec and exposes CORS for HEAD\n * (most public gateways do, e.g. ipfs.zt.ax, ipfs.io, dweb.link).\n *\n * The legacy w3name HTTP endpoint (`GET <base>/name/<ipns>` returning `{value: \"/ipfs/<cid>\"}`)\n * is also supported here for back-compat with self-hosted w3name-like services — but the\n * X-Ipfs-Roots path is preferred since it's the standardised gateway mechanism.\n *\n * @param ipns - The IPNS name (k51... string)\n * @param gateways - List of gateway base URLs (e.g. `[\"https://ipfs.zt.ax\"]`)\n * @returns The resolved CID, or null if no gateway could resolve the name\n */\nexport async function resolveIPNSViaGateway(ipns: string, gateways: string[]): Promise<CID | null> {\n\tif (!ipns.startsWith('k51')) return null // only IPNS libp2p-key names go through gateway\n\tif (!gateways?.length) return null\n\n\tfor (const rawGateway of gateways) {\n\t\tconst gateway = rawGateway.replace(/\\/+$/, '')\n\t\tconst url = `${gateway}/ipns/${ipns}/`\n\t\ttry {\n\t\t\tDEBUG(`[resolveIPNSViaGateway] HEAD ${url}`)\n\t\t\tconst response = await fetch(url, { method: 'HEAD' })\n\t\t\tif (!response.ok) {\n\t\t\t\tDEBUG(`[resolveIPNSViaGateway] ${gateway} returned ${response.status}`)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst roots = response.headers.get('x-ipfs-roots') ?? response.headers.get('X-Ipfs-Roots')\n\t\t\tif (roots) {\n\t\t\t\tconst first = roots.split(/[\\s,]+/)[0]?.trim()\n\t\t\t\tif (first) {\n\t\t\t\t\tconst cid = CID.parse(first)\n\t\t\t\t\tDEBUG(`[resolveIPNSViaGateway] resolved via ${gateway} x-ipfs-roots:`, cid.toString())\n\t\t\t\t\treturn cid\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Some gateways omit X-Ipfs-Roots but put the CID in etag (e.g. `<cid>.dag-json`)\n\t\t\tconst etag = response.headers.get('etag')\n\t\t\tif (etag) {\n\t\t\t\tconst m = etag.match(/^\"?([a-z0-9]+)/i)\n\t\t\t\tif (m) {\n\t\t\t\t\tconst cid = CID.parse(m[1])\n\t\t\t\t\tDEBUG(`[resolveIPNSViaGateway] resolved via ${gateway} etag:`, cid.toString())\n\t\t\t\t\treturn cid\n\t\t\t\t}\n\t\t\t}\n\t\t\tWARN(`[resolveIPNSViaGateway] ${gateway} returned 200 but no usable CID header`)\n\t\t} catch (err) {\n\t\t\tWARN(`[resolveIPNSViaGateway] ${gateway} failed:`, err)\n\t\t}\n\t}\n\treturn null\n}\n","import { createIPNSRecord, marshalIPNSRecord, unmarshalIPNSRecord } from 'ipns'\nimport { privateKeyFromRaw } from '@libp2p/crypto/keys'\nimport { base36 } from 'multiformats/bases/base36'\nimport { base64pad } from 'multiformats/bases/base64'\nimport type { CID } from 'multiformats/cid'\n\nexport interface SignedIPNSRecord {\n\trecordBytes: Uint8Array // marshalled protobuf, signed — the wire format\n\tipnsName: string // k51... string\n\tvalue: string // /ipfs/<cid>\n\tsequence: bigint\n}\n\n/** Derive IPNS name string (k51...) from Ed25519 private key bytes */\nexport function ipnsNameFromPrivateKey(privKeyBytes: Uint8Array): string {\n\tconst privKey = privateKeyFromRaw(privKeyBytes)\n\treturn privKey.publicKey.toCID().toString(base36)\n}\n\n/**\n * Create a signed IPNS record (protobuf wire format).\n * Same bytes can be published to any naming service.\n */\nexport async function createSignedIPNSRecord(\n\tprivateKey: Uint8Array,\n\tcid: CID,\n\tsequence: bigint,\n\tlifetimeMs = 365 * 24 * 60 * 60 * 1000, // 1 year\n): Promise<SignedIPNSRecord> {\n\tconst privKey = privateKeyFromRaw(privateKey)\n\tconst value = `/ipfs/${cid.toV1()}`\n\tconst record = await createIPNSRecord(privKey, value, sequence, lifetimeMs)\n\tconst recordBytes = marshalIPNSRecord(record)\n\tconst ipnsName = privKey.publicKey.toCID().toString(base36)\n\treturn { recordBytes, ipnsName, value, sequence }\n}\n\nexport { unmarshalIPNSRecord }\n\n/**\n * A target that can receive a signed IPNS record, advertise its current\n * sequence, or both.\n *\n * - `publish` is called by `publishIPNSRecord` to actually store the record\n * on the target's backing service. Targets without `publish` are skipped\n * during the fan-out (e.g. a sequence-only source).\n * - `resolveSequence` is consulted by `publishIPNSRecord` to compute the\n * next IPNS sequence. The first target to return a value (including\n * `null` for \"never published\") wins. Throw to indicate a transient\n * error — the caller will try the next target.\n *\n * Most real targets (e.g. a storage connector) provide both. A simple\n * \"track sequence in localStorage\" target only needs `resolveSequence`.\n */\nexport interface IPNSPublishTarget {\n\tname: string\n\tpublish?(ipnsName: string, recordBytes: Uint8Array): Promise<void>\n\tresolveSequence?(ipnsName: string): Promise<bigint | null>\n}\n\n/**\n * Resolve the current IPNS sequence from a generic naming service.\n * Returns null if the name was never published (404).\n * Throws on network/server errors so the caller can try a different target.\n */\nexport async function resolveIPNSSequence(\n\tnameServiceUrl: string,\n\tipnsName: string,\n): Promise<bigint | null> {\n\tconst url = `${nameServiceUrl}/name/${ipnsName}`\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetch(url)\n\t} catch (err) {\n\t\tthrow new Error(`Network error resolving IPNS ${ipnsName}: ${err}`)\n\t}\n\n\tif (response.status === 404) return null\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP ${response.status} resolving IPNS ${ipnsName}: ${response.statusText}`)\n\t}\n\n\tconst { record, value } = await response.json()\n\tif (!record && !value) return null // never published\n\n\t// If raw record is available, unmarshal to get sequence\n\tif (record) {\n\t\tconst bytes = base64pad.baseDecode(record)\n\t\tconst entry = unmarshalIPNSRecord(bytes)\n\t\treturn entry.sequence\n\t}\n\n\t// Server only returned a value, no raw record — can't know the exact sequence.\n\t// Most services still accept this as \"previous published\"; treat as seq=0n.\n\treturn 0n\n}\n\n/** Regex to detect Kubo IPNS sequence conflict in error messages */\nconst SEQ_CONFLICT_RE = /existing IPNS record has sequence (\\d+) >= new record sequence (\\d+)/\n\n/**\n * Options for {@link publishIPNSRecord}.\n */\nexport interface PublishIPNSRecordOptions {\n\t/**\n\t * Max number of times to bump the sequence on \"existing >= new\" conflict.\n\t * Defaults to 3. Each bump re-signs the record with a higher sequence\n\t * and retries all targets.\n\t */\n\tmaxSequenceBumps?: number\n}\n\n/**\n * Create a signed IPNS record and publish to all configured targets.\n *\n * Sequence resolution: walks `targets` in order asking each one with a\n * `resolveSequence` method. The first target to successfully return a value\n * (including `null` for \"never published\") determines the next sequence.\n * If every target throws or none supports `resolveSequence`, falls back to 0n.\n *\n * Publish fan-out: only targets with a `publish` method are called.\n * Throws if every publish-capable target fails; partial failures are logged.\n *\n * **Sequence-coherence retry:** if a publish target rejects with the Kubo\n * \"existing IPNS record has sequence X >= new record sequence Y\" error,\n * the function parses `X`, bumps the sequence to `max(X + 1n, Y + 1n)`,\n * re-signs the record, and retries (up to `maxSequenceBumps` times).\n * This is the \"increment and clobber\" mechanism that recovers from\n * sequence drift without requiring server-side `--force` support.\n */\nexport async function publishIPNSRecord(\n\tprivateKey: Uint8Array,\n\tcid: CID,\n\ttargets: IPNSPublishTarget[],\n\toptions?: PublishIPNSRecordOptions,\n): Promise<SignedIPNSRecord> {\n\tconst ipnsName = ipnsNameFromPrivateKey(privateKey)\n\tconst maxBumps = options?.maxSequenceBumps ?? 3\n\n\tconst publishTargets = targets.filter(t => typeof t.publish === 'function')\n\tif (publishTargets.length === 0) {\n\t\tthrow new Error('No publish-capable targets supplied to publishIPNSRecord')\n\t}\n\n\tlet sequence: bigint | undefined\n\tlet bumpFloor: bigint | undefined\n\n\tfor (let attempt = 0; ; attempt++) {\n\t\t// Compute next sequence on first pass or after a conflict bump\n\t\tif (sequence === undefined) {\n\t\t\tsequence = await pickNextSequence(ipnsName, targets)\n\t\t}\n\t\tif (bumpFloor !== undefined) {\n\t\t\t// bumpFloor was set on previous attempt from a conflict error\n\t\t\tif (bumpFloor > sequence) sequence = bumpFloor\n\t\t\tbumpFloor = undefined\n\t\t}\n\n\t\tconst signed = await createSignedIPNSRecord(privateKey, cid, sequence)\n\n\t\tconst results = await Promise.allSettled(\n\t\t\tpublishTargets.map(t => t.publish!(ipnsName, signed.recordBytes)),\n\t\t)\n\t\tconst failures = results\n\t\t\t.map((r, i) => ({ r, name: publishTargets[i].name }))\n\t\t\t.filter(({ r }) => r.status === 'rejected') as { r: PromiseRejectedResult; name: string }[]\n\n\t\t// All succeeded — done\n\t\tif (failures.length === 0) {\n\t\t\treturn signed\n\t\t}\n\n\t\t// Check if any failure is a sequence conflict we can recover from\n\t\tconst conflictReasons = failures.filter(({ r }) =>\n\t\t\tSEQ_CONFLICT_RE.test(typeof r.reason === 'string' ? r.reason : String(r.reason)),\n\t\t)\n\n\t\tif (conflictReasons.length > 0 && attempt < maxBumps) {\n\t\t\t// Parse the highest existing sequence from each conflict error\n\t\t\tlet bump = sequence\n\t\t\tfor (const { r } of conflictReasons) {\n\t\t\t\tconst msg = typeof r.reason === 'string' ? r.reason : String(r.reason)\n\t\t\t\tconst m = msg.match(SEQ_CONFLICT_RE)\n\t\t\t\tif (m) {\n\t\t\t\t\tconst existing = BigInt(m[1])\n\t\t\t\t\tif (existing >= bump) bump = existing + 1n\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bump > sequence) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[publishIPNSRecord] Sequence conflict: server seq ${bump - 1n} >= current ${sequence}, ` +\n\t\t\t\t\t`bumping to ${bump} (attempt ${attempt + 1}/${maxBumps})`,\n\t\t\t\t)\n\t\t\t\tsequence = bump\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Partial failure (some targets succeeded) — log and return the signed record\n\t\tif (failures.length < publishTargets.length) {\n\t\t\tfor (const { r, name } of failures) {\n\t\t\t\tconsole.warn(`[publishIPNSRecord] target '${name}' failed:`, r.reason)\n\t\t\t}\n\t\t\treturn signed\n\t\t}\n\n\t\t// Every publish-capable target failed and we cannot recover\n\t\tif (conflictReasons.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`IPNS sequence conflict not resolved after ${Math.min(attempt + 1, maxBumps)} bumps. ` +\n\t\t\t\t`All publish targets failed: ${failures.map(({ r, name }) => `${name}: ${r.reason}`).join('; ')}`,\n\t\t\t)\n\t\t}\n\t\tthrow new Error(\n\t\t\t`All IPNS publish targets failed: ${failures.map(({ r, name }) => `${name}: ${r.reason}`).join('; ')}`,\n\t\t)\n\t}\n}\n\n/**\n * Walk targets, asking each to resolve the current IPNS sequence. First success wins.\n * Falls back to 0n if no target can answer.\n */\nasync function pickNextSequence(\n\tipnsName: string,\n\ttargets: IPNSPublishTarget[],\n): Promise<bigint> {\n\tconst capable = targets.filter(t => typeof t.resolveSequence === 'function')\n\tif (capable.length === 0) {\n\t\treturn 0n\n\t}\n\n\tfor (const target of capable) {\n\t\ttry {\n\t\t\tconst current = await target.resolveSequence!(ipnsName)\n\t\t\treturn current == null ? 0n : current + 1n\n\t\t} catch (err) {\n\t\t\tconsole.warn(`[publishIPNSRecord] target '${target.name}' sequence resolve failed:`, err)\n\t\t}\n\t}\n\n\tconsole.warn(`[publishIPNSRecord] no target could resolve sequence for ${ipnsName} — starting at 0n`)\n\treturn 0n\n}\n","import type { IPNSPublishTarget } from '@wovin/core/ipns'\nimport { Logger } from 'besonders-logger'\nimport { base64pad } from 'multiformats/bases/base64'\nimport { resolveIPNSSequence, unmarshalIPNSRecord } from './ipns-record.ts'\nimport { CID } from 'multiformats/cid'\nimport * as W3Name from 'w3name'\n\nconst { WARN, LOG, DEBUG, ERROR } = Logger.setup(Logger.INFO)\n\n/**\n * Try to resolve IPNS name to get existing revision.\n * Returns null if record doesn't exist (404).\n * Throws on network errors or server errors.\n *\n * This does a custom HTTP check first to distinguish 404 from network errors,\n * then delegates to W3Name.resolve() for validation if record exists.\n */\nasync function tryResolveIPNS(ipns: W3Name.WritableName): Promise<W3Name.Revision | null> {\n\tconst url = `https://name.web3.storage/name/${ipns.toString()}`\n\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetch(url, { signal: AbortSignal.timeout(30_000) })\n\t} catch (err) {\n\t\t// Network error (no connection, DNS failure, etc.)\n\t\tthrow ERROR('[w3name] Network error resolving IPNS:', err)\n\t}\n\n\t// 404 = record never published\n\tif (response.status === 404) {\n\t\tDEBUG('[w3name] IPNS record not found (never published):', ipns.toString())\n\t\treturn null\n\t}\n\n\t// Other HTTP errors (5xx server error, etc.)\n\tif (!response.ok) {\n\t\tthrow ERROR(`[w3name] HTTP ${response.status} resolving IPNS:`, response.statusText)\n\t}\n\n\t// Success - use W3Name.resolve to get validated Revision\n\t// (We could parse the record ourselves, but W3Name does validation/signature checks)\n\tconst existing = await W3Name.resolve(ipns)\n\treturn existing\n}\n\n/**\n * Publish CID to IPNS, automatically handling increment vs v0.\n * Returns the revision for further processing (e.g., Kubo integration).\n */\nexport async function publishIPNS(ipnsPrivateKey: Uint8Array, cid: CID): Promise<W3Name.Revision> {\n\tconst TIMEOUT_MS = 30_000\n\tconst timeout = new Promise<never>((_, reject) =>\n\t\tsetTimeout(() => reject(new Error(`publishIPNS timed out after ${TIMEOUT_MS}ms`)), TIMEOUT_MS),\n\t)\n\treturn Promise.race([_publishIPNSImpl(ipnsPrivateKey, cid), timeout])\n}\n\nasync function _publishIPNSImpl(ipnsPrivateKey: Uint8Array, cid: CID): Promise<W3Name.Revision> {\n\tconst value = `/ipfs/${cid}`\n\tconst ipns = await W3Name.from(ipnsPrivateKey)\n\n\tlet revision: W3Name.Revision\n\tconst existing = await tryResolveIPNS(ipns)\n\n\tif (existing) {\n\t\t// Record exists - increment sequence number\n\t\trevision = await W3Name.increment(existing, value)\n\t\tDEBUG('[w3name] incrementing revision for', ipns.toString())\n\t} else {\n\t\t// First publish - use v0\n\t\trevision = await W3Name.v0(ipns, value)\n\t\tDEBUG('[w3name] creating initial revision for', ipns.toString())\n\t}\n\n\tawait W3Name.publish(revision, ipns.key)\n\tDEBUG('[w3name] published', cid.toString(), 'to', ipns.toString())\n\n\treturn revision // Return for Kubo integration or other uses\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// zt.ax naming service target (primary)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve the current IPNS sequence from a zt.ax-compatible naming service.\n *\n * The naming service API uses the simple W3NameRecord format:\n * `GET <baseUrl>/<ipnsName>` → `{ value: \"/ipfs/<cid>\", seq?: number, validity?: string }`\n *\n * Also supports the legacy w3name record format (`{ record: \"<base64>\", value: \"...\" }`)\n * for backward compatibility with hybrid services.\n */\nexport async function resolveZtaxSequence(\n\tbaseUrl: string,\n\tipnsName: string,\n): Promise<bigint | null> {\n\tconst url = `${baseUrl.replace(/\\/+$/, '')}/${ipnsName}`\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetch(url)\n\t} catch (err) {\n\t\tthrow new Error(`Network error resolving sequence from ${baseUrl}: ${err}`)\n\t}\n\n\tif (response.status === 404) return null\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP ${response.status} resolving sequence from ${baseUrl}: ${response.statusText}`)\n\t}\n\n\tconst body: Record<string, unknown> = await response.json()\n\n\t// Format 1: simple W3NameRecord with seq number\n\tif (typeof body.seq === 'number') {\n\t\treturn BigInt(body.seq)\n\t}\n\n\t// Format 2: legacy w3name record with base64-encoded protobuf\n\tif (typeof body.record === 'string') {\n\t\ttry {\n\t\t\tconst bytes = base64pad.baseDecode(body.record)\n\t\t\tconst entry = unmarshalIPNSRecord(bytes)\n\t\t\treturn entry.sequence\n\t\t} catch {\n\t\t\tWARN('[resolveZtaxSequence] failed to unmarshal record for', ipnsName)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t// No sequence info — treat as never published or zero\n\treturn null\n}\n\n/**\n * Create an IPNSPublishTarget that publishes to a zt.ax naming service.\n *\n * Uses HTTP POST to publish signed IPNS records and HTTP GET to resolve\n * the current sequence number, following the same wire format as the\n * standard w3name API but at a configurable base URL.\n *\n * The naming service is expected to support:\n * - `POST <baseUrl>/<ipnsName>` — publish signed IPNS record (base64-encoded body)\n * - `GET <baseUrl>/<ipnsName>` — resolve current record (`{ value, seq?, record? }`)\n *\n * @param baseUrl - Base URL of the naming service (default: https://ipfs.zt.ax)\n */\nexport function ztaxTarget(baseUrl = 'https://ipfs.zt.ax'): IPNSPublishTarget {\n\tconst cleanBase = baseUrl.replace(/\\/+$/, '')\n\treturn {\n\t\tname: 'zt.ax',\n\t\tasync publish(ipnsName: string, recordBytes: Uint8Array) {\n\t\t\tconst url = `${cleanBase}/${ipnsName}`\n\t\t\tDEBUG(`[ztaxTarget] POST ${url}`)\n\t\t\tconst res = await fetch(url, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: base64pad.baseEncode(recordBytes),\n\t\t\t})\n\t\t\tif (!res.ok) {\n\t\t\t\tlet detail = ''\n\t\t\t\ttry {\n\t\t\t\t\tconst body = await res.json() as Record<string, unknown>\n\t\t\t\t\tdetail = body.message ? ` — ${body.message}` : ''\n\t\t\t\t} catch {\n\t\t\t\t\tdetail = res.statusText ? ` — ${res.statusText}` : ''\n\t\t\t\t}\n\t\t\t\tthrow new Error(`zt.ax HTTP ${res.status}${detail}`)\n\t\t\t}\n\t\t},\n\t\tasync resolveSequence(ipnsName: string): Promise<bigint | null> {\n\t\t\treturn resolveZtaxSequence(cleanBase, ipnsName)\n\t\t},\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// w3name naming service target (deprecated — read‑only backup)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create an IPNSPublishTarget for the w3name service.\n *\n * @deprecated w3name is shut down for publishing. This target is kept as a\n * read‑only backup for sequence resolution only (no publish method).\n * Use {@link ztaxTarget} for all publishing.\n *\n * @param serviceUrl - Base URL of the w3name-compatible service (default: https://name.web3.storage)\n */\nexport function w3nameTarget(serviceUrl = 'https://name.web3.storage'): IPNSPublishTarget {\n\treturn {\n\t\tname: 'w3name',\n\t\t// No publish() — w3name is read-only; publishing goes through ztaxTarget\n\t\tasync resolveSequence(ipnsName: string): Promise<bigint | null> {\n\t\t\treturn resolveIPNSSequence(serviceUrl, ipnsName)\n\t\t},\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport async function generateIpnsKey() {\n\treturn W3Name.create() // Returns W3Name.WritableName type\n}\n\nexport async function getW3NamePublic(pk: Uint8Array) {\n\tconst ipns = await W3Name.from(pk)\n\treturn ipns.toString()\n}\n","import { Logger } from 'besonders-logger'\nimport { CID } from 'multiformats/cid'\nimport ReconnectingWebSocket, { type Options as PartysocketOptions } from 'partysocket/ws'\n\nexport type { PartysocketOptions }\n\nconst { WARN, LOG, DEBUG, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars\n\n/**\n * `nameBaseUrl` is required for both `watchNameRaw` and `IpnsWatcher`. The\n * legacy `https://name.web3.storage` endpoint (used by the old hardcoded\n * `NAME_WS_URL`/`NAME_HTTP_URL` constants) is **shut down** — these classes\n * will not work without a real, configured naming service that supports\n * WebSocket subscriptions to `/name/<ipns>/watch` and HTTP GET on `/name/<ipns>`.\n *\n * As of writing no such public service exists, so most callers should expect\n * these to fail at runtime and handle the error in their `onError` handler.\n */\nfunction buildWsUrl(nameBaseUrl: string, name: string) {\n\tconst base = nameBaseUrl.replace(/\\/+$/, '').replace(/^http/, 'ws')\n\treturn `${base}/${name}/watch`\n}\nfunction buildHttpUrl(nameBaseUrl: string, name: string) {\n\tconst base = nameBaseUrl.replace(/\\/+$/, '')\n\treturn `${base}/${name}`\n}\n\nfunction requireNameBaseUrl(nameBaseUrl: string | undefined, fn: string): string {\n\tif (!nameBaseUrl) {\n\t\tthrow new Error(\n\t\t\t`[${fn}] nameBaseUrl is required. The legacy default `\n\t\t\t+ `https://name.web3.storage is shut down. Pass the base URL of a naming `\n\t\t\t+ `service that supports WebSocket subscriptions to /name/<ipns>/watch `\n\t\t\t+ `and HTTP GET on /name/<ipns>.`,\n\t\t)\n\t}\n\treturn nameBaseUrl\n}\n\nexport interface W3NameRecord {\n\tvalue: string // e.g. \"/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi\"\n\tseq?: number\n\tvalidity?: string\n}\n\n/**\n * Debug info provided when a stale WebSocket connection is detected.\n */\nexport interface StaleConnectionInfo {\n\t/** When the WebSocket connection was established */\n\tconnectedAt: Date\n\t/** When we last received a WebSocket message */\n\tlastMessageAt: Date | null\n\t/** How long since last message (ms) */\n\tsilenceDuration: number\n\t/** The stale value from WebSocket */\n\tstaleValue: string | null\n\t/** The current value from HTTP */\n\tcurrentValue: string\n}\n\n/**\n * Enriched IPNS update with parsed CID and change detection.\n * Backwards compatible - `.value` still works as before.\n */\nexport interface IpnsUpdate {\n\t/** Raw IPNS value string (e.g. '/ipfs/bafy...') — same as W3NameRecord.value */\n\tvalue: string\n\t/** Parsed CID if value is valid IPFS path, null otherwise */\n\tcid: CID | null\n\t/** Previous value (null on first update) */\n\tlastValue: string | null\n\t/** Whether this is a change from lastValue */\n\tisNew: boolean\n\t/** Original W3NameRecord for access to seq/validity */\n\trecord: W3NameRecord\n}\n\n/**\n * Parse CID from IPNS value string (e.g. \"/ipfs/bafybeig...\")\n * @returns CID if valid, null otherwise\n */\nfunction parseCidFromIpnsValue(value: string): CID | null {\n\ttry {\n\t\t// Strip /ipfs/ prefix if present\n\t\tconst cidStr = value.startsWith('/ipfs/') ? value.slice(6) : value\n\t\treturn CID.parse(cidStr)\n\t} catch {\n\t\tDEBUG('[parseCidFromIpnsValue] failed to parse:', value)\n\t\treturn null\n\t}\n}\n\nexport interface WatchRawOptions {\n\t/** Called when the IPNS record is updated */\n\tonUpdate: (record: W3NameRecord) => void\n\t/** Called when an error occurs */\n\tonError?: (error: Event | Error) => void\n\t/** Called when the connection is opened */\n\tonOpen?: () => void\n\t/** Called when the connection is closed */\n\tonClose?: (event: CloseEvent) => void\n}\n\nexport interface WatchRawSubscription {\n\t/** Close the WebSocket connection */\n\tclose: () => void\n\t/** The underlying WebSocket instance */\n\tws: WebSocket\n}\n\n/**\n * Low-level WebSocket watcher for IPNS (no reconnect logic).\n * Use this when you want full control over connection lifecycle.\n * For most cases, prefer `watchName` or `IpnsWatcher` which handle reconnection.\n *\n * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)\n * @param name - The IPNS name/key to watch\n * @param options - Callback options\n * @returns Subscription with close() and ws\n *\n * @example\n * ```ts\n * const sub = watchNameRaw('https://name.example.com', 'k51qzi5u...', {\n * onUpdate: (record) => console.log('Update:', record.value),\n * onClose: () => console.log('Disconnected - handle reconnect yourself'),\n * })\n * ```\n */\nexport function watchNameRaw(nameBaseUrl: string, name: string, options: WatchRawOptions): WatchRawSubscription {\n\tconst resolvedBase = requireNameBaseUrl(nameBaseUrl, 'watchNameRaw')\n\tconst url = buildWsUrl(resolvedBase, name)\n\tDEBUG('[watchNameRaw] connecting to', url)\n\n\tconst ws = new WebSocket(url)\n\n\tws.onopen = () => {\n\t\tLOG('[watchNameRaw] connected to', name)\n\t\toptions.onOpen?.()\n\t}\n\n\tws.onmessage = (event) => {\n\t\ttry {\n\t\t\tconst record: W3NameRecord = JSON.parse(event.data)\n\t\t\tDEBUG('[watchNameRaw] received update for', name, record)\n\t\t\toptions.onUpdate(record)\n\t\t} catch (err) {\n\t\t\tWARN('[watchNameRaw] failed to parse message:', event.data, err)\n\t\t\toptions.onError?.(err instanceof Error ? err : new Error(String(err)))\n\t\t}\n\t}\n\n\tws.onerror = (event) => {\n\t\tconst errorMsg = event instanceof ErrorEvent ? event.message : 'WebSocket error'\n\t\tWARN('[watchNameRaw] error for', name, ':', errorMsg)\n\t\toptions.onError?.(new Error(errorMsg))\n\t}\n\n\tws.onclose = (event) => {\n\t\tDEBUG('[watchNameRaw] closed for', name, 'code:', event.code)\n\t\toptions.onClose?.(event)\n\t}\n\n\treturn {\n\t\tclose: () => {\n\t\t\tDEBUG('[watchNameRaw] closing connection for', name)\n\t\t\tws.close()\n\t\t},\n\t\tws,\n\t}\n}\n\nexport interface IpnsWatcherOptions {\n\t/** Called when the IPNS record is updated (enriched payload with CID and change detection) */\n\tonUpdate: (update: IpnsUpdate) => void | Promise<void>\n\t/** Called when an error occurs */\n\tonError?: (error: Error | Event) => void\n\t/** Called when the connection is opened/reconnected */\n\tonConnected?: () => void\n\t/** Called when the connection is closed */\n\tonDisconnected?: () => void\n\t/** Fetch current IPNS state on first connect (default: false) */\n\tfetchInitialState?: boolean\n\t/** Fetch current IPNS state on reconnect to catch missed updates (default: true) */\n\tcatchUpOnReconnect?: boolean\n\t/** If true, call onUpdate even when value hasn't changed (default: false) */\n\tincludeUnchanged?: boolean\n\t/**\n\t * Enable periodic liveness checks via HTTP to detect zombie connections (default: true).\n\t * When enabled, periodically fetches current IPNS value and forces reconnect if it\n\t * differs from the last WebSocket update.\n\t */\n\tlivenessCheck?: boolean\n\t/**\n\t * Liveness check interval in milliseconds (default: 3600000 = 1 hour).\n\t * Only used when livenessCheck is enabled.\n\t */\n\tlivenessCheckInterval?: number\n\t/**\n\t * Called when a stale connection is detected (WebSocket missed updates).\n\t * Provides debug info about the connection state.\n\t */\n\tonStaleConnection?: (info: StaleConnectionInfo) => void\n\t/**\n\t * Partysocket options (passed through to ReconnectingWebSocket).\n\t * Useful options: startClosed, maxReconnectionDelay, minReconnectionDelay, etc.\n\t * @see https://github.com/partykit/partykit/tree/main/packages/partysocket\n\t */\n\twsOptions?: PartysocketOptions\n}\n\n/**\n * Robust IPNS watcher with auto-reconnect and catch-up logic.\n * Uses partysocket for reliable WebSocket reconnection.\n *\n * @example\n * ```ts\n * const watcher = new IpnsWatcher('k51qzi5uqu...', {\n * onUpdate: (update) => console.log('New CID:', update.cid?.toString()),\n * onError: (err) => console.error('Error:', err),\n * })\n *\n * // Later, to stop watching:\n * watcher.close()\n * ```\n */\nconst DEFAULT_LIVENESS_INTERVAL = 3600000 // 1 hour\n\nexport class IpnsWatcher {\n\tprivate name: string\n\tprivate nameBaseUrl: string\n\tprivate ws: ReconnectingWebSocket\n\tprivate lastKnownValue: string | null = null\n\tprivate options: IpnsWatcherOptions\n\tprivate isFirstConnect = true\n\tprivate livenessTimer: ReturnType<typeof setInterval> | null = null\n\tprivate connectedAt: Date | null = null\n\tprivate lastMessageAt: Date | null = null\n\n\tconstructor(nameBaseUrl: string, name: string, options: IpnsWatcherOptions) {\n\t\tthis.nameBaseUrl = requireNameBaseUrl(nameBaseUrl, 'IpnsWatcher')\n\t\tthis.name = name\n\t\tthis.options = options\n\n\t\tconst url = buildWsUrl(this.nameBaseUrl, name)\n\t\tDEBUG('[IpnsWatcher] creating for', name)\n\n\t\tthis.ws = new ReconnectingWebSocket(url, [], {\n\t\t\tmaxReconnectionDelay: 900000, // 15min\n\t\t\tminReconnectionDelay: 5000,\n\t\t\treconnectionDelayGrowFactor: 2,\n\t\t\tmaxRetries: Infinity,\n\t\t\t...options.wsOptions,\n\t\t})\n\n\t\tthis.ws.onopen = () => {\n\t\t\tLOG('[IpnsWatcher] connected to', name)\n\t\t\tthis.connectedAt = new Date()\n\t\t\toptions.onConnected?.()\n\n\t\t\t// Check for current state on first connect if requested\n\t\t\tif (this.isFirstConnect && (options.fetchInitialState ?? false)) {\n\t\t\t\tthis.checkForMissedUpdates()\n\t\t\t}\n\t\t\t// Check for missed updates on reconnect\n\t\t\telse if (!this.isFirstConnect && (options.catchUpOnReconnect ?? true)) {\n\t\t\t\tthis.checkForMissedUpdates()\n\t\t\t}\n\n\t\t\tthis.isFirstConnect = false\n\n\t\t\t// Start liveness checking (default: enabled)\n\t\t\tif (options.livenessCheck !== false) {\n\t\t\t\tthis.startLivenessCheck()\n\t\t\t}\n\t\t}\n\n\t\tthis.ws.onmessage = (event) => {\n\t\t\tthis.lastMessageAt = new Date()\n\t\t\ttry {\n\t\t\t\tconst record: W3NameRecord = JSON.parse(event.data as string)\n\t\t\t\tDEBUG('[IpnsWatcher] received update for', name, record)\n\n\t\t\t\tconst lastValue = this.lastKnownValue\n\t\t\t\tconst isNew = record.value !== lastValue\n\t\t\t\tconst cid = parseCidFromIpnsValue(record.value)\n\n\t\t\t\t// Skip unchanged values unless includeUnchanged is set\n\t\t\t\tif (!isNew && !options.includeUnchanged) {\n\t\t\t\t\tDEBUG('[IpnsWatcher] skipping unchanged value for', name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Update lastKnownValue after the skip check\n\t\t\t\tthis.lastKnownValue = record.value\n\n\t\t\t\tconst update: IpnsUpdate = {\n\t\t\t\t\tvalue: record.value,\n\t\t\t\t\tcid,\n\t\t\t\t\tlastValue,\n\t\t\t\t\tisNew,\n\t\t\t\t\trecord,\n\t\t\t\t}\n\n\t\t\t\tvoid options.onUpdate(update)\n\t\t\t} catch (err) {\n\t\t\t\tWARN('[IpnsWatcher] failed to parse message:', event.data, err)\n\t\t\t\toptions.onError?.(err instanceof Error ? err : new Error(String(err)))\n\t\t\t}\n\t\t}\n\n\t\tthis.ws.onerror = (event) => {\n\t\t\t// Extract meaningful error info instead of logging entire ErrorEvent\n\t\t\tconst errorMsg = event instanceof ErrorEvent ? event.message : 'WebSocket error'\n\n\t\t\t// \"Unexpected EOF\" is a normal disconnection - partysocket will auto-reconnect\n\t\t\t// Log at INFO level as it's expected behavior, not an error\n\t\t\tif (errorMsg === 'Unexpected EOF') {\n\t\t\t\tLOG('[IpnsWatcher] error for', name, ':', errorMsg, '(auto-reconnect enabled)')\n\t\t\t} else {\n\t\t\t\tWARN('[IpnsWatcher] error for', name, ':', errorMsg)\n\t\t\t}\n\n\t\t\t// Still call the error handler for unexpected errors\n\t\t\tif (errorMsg !== 'Unexpected EOF') {\n\t\t\t\toptions.onError?.(new Error(errorMsg))\n\t\t\t}\n\t\t}\n\n\t\tthis.ws.onclose = () => {\n\t\t\tDEBUG('[IpnsWatcher] disconnected from', name)\n\t\t\tthis.stopLivenessCheck()\n\t\t\tthis.connectedAt = null\n\t\t\tthis.lastMessageAt = null\n\t\t\toptions.onDisconnected?.()\n\t\t}\n\t}\n\n\t/**\n\t * Resolve current IPNS value via HTTP API to catch missed updates\n\t */\n\tprivate async checkForMissedUpdates(): Promise<void> {\n\t\ttry {\n\t\t\tDEBUG('[IpnsWatcher] checking for missed updates for', this.name)\n\t\t\tconst response = await fetch(buildHttpUrl(this.nameBaseUrl, this.name))\n\n\t\t\tif (!response.ok) {\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\tDEBUG('[IpnsWatcher] IPNS not yet published:', this.name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthrow new Error(`HTTP ${response.status}: ${response.statusText}`)\n\t\t\t}\n\n\t\t\tconst record: W3NameRecord = await response.json()\n\t\t\tconst lastValue = this.lastKnownValue\n\t\t\tconst isNew = record.value !== lastValue\n\t\t\tconst cid = parseCidFromIpnsValue(record.value)\n\n\t\t\t// Skip unchanged values unless includeUnchanged is set\n\t\t\tif (!isNew && !this.options.includeUnchanged) {\n\t\t\t\tDEBUG('[IpnsWatcher] no new updates for', this.name)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst logMsg = lastValue === null\n\t\t\t\t? '[IpnsWatcher] fetched initial state for'\n\t\t\t\t: '[IpnsWatcher] caught missed update for'\n\t\t\tLOG(logMsg, this.name, {\n\t\t\t\tprevious: lastValue,\n\t\t\t\tcurrent: record.value,\n\t\t\t})\n\n\t\t\t// Update lastKnownValue after the skip check\n\t\t\tthis.lastKnownValue = record.value\n\n\t\t\tconst update: IpnsUpdate = {\n\t\t\t\tvalue: record.value,\n\t\t\t\tcid,\n\t\t\t\tlastValue,\n\t\t\t\tisNew,\n\t\t\t\trecord,\n\t\t\t}\n\n\t\t\tvoid this.options.onUpdate(update)\n\t\t} catch (err) {\n\t\t\tWARN('[IpnsWatcher] failed to check for missed updates:', this.name, err)\n\t\t\tthis.options.onError?.(err instanceof Error ? err : new Error(String(err)))\n\t\t}\n\t}\n\n\t/**\n\t * Start periodic liveness checks to detect zombie connections.\n\t */\n\tprivate startLivenessCheck(): void {\n\t\tthis.stopLivenessCheck() // Clear any existing timer\n\t\tconst interval = this.options.livenessCheckInterval ?? DEFAULT_LIVENESS_INTERVAL\n\t\tDEBUG('[IpnsWatcher] starting liveness check for', this.name, 'interval:', interval)\n\n\t\tthis.livenessTimer = setInterval(() => {\n\t\t\tvoid this.performLivenessCheck()\n\t\t}, interval)\n\t}\n\n\t/**\n\t * Stop periodic liveness checks.\n\t */\n\tprivate stopLivenessCheck(): void {\n\t\tif (this.livenessTimer !== null) {\n\t\t\tDEBUG('[IpnsWatcher] stopping liveness check for', this.name)\n\t\t\tclearInterval(this.livenessTimer)\n\t\t\tthis.livenessTimer = null\n\t\t}\n\t}\n\n\t/**\n\t * Perform a single liveness check via HTTP.\n\t * If the HTTP value differs from lastKnownValue, the connection is stale.\n\t */\n\tprivate async performLivenessCheck(): Promise<void> {\n\t\ttry {\n\t\t\tDEBUG('[IpnsWatcher] performing liveness check for', this.name)\n\t\t\tconst response = await fetch(buildHttpUrl(this.nameBaseUrl, this.name))\n\n\t\t\tif (!response.ok) {\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\t// IPNS not published - if we also have null, that's consistent\n\t\t\t\t\tif (this.lastKnownValue === null) {\n\t\t\t\t\t\tDEBUG('[IpnsWatcher] liveness check OK (both null) for', this.name)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t// We have a value but HTTP says 404 - this shouldn't happen normally\n\t\t\t\t\tWARN('[IpnsWatcher] liveness check inconsistent (we have value, HTTP 404) for', this.name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthrow new Error(`HTTP ${response.status}: ${response.statusText}`)\n\t\t\t}\n\n\t\t\tconst record: W3NameRecord = await response.json()\n\n\t\t\t// Check if values match\n\t\t\tif (record.value === this.lastKnownValue) {\n\t\t\t\tDEBUG('[IpnsWatcher] liveness check OK for', this.name)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Stale connection detected!\n\t\t\tconst now = new Date()\n\t\t\tconst silenceDuration = this.lastMessageAt\n\t\t\t\t? now.getTime() - this.lastMessageAt.getTime()\n\t\t\t\t: this.connectedAt\n\t\t\t\t\t? now.getTime() - this.connectedAt.getTime()\n\t\t\t\t\t: 0\n\n\t\t\tconst staleInfo: StaleConnectionInfo = {\n\t\t\t\tconnectedAt: this.connectedAt ?? now,\n\t\t\t\tlastMessageAt: this.lastMessageAt,\n\t\t\t\tsilenceDuration,\n\t\t\t\tstaleValue: this.lastKnownValue,\n\t\t\t\tcurrentValue: record.value,\n\t\t\t}\n\n\t\t\tWARN('[IpnsWatcher] stale connection detected for', this.name, {\n\t\t\t\tconnectedAt: staleInfo.connectedAt.toISOString(),\n\t\t\t\tlastMessageAt: staleInfo.lastMessageAt?.toISOString() ?? 'never',\n\t\t\t\tsilenceDuration: `${Math.round(silenceDuration / 1000)}s`,\n\t\t\t\tstaleValue: staleInfo.staleValue,\n\t\t\t\tcurrentValue: staleInfo.currentValue,\n\t\t\t})\n\n\t\t\t// Notify via callback\n\t\t\tthis.options.onStaleConnection?.(staleInfo)\n\n\t\t\t// Fire immediate update with the current value\n\t\t\tconst lastValue = this.lastKnownValue\n\t\t\tconst cid = parseCidFromIpnsValue(record.value)\n\t\t\tthis.lastKnownValue = record.value\n\n\t\t\tconst update: IpnsUpdate = {\n\t\t\t\tvalue: record.value,\n\t\t\t\tcid,\n\t\t\t\tlastValue,\n\t\t\t\tisNew: true,\n\t\t\t\trecord,\n\t\t\t}\n\t\t\tvoid this.options.onUpdate(update)\n\n\t\t\t// Force reconnect to get a fresh connection\n\t\t\tLOG('[IpnsWatcher] forcing reconnect due to stale connection for', this.name)\n\t\t\tthis.ws.reconnect()\n\t\t} catch (err) {\n\t\t\t// Don't treat HTTP errors as stale - could be network issue\n\t\t\tWARN('[IpnsWatcher] liveness check failed for', this.name, err)\n\t\t}\n\t}\n\n\t/**\n\t * Manually start/reconnect the WebSocket.\n\t * Only needed if you used `wsOptions: { startClosed: true }`.\n\t */\n\tstart(): void {\n\t\tLOG('[IpnsWatcher] starting watcher for', this.name)\n\t\tthis.ws.reconnect()\n\t}\n\n\t/**\n\t * Alias for close() - for backward compatibility\n\t */\n\tstop(): void {\n\t\tthis.close()\n\t}\n\n\t/**\n\t * Close the WebSocket connection and stop watching\n\t */\n\tclose(): void {\n\t\tLOG('[IpnsWatcher] closing watcher for', this.name)\n\t\tthis.stopLivenessCheck()\n\t\tthis.ws.close()\n\t}\n\n\t/**\n\t * Get the last known IPNS value\n\t */\n\tget lastValue(): string | null {\n\t\treturn this.lastKnownValue\n\t}\n\n\t/**\n\t * Get the WebSocket ready state\n\t */\n\tget readyState(): number {\n\t\treturn this.ws.readyState\n\t}\n}\n\n/**\n * Create an IPNS watcher with auto-reconnect and catch-up logic.\n * Convenience function that creates and returns an IpnsWatcher instance.\n *\n * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)\n * @param name - The IPNS name/key to watch (e.g. \"k51qzi5u...\")\n * @param options - Callback options for handling events\n * @returns An IpnsWatcher instance with close() method\n */\nexport function watchName(nameBaseUrl: string, name: string, options: IpnsWatcherOptions): IpnsWatcher {\n\treturn new IpnsWatcher(nameBaseUrl, name, options)\n}\n\n/**\n * Watch an IPNS name and return updates as an async iterator.\n * Includes auto-reconnect - iterator continues through disconnections.\n *\n * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)\n * @param name - The IPNS name/key to watch\n * @param signal - Optional AbortSignal to stop the watch\n *\n * @example\n * ```ts\n * const controller = new AbortController()\n * for await (const update of watchNameIterator('https://name.example.com', 'k51qzi5u...', controller.signal)) {\n * console.log('Update:', update.cid?.toString())\n * }\n * ```\n */\nexport async function* watchNameIterator(\n\tnameBaseUrl: string,\n\tname: string,\n\tsignal?: AbortSignal,\n): AsyncGenerator<IpnsUpdate, void, unknown> {\n\tconst queue: IpnsUpdate[] = []\n\tlet resolve: (() => void) | null = null\n\tlet error: Error | null = null\n\n\tconst watcher = new IpnsWatcher(nameBaseUrl, name, {\n\t\tonUpdate: (update) => {\n\t\t\tqueue.push(update)\n\t\t\tresolve?.()\n\t\t},\n\t\tonError: (err) => {\n\t\t\terror = err instanceof Error ? err : new Error('WebSocket error')\n\t\t\tresolve?.()\n\t\t},\n\t})\n\n\tsignal?.addEventListener('abort', () => {\n\t\twatcher.close()\n\t})\n\n\ttry {\n\t\twhile (!signal?.aborted) {\n\t\t\tif (queue.length > 0) {\n\t\t\t\tyield queue.shift()!\n\t\t\t} else if (error) {\n\t\t\t\t// Log error but continue - partysocket will reconnect\n\t\t\t\tWARN('[watchNameIterator] error occurred, continuing:', error)\n\t\t\t\terror = null\n\t\t\t} else {\n\t\t\t\tawait new Promise<void>((r) => {\n\t\t\t\t\tresolve = r\n\t\t\t\t})\n\t\t\t\tresolve = null\n\t\t\t}\n\t\t}\n\t} finally {\n\t\twatcher.close()\n\t}\n}\n"],"mappings":"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","names":["Logger","base64pad","WARN","LOG","DEBUG","Logger","base64pad","Logger","CID","WARN","LOG","DEBUG","ERROR","resolve"]}
1
+ {"version":3,"sources":["../src/ipns/gateway-resolver.ts","../src/ipns/ipns-record.ts","../src/ipns/ipns-w3name.ts","../src/ipns/ipns-watcher.ts"],"sourcesContent":["import { CID } from 'multiformats/cid'\nimport { Logger } from 'besonders-logger'\n\nconst { WARN, LOG, DEBUG } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars\n\n/**\n * Resolve an IPNS name to a CID using a public IPFS gateway's HTTP HEAD response.\n *\n * Mechanism: per the IPFS HTTP Gateway spec, `HEAD <gateway>/ipns/<name>/` returns the\n * IPNS-resolved root CID in the `X-Ipfs-Roots` response header (space-separated, ordered\n * from root to leaf). The first entry is the IPNS-resolved CID.\n *\n * This works against any gateway that follows the spec and exposes CORS for HEAD\n * (most public gateways do, e.g. ipfs.zt.ax, ipfs.io, dweb.link).\n *\n * The legacy w3name HTTP endpoint (`GET <base>/name/<ipns>` returning `{value: \"/ipfs/<cid>\"}`)\n * is also supported here for back-compat with self-hosted w3name-like services — but the\n * X-Ipfs-Roots path is preferred since it's the standardised gateway mechanism.\n *\n * @param ipns - The IPNS name (k51... string)\n * @param gateways - List of gateway base URLs (e.g. `[\"https://ipfs.zt.ax\"]`)\n * @returns The resolved CID, or null if no gateway could resolve the name\n */\nexport async function resolveIPNSViaGateway(ipns: string, gateways: string[]): Promise<CID | null> {\n\tif (!ipns.startsWith('k51')) return null // only IPNS libp2p-key names go through gateway\n\tif (!gateways?.length) return null\n\n\tfor (const rawGateway of gateways) {\n\t\tconst gateway = rawGateway.replace(/\\/+$/, '')\n\t\tconst url = `${gateway}/ipns/${ipns}/`\n\t\ttry {\n\t\t\tDEBUG(`[resolveIPNSViaGateway] HEAD ${url}`)\n\t\t\tconst response = await fetch(url, { method: 'HEAD' })\n\t\t\tif (!response.ok) {\n\t\t\t\tDEBUG(`[resolveIPNSViaGateway] ${gateway} returned ${response.status}`)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst roots = response.headers.get('x-ipfs-roots') ?? response.headers.get('X-Ipfs-Roots')\n\t\t\tif (roots) {\n\t\t\t\tconst first = roots.split(/[\\s,]+/)[0]?.trim()\n\t\t\t\tif (first) {\n\t\t\t\t\tconst cid = CID.parse(first)\n\t\t\t\t\tDEBUG(`[resolveIPNSViaGateway] resolved via ${gateway} x-ipfs-roots:`, cid.toString())\n\t\t\t\t\treturn cid\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Some gateways omit X-Ipfs-Roots but put the CID in etag (e.g. `<cid>.dag-json`)\n\t\t\tconst etag = response.headers.get('etag')\n\t\t\tif (etag) {\n\t\t\t\tconst m = etag.match(/^\"?([a-z0-9]+)/i)\n\t\t\t\tif (m) {\n\t\t\t\t\tconst cid = CID.parse(m[1])\n\t\t\t\t\tDEBUG(`[resolveIPNSViaGateway] resolved via ${gateway} etag:`, cid.toString())\n\t\t\t\t\treturn cid\n\t\t\t\t}\n\t\t\t}\n\t\t\tWARN(`[resolveIPNSViaGateway] ${gateway} returned 200 but no usable CID header`)\n\t\t} catch (err) {\n\t\t\tWARN(`[resolveIPNSViaGateway] ${gateway} failed:`, err)\n\t\t}\n\t}\n\treturn null\n}\n","import { createIPNSRecord, marshalIPNSRecord, unmarshalIPNSRecord } from 'ipns'\nimport { privateKeyFromRaw } from '@libp2p/crypto/keys'\nimport { base36 } from 'multiformats/bases/base36'\nimport { base64pad } from 'multiformats/bases/base64'\nimport type { CID } from 'multiformats/cid'\n\nexport interface SignedIPNSRecord {\n\trecordBytes: Uint8Array // marshalled protobuf, signed — the wire format\n\tipnsName: string // k51... string\n\tvalue: string // /ipfs/<cid>\n\tsequence: bigint\n}\n\n/** Derive IPNS name string (k51...) from Ed25519 private key bytes */\nexport function ipnsNameFromPrivateKey(privKeyBytes: Uint8Array): string {\n\tconst privKey = privateKeyFromRaw(privKeyBytes)\n\treturn privKey.publicKey.toCID().toString(base36)\n}\n\n/**\n * Create a signed IPNS record (protobuf wire format).\n * Same bytes can be published to any naming service.\n */\nexport async function createSignedIPNSRecord(\n\tprivateKey: Uint8Array,\n\tcid: CID,\n\tsequence: bigint,\n\tlifetimeMs = 365 * 24 * 60 * 60 * 1000, // 1 year\n): Promise<SignedIPNSRecord> {\n\tconst privKey = privateKeyFromRaw(privateKey)\n\tconst value = `/ipfs/${cid.toV1()}`\n\tconst record = await createIPNSRecord(privKey, value, sequence, lifetimeMs)\n\tconst recordBytes = marshalIPNSRecord(record)\n\tconst ipnsName = privKey.publicKey.toCID().toString(base36)\n\treturn { recordBytes, ipnsName, value, sequence }\n}\n\nexport { unmarshalIPNSRecord }\n\n/**\n * A target that can receive a signed IPNS record, advertise its current\n * sequence, or both.\n *\n * - `publish` is called by `publishIPNSRecord` to actually store the record\n * on the target's backing service. Targets without `publish` are skipped\n * during the fan-out (e.g. a sequence-only source).\n * - `resolveSequence` is consulted by `publishIPNSRecord` to compute the\n * next IPNS sequence. The first target to return a value (including\n * `null` for \"never published\") wins. Throw to indicate a transient\n * error — the caller will try the next target.\n *\n * Most real targets (e.g. a storage connector) provide both. A simple\n * \"track sequence in localStorage\" target only needs `resolveSequence`.\n */\nexport interface IPNSPublishTarget {\n\tname: string\n\tpublish?(ipnsName: string, recordBytes: Uint8Array): Promise<void>\n\tresolveSequence?(ipnsName: string): Promise<bigint | null>\n}\n\n/**\n * Resolve the current IPNS sequence from a generic naming service.\n * Returns null if the name was never published (404).\n * Throws on network/server errors so the caller can try a different target.\n */\nexport async function resolveIPNSSequence(\n\tnameServiceUrl: string,\n\tipnsName: string,\n): Promise<bigint | null> {\n\tconst url = `${nameServiceUrl}/name/${ipnsName}`\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetch(url)\n\t} catch (err) {\n\t\tthrow new Error(`Network error resolving IPNS ${ipnsName}: ${err}`)\n\t}\n\n\tif (response.status === 404) return null\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP ${response.status} resolving IPNS ${ipnsName}: ${response.statusText}`)\n\t}\n\n\tconst { record, value } = await response.json()\n\tif (!record && !value) return null // never published\n\n\t// If raw record is available, unmarshal to get sequence\n\tif (record) {\n\t\tconst bytes = base64pad.baseDecode(record)\n\t\tconst entry = unmarshalIPNSRecord(bytes)\n\t\treturn entry.sequence\n\t}\n\n\t// Server only returned a value, no raw record — can't know the exact sequence.\n\t// Most services still accept this as \"previous published\"; treat as seq=0n.\n\treturn 0n\n}\n\n/**\n * Regex to detect Kubo IPNS sequence conflict in error messages.\n *\n * Matches messages like:\n * \"existing IPNS record has sequence 406 >= new record sequence 406\"\n *\n * The operator between the two sequence numbers is matched as an opaque\n * non-whitespace token (`\\S{1,12}`) on purpose: Go's JSON encoder HTML-escapes\n * `>` to `>`, so the string that actually reaches us through the storage\n * proxy reads `... sequence 406 >= new record sequence 406 ...`. A regex\n * hard-coded to `>=` (or even a non-digit bridge like `\\D+`, which trips over\n * the digits inside `>`) would silently fail to match, the\n * sequence-coherence retry below would never fire, and the publish would\n * surface the generic \"All IPNS publish targets failed\" error instead of\n * self-healing.\n *\n * Capture 1 = existing (server) sequence, capture 2 = rejected (new) sequence.\n */\nconst SEQ_CONFLICT_RE = /existing IPNS record has sequence (\\d+) \\S{1,12} new record sequence (\\d+)/\n\n/**\n * Options for {@link publishIPNSRecord}.\n */\nexport interface PublishIPNSRecordOptions {\n\t/**\n\t * Max number of times to bump the sequence on \"existing >= new\" conflict.\n\t * Defaults to 3. Each bump re-signs the record with a higher sequence\n\t * and retries all targets.\n\t */\n\tmaxSequenceBumps?: number\n}\n\n/**\n * Create a signed IPNS record and publish to all configured targets.\n *\n * Sequence resolution: walks `targets` in order asking each one with a\n * `resolveSequence` method. The first target to successfully return a value\n * (including `null` for \"never published\") determines the next sequence.\n * If every target throws or none supports `resolveSequence`, falls back to 0n.\n *\n * Publish fan-out: only targets with a `publish` method are called.\n * Throws if every publish-capable target fails; partial failures are logged.\n *\n * **Sequence-coherence retry:** if a publish target rejects with the Kubo\n * \"existing IPNS record has sequence X >= new record sequence Y\" error,\n * the function parses `X`, bumps the sequence to `max(X + 1n, Y + 1n)`,\n * re-signs the record, and retries (up to `maxSequenceBumps` times).\n * This is the \"increment and clobber\" mechanism that recovers from\n * sequence drift without requiring server-side `--force` support.\n */\nexport async function publishIPNSRecord(\n\tprivateKey: Uint8Array,\n\tcid: CID,\n\ttargets: IPNSPublishTarget[],\n\toptions?: PublishIPNSRecordOptions,\n): Promise<SignedIPNSRecord> {\n\tconst ipnsName = ipnsNameFromPrivateKey(privateKey)\n\tconst maxBumps = options?.maxSequenceBumps ?? 3\n\n\tconst publishTargets = targets.filter(t => typeof t.publish === 'function')\n\tif (publishTargets.length === 0) {\n\t\tthrow new Error('No publish-capable targets supplied to publishIPNSRecord')\n\t}\n\n\tlet sequence: bigint | undefined\n\tlet bumpFloor: bigint | undefined\n\n\tfor (let attempt = 0;; attempt++) {\n\t\t// Compute next sequence on first pass or after a conflict bump\n\t\tif (sequence === undefined) {\n\t\t\tsequence = await pickNextSequence(ipnsName, targets)\n\t\t}\n\t\tif (bumpFloor !== undefined) {\n\t\t\t// bumpFloor was set on previous attempt from a conflict error\n\t\t\tif (bumpFloor > sequence) sequence = bumpFloor\n\t\t\tbumpFloor = undefined\n\t\t}\n\n\t\tconst signed = await createSignedIPNSRecord(privateKey, cid, sequence)\n\n\t\tconst results = await Promise.allSettled(\n\t\t\tpublishTargets.map(t => t.publish!(ipnsName, signed.recordBytes)),\n\t\t)\n\t\tconst failures = results\n\t\t\t.map((r, i) => ({ r, name: publishTargets[i].name }))\n\t\t\t.filter(({ r }) => r.status === 'rejected') as { r: PromiseRejectedResult; name: string }[]\n\n\t\t// All succeeded — done\n\t\tif (failures.length === 0) {\n\t\t\treturn signed\n\t\t}\n\n\t\t// Check if any failure is a sequence conflict we can recover from\n\t\tconst conflictReasons = failures.filter(({ r }) => SEQ_CONFLICT_RE.test(typeof r.reason === 'string' ? r.reason : String(r.reason)))\n\n\t\tif (conflictReasons.length > 0 && attempt < maxBumps) {\n\t\t\t// Parse the highest existing sequence from each conflict error\n\t\t\tlet bump = sequence\n\t\t\tfor (const { r } of conflictReasons) {\n\t\t\t\tconst msg = typeof r.reason === 'string' ? r.reason : String(r.reason)\n\t\t\t\tconst m = msg.match(SEQ_CONFLICT_RE)\n\t\t\t\tif (m) {\n\t\t\t\t\tconst existing = BigInt(m[1])\n\t\t\t\t\tif (existing >= bump) bump = existing + 1n\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bump > sequence) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[publishIPNSRecord] Sequence conflict: server seq ${bump - 1n} >= current ${sequence}, ` +\n\t\t\t\t\t\t`bumping to ${bump} (attempt ${attempt + 1}/${maxBumps})`,\n\t\t\t\t)\n\t\t\t\tsequence = bump\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Partial failure (some targets succeeded) — log and return the signed record\n\t\tif (failures.length < publishTargets.length) {\n\t\t\tfor (const { r, name } of failures) {\n\t\t\t\tconsole.warn(`[publishIPNSRecord] target '${name}' failed:`, r.reason)\n\t\t\t}\n\t\t\treturn signed\n\t\t}\n\n\t\t// Every publish-capable target failed and we cannot recover\n\t\tif (conflictReasons.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`IPNS sequence conflict not resolved after ${Math.min(attempt + 1, maxBumps)} bumps. ` +\n\t\t\t\t\t`All publish targets failed: ${failures.map(({ r, name }) => `${name}: ${r.reason}`).join('; ')}`,\n\t\t\t)\n\t\t}\n\t\tthrow new Error(\n\t\t\t`All IPNS publish targets failed: ${failures.map(({ r, name }) => `${name}: ${r.reason}`).join('; ')}`,\n\t\t)\n\t}\n}\n\n/**\n * Walk targets, asking each to resolve the current IPNS sequence. First success wins.\n * Falls back to 0n if no target can answer.\n */\nasync function pickNextSequence(\n\tipnsName: string,\n\ttargets: IPNSPublishTarget[],\n): Promise<bigint> {\n\tconst capable = targets.filter(t => typeof t.resolveSequence === 'function')\n\tif (capable.length === 0) {\n\t\treturn 0n\n\t}\n\n\tfor (const target of capable) {\n\t\ttry {\n\t\t\tconst current = await target.resolveSequence!(ipnsName)\n\t\t\treturn current == null ? 0n : current + 1n\n\t\t} catch (err) {\n\t\t\tconsole.warn(`[publishIPNSRecord] target '${target.name}' sequence resolve failed:`, err)\n\t\t}\n\t}\n\n\tconsole.warn(`[publishIPNSRecord] no target could resolve sequence for ${ipnsName} — starting at 0n`)\n\treturn 0n\n}\n","import type { IPNSPublishTarget } from '@wovin/core/ipns'\nimport { Logger } from 'besonders-logger'\nimport { base64pad } from 'multiformats/bases/base64'\nimport { resolveIPNSSequence, unmarshalIPNSRecord } from './ipns-record.ts'\nimport { CID } from 'multiformats/cid'\nimport * as W3Name from 'w3name'\n\nconst { WARN, LOG, DEBUG, ERROR } = Logger.setup(Logger.INFO)\n\n/**\n * Try to resolve IPNS name to get existing revision.\n * Returns null if record doesn't exist (404).\n * Throws on network errors or server errors.\n *\n * This does a custom HTTP check first to distinguish 404 from network errors,\n * then delegates to W3Name.resolve() for validation if record exists.\n */\nasync function tryResolveIPNS(ipns: W3Name.WritableName): Promise<W3Name.Revision | null> {\n\tconst url = `https://name.web3.storage/name/${ipns.toString()}`\n\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetch(url, { signal: AbortSignal.timeout(30_000) })\n\t} catch (err) {\n\t\t// Network error (no connection, DNS failure, etc.)\n\t\tthrow ERROR('[w3name] Network error resolving IPNS:', err)\n\t}\n\n\t// 404 = record never published\n\tif (response.status === 404) {\n\t\tDEBUG('[w3name] IPNS record not found (never published):', ipns.toString())\n\t\treturn null\n\t}\n\n\t// Other HTTP errors (5xx server error, etc.)\n\tif (!response.ok) {\n\t\tthrow ERROR(`[w3name] HTTP ${response.status} resolving IPNS:`, response.statusText)\n\t}\n\n\t// Success - use W3Name.resolve to get validated Revision\n\t// (We could parse the record ourselves, but W3Name does validation/signature checks)\n\tconst existing = await W3Name.resolve(ipns)\n\treturn existing\n}\n\n/**\n * Publish CID to IPNS, automatically handling increment vs v0.\n * Returns the revision for further processing (e.g., Kubo integration).\n */\nexport async function publishIPNS(ipnsPrivateKey: Uint8Array, cid: CID): Promise<W3Name.Revision> {\n\tconst TIMEOUT_MS = 30_000\n\tconst timeout = new Promise<never>((_, reject) =>\n\t\tsetTimeout(() => reject(new Error(`publishIPNS timed out after ${TIMEOUT_MS}ms`)), TIMEOUT_MS),\n\t)\n\treturn Promise.race([_publishIPNSImpl(ipnsPrivateKey, cid), timeout])\n}\n\nasync function _publishIPNSImpl(ipnsPrivateKey: Uint8Array, cid: CID): Promise<W3Name.Revision> {\n\tconst value = `/ipfs/${cid}`\n\tconst ipns = await W3Name.from(ipnsPrivateKey)\n\n\tlet revision: W3Name.Revision\n\tconst existing = await tryResolveIPNS(ipns)\n\n\tif (existing) {\n\t\t// Record exists - increment sequence number\n\t\trevision = await W3Name.increment(existing, value)\n\t\tDEBUG('[w3name] incrementing revision for', ipns.toString())\n\t} else {\n\t\t// First publish - use v0\n\t\trevision = await W3Name.v0(ipns, value)\n\t\tDEBUG('[w3name] creating initial revision for', ipns.toString())\n\t}\n\n\tawait W3Name.publish(revision, ipns.key)\n\tDEBUG('[w3name] published', cid.toString(), 'to', ipns.toString())\n\n\treturn revision // Return for Kubo integration or other uses\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// zt.ax naming service target (primary)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve the current IPNS sequence from a zt.ax-compatible naming service.\n *\n * The naming service API uses the simple W3NameRecord format:\n * `GET <baseUrl>/<ipnsName>` → `{ value: \"/ipfs/<cid>\", seq?: number, validity?: string }`\n *\n * Also supports the legacy w3name record format (`{ record: \"<base64>\", value: \"...\" }`)\n * for backward compatibility with hybrid services.\n */\nexport async function resolveZtaxSequence(\n\tbaseUrl: string,\n\tipnsName: string,\n): Promise<bigint | null> {\n\tconst url = `${baseUrl.replace(/\\/+$/, '')}/${ipnsName}`\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetch(url)\n\t} catch (err) {\n\t\tthrow new Error(`Network error resolving sequence from ${baseUrl}: ${err}`)\n\t}\n\n\tif (response.status === 404) return null\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP ${response.status} resolving sequence from ${baseUrl}: ${response.statusText}`)\n\t}\n\n\tconst body: Record<string, unknown> = await response.json()\n\n\t// Format 1: simple W3NameRecord with seq number\n\tif (typeof body.seq === 'number') {\n\t\treturn BigInt(body.seq)\n\t}\n\n\t// Format 2: legacy w3name record with base64-encoded protobuf\n\tif (typeof body.record === 'string') {\n\t\ttry {\n\t\t\tconst bytes = base64pad.baseDecode(body.record)\n\t\t\tconst entry = unmarshalIPNSRecord(bytes)\n\t\t\treturn entry.sequence\n\t\t} catch {\n\t\t\tWARN('[resolveZtaxSequence] failed to unmarshal record for', ipnsName)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t// No sequence info — treat as never published or zero\n\treturn null\n}\n\n/**\n * Create an IPNSPublishTarget that publishes to a zt.ax naming service.\n *\n * Uses HTTP POST to publish signed IPNS records and HTTP GET to resolve\n * the current sequence number, following the same wire format as the\n * standard w3name API but at a configurable base URL.\n *\n * The naming service is expected to support:\n * - `POST <baseUrl>/<ipnsName>` — publish signed IPNS record (base64-encoded body)\n * - `GET <baseUrl>/<ipnsName>` — resolve current record (`{ value, seq?, record? }`)\n *\n * @param baseUrl - Base URL of the naming service (default: https://ipfs.zt.ax)\n */\nexport function ztaxTarget(baseUrl = 'https://ipfs.zt.ax'): IPNSPublishTarget {\n\tconst cleanBase = baseUrl.replace(/\\/+$/, '')\n\treturn {\n\t\tname: 'zt.ax',\n\t\tasync publish(ipnsName: string, recordBytes: Uint8Array) {\n\t\t\tconst url = `${cleanBase}/${ipnsName}`\n\t\t\tDEBUG(`[ztaxTarget] POST ${url}`)\n\t\t\tconst res = await fetch(url, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: base64pad.baseEncode(recordBytes),\n\t\t\t})\n\t\t\tif (!res.ok) {\n\t\t\t\tlet detail = ''\n\t\t\t\ttry {\n\t\t\t\t\tconst body = await res.json() as Record<string, unknown>\n\t\t\t\t\tdetail = body.message ? ` — ${body.message}` : ''\n\t\t\t\t} catch {\n\t\t\t\t\tdetail = res.statusText ? ` — ${res.statusText}` : ''\n\t\t\t\t}\n\t\t\t\tthrow new Error(`zt.ax HTTP ${res.status}${detail}`)\n\t\t\t}\n\t\t},\n\t\tasync resolveSequence(ipnsName: string): Promise<bigint | null> {\n\t\t\treturn resolveZtaxSequence(cleanBase, ipnsName)\n\t\t},\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// w3name naming service target (deprecated — read‑only backup)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create an IPNSPublishTarget for the w3name service.\n *\n * @deprecated w3name is shut down for publishing. This target is kept as a\n * read‑only backup for sequence resolution only (no publish method).\n * Use {@link ztaxTarget} for all publishing.\n *\n * @param serviceUrl - Base URL of the w3name-compatible service (default: https://name.web3.storage)\n */\nexport function w3nameTarget(serviceUrl = 'https://name.web3.storage'): IPNSPublishTarget {\n\treturn {\n\t\tname: 'w3name',\n\t\t// No publish() — w3name is read-only; publishing goes through ztaxTarget\n\t\tasync resolveSequence(ipnsName: string): Promise<bigint | null> {\n\t\t\treturn resolveIPNSSequence(serviceUrl, ipnsName)\n\t\t},\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport async function generateIpnsKey() {\n\treturn W3Name.create() // Returns W3Name.WritableName type\n}\n\nexport async function getW3NamePublic(pk: Uint8Array) {\n\tconst ipns = await W3Name.from(pk)\n\treturn ipns.toString()\n}\n","import { Logger } from 'besonders-logger'\nimport { CID } from 'multiformats/cid'\nimport ReconnectingWebSocket, { type Options as PartysocketOptions } from 'partysocket/ws'\n\nexport type { PartysocketOptions }\n\nconst { WARN, LOG, DEBUG, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars\n\n/**\n * `nameBaseUrl` is required for both `watchNameRaw` and `IpnsWatcher`. The\n * legacy `https://name.web3.storage` endpoint (used by the old hardcoded\n * `NAME_WS_URL`/`NAME_HTTP_URL` constants) is **shut down** — these classes\n * will not work without a real, configured naming service that supports\n * WebSocket subscriptions to `/name/<ipns>/watch` and HTTP GET on `/name/<ipns>`.\n *\n * As of writing no such public service exists, so most callers should expect\n * these to fail at runtime and handle the error in their `onError` handler.\n */\nfunction buildWsUrl(nameBaseUrl: string, name: string) {\n\tconst base = nameBaseUrl.replace(/\\/+$/, '').replace(/\\/name$/, '').replace(/^http/, 'ws')\n\treturn `${base}/name/${name}/watch`\n}\nfunction buildHttpUrl(nameBaseUrl: string, name: string) {\n\tconst base = nameBaseUrl.replace(/\\/+$/, '').replace(/\\/name$/, '')\n\treturn `${base}/name/${name}`\n}\n\nfunction requireNameBaseUrl(nameBaseUrl: string | undefined, fn: string): string {\n\tif (!nameBaseUrl) {\n\t\tthrow new Error(\n\t\t\t`[${fn}] nameBaseUrl is required. The legacy default `\n\t\t\t\t+ `https://name.web3.storage is shut down. Pass the base URL of a naming `\n\t\t\t\t+ `service that supports WebSocket subscriptions to /name/<ipns>/watch `\n\t\t\t\t+ `and HTTP GET on /name/<ipns>.`,\n\t\t)\n\t}\n\treturn nameBaseUrl\n}\n\nexport interface W3NameRecord {\n\tvalue: string // e.g. \"/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi\"\n\tseq?: number\n\tvalidity?: string\n}\n\n/**\n * Debug info provided when a stale WebSocket connection is detected.\n */\nexport interface StaleConnectionInfo {\n\t/** When the WebSocket connection was established */\n\tconnectedAt: Date\n\t/** When we last received a WebSocket message */\n\tlastMessageAt: Date | null\n\t/** How long since last message (ms) */\n\tsilenceDuration: number\n\t/** The stale value from WebSocket */\n\tstaleValue: string | null\n\t/** The current value from HTTP */\n\tcurrentValue: string\n}\n\n/**\n * Enriched IPNS update with parsed CID and change detection.\n * Backwards compatible - `.value` still works as before.\n */\nexport interface IpnsUpdate {\n\t/** Raw IPNS value string (e.g. '/ipfs/bafy...') — same as W3NameRecord.value */\n\tvalue: string\n\t/** Parsed CID if value is valid IPFS path, null otherwise */\n\tcid: CID | null\n\t/** Previous value (null on first update) */\n\tlastValue: string | null\n\t/** Whether this is a change from lastValue */\n\tisNew: boolean\n\t/** Original W3NameRecord for access to seq/validity */\n\trecord: W3NameRecord\n}\n\n/**\n * Parse CID from IPNS value string (e.g. \"/ipfs/bafybeig...\")\n * @returns CID if valid, null otherwise\n */\nfunction parseCidFromIpnsValue(value: string): CID | null {\n\ttry {\n\t\t// Strip /ipfs/ prefix if present\n\t\tconst cidStr = value.startsWith('/ipfs/') ? value.slice(6) : value\n\t\treturn CID.parse(cidStr)\n\t} catch {\n\t\tDEBUG('[parseCidFromIpnsValue] failed to parse:', value)\n\t\treturn null\n\t}\n}\n\nexport interface WatchRawOptions {\n\t/** Called when the IPNS record is updated */\n\tonUpdate: (record: W3NameRecord) => void\n\t/** Called when an error occurs */\n\tonError?: (error: Event | Error) => void\n\t/** Called when the connection is opened */\n\tonOpen?: () => void\n\t/** Called when the connection is closed */\n\tonClose?: (event: CloseEvent) => void\n}\n\nexport interface WatchRawSubscription {\n\t/** Close the WebSocket connection */\n\tclose: () => void\n\t/** The underlying WebSocket instance */\n\tws: WebSocket\n}\n\n/**\n * Low-level WebSocket watcher for IPNS (no reconnect logic).\n * Use this when you want full control over connection lifecycle.\n * For most cases, prefer `watchName` or `IpnsWatcher` which handle reconnection.\n *\n * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)\n * @param name - The IPNS name/key to watch\n * @param options - Callback options\n * @returns Subscription with close() and ws\n *\n * @example\n * ```ts\n * const sub = watchNameRaw('https://name.example.com', 'k51qzi5u...', {\n * onUpdate: (record) => console.log('Update:', record.value),\n * onClose: () => console.log('Disconnected - handle reconnect yourself'),\n * })\n * ```\n */\nexport function watchNameRaw(nameBaseUrl: string, name: string, options: WatchRawOptions): WatchRawSubscription {\n\tconst resolvedBase = requireNameBaseUrl(nameBaseUrl, 'watchNameRaw')\n\tconst url = buildWsUrl(resolvedBase, name)\n\tDEBUG('[watchNameRaw] connecting to', url)\n\n\tconst ws = new WebSocket(url)\n\n\tws.onopen = () => {\n\t\tLOG('[watchNameRaw] connected to', name)\n\t\toptions.onOpen?.()\n\t}\n\n\tws.onmessage = (event) => {\n\t\ttry {\n\t\t\tconst record: W3NameRecord = JSON.parse(event.data)\n\t\t\tDEBUG('[watchNameRaw] received update for', name, record)\n\t\t\toptions.onUpdate(record)\n\t\t} catch (err) {\n\t\t\tWARN('[watchNameRaw] failed to parse message:', event.data, err)\n\t\t\toptions.onError?.(err instanceof Error ? err : new Error(String(err)))\n\t\t}\n\t}\n\n\tws.onerror = (event) => {\n\t\tconst errorMsg = event instanceof ErrorEvent ? event.message : 'WebSocket error'\n\t\tWARN('[watchNameRaw] error for', name, ':', errorMsg)\n\t\toptions.onError?.(new Error(errorMsg))\n\t}\n\n\tws.onclose = (event) => {\n\t\tDEBUG('[watchNameRaw] closed for', name, 'code:', event.code)\n\t\toptions.onClose?.(event)\n\t}\n\n\treturn {\n\t\tclose: () => {\n\t\t\tDEBUG('[watchNameRaw] closing connection for', name)\n\t\t\tws.close()\n\t\t},\n\t\tws,\n\t}\n}\n\nexport interface IpnsWatcherOptions {\n\t/** Called when the IPNS record is updated (enriched payload with CID and change detection) */\n\tonUpdate: (update: IpnsUpdate) => void | Promise<void>\n\t/** Called when an error occurs */\n\tonError?: (error: Error | Event) => void\n\t/** Called when the connection is opened/reconnected */\n\tonConnected?: () => void\n\t/** Called when the connection is closed */\n\tonDisconnected?: () => void\n\t/** Fetch current IPNS state on first connect (default: false) */\n\tfetchInitialState?: boolean\n\t/** Fetch current IPNS state on reconnect to catch missed updates (default: true) */\n\tcatchUpOnReconnect?: boolean\n\t/** If true, call onUpdate even when value hasn't changed (default: false) */\n\tincludeUnchanged?: boolean\n\t/**\n\t * Enable periodic liveness checks via HTTP to detect zombie connections (default: true).\n\t * When enabled, periodically fetches current IPNS value and forces reconnect if it\n\t * differs from the last WebSocket update.\n\t */\n\tlivenessCheck?: boolean\n\t/**\n\t * Liveness check interval in milliseconds (default: 3600000 = 1 hour).\n\t * Only used when livenessCheck is enabled.\n\t */\n\tlivenessCheckInterval?: number\n\t/**\n\t * Called when a stale connection is detected (WebSocket missed updates).\n\t * Provides debug info about the connection state.\n\t */\n\tonStaleConnection?: (info: StaleConnectionInfo) => void\n\t/**\n\t * Partysocket options (passed through to ReconnectingWebSocket).\n\t * Useful options: startClosed, maxReconnectionDelay, minReconnectionDelay, etc.\n\t * @see https://github.com/partykit/partykit/tree/main/packages/partysocket\n\t */\n\twsOptions?: PartysocketOptions\n}\n\n/**\n * Robust IPNS watcher with auto-reconnect and catch-up logic.\n * Uses partysocket for reliable WebSocket reconnection.\n *\n * @example\n * ```ts\n * const watcher = new IpnsWatcher('k51qzi5uqu...', {\n * onUpdate: (update) => console.log('New CID:', update.cid?.toString()),\n * onError: (err) => console.error('Error:', err),\n * })\n *\n * // Later, to stop watching:\n * watcher.close()\n * ```\n */\nconst DEFAULT_LIVENESS_INTERVAL = 3600000 // 1 hour\n\nexport class IpnsWatcher {\n\tprivate name: string\n\tprivate nameBaseUrl: string\n\tprivate ws: ReconnectingWebSocket\n\tprivate lastKnownValue: string | null = null\n\tprivate options: IpnsWatcherOptions\n\tprivate isFirstConnect = true\n\tprivate livenessTimer: ReturnType<typeof setInterval> | null = null\n\tprivate connectedAt: Date | null = null\n\tprivate lastMessageAt: Date | null = null\n\n\tconstructor(nameBaseUrl: string, name: string, options: IpnsWatcherOptions) {\n\t\tthis.nameBaseUrl = requireNameBaseUrl(nameBaseUrl, 'IpnsWatcher')\n\t\tthis.name = name\n\t\tthis.options = options\n\n\t\tconst url = buildWsUrl(this.nameBaseUrl, name)\n\t\tDEBUG('[IpnsWatcher] creating for', name)\n\n\t\tthis.ws = new ReconnectingWebSocket(url, [], {\n\t\t\tmaxReconnectionDelay: 900000, // 15min\n\t\t\tminReconnectionDelay: 5000,\n\t\t\treconnectionDelayGrowFactor: 2,\n\t\t\tmaxRetries: Infinity,\n\t\t\t...options.wsOptions,\n\t\t})\n\n\t\tthis.ws.onopen = () => {\n\t\t\tLOG('[IpnsWatcher] connected to', name)\n\t\t\tthis.connectedAt = new Date()\n\t\t\toptions.onConnected?.()\n\n\t\t\t// Check for current state on first connect if requested\n\t\t\tif (this.isFirstConnect && (options.fetchInitialState ?? false)) {\n\t\t\t\tthis.checkForMissedUpdates()\n\t\t\t} // Check for missed updates on reconnect\n\t\t\telse if (!this.isFirstConnect && (options.catchUpOnReconnect ?? true)) {\n\t\t\t\tthis.checkForMissedUpdates()\n\t\t\t}\n\n\t\t\tthis.isFirstConnect = false\n\n\t\t\t// Start liveness checking (default: enabled)\n\t\t\tif (options.livenessCheck !== false) {\n\t\t\t\tthis.startLivenessCheck()\n\t\t\t}\n\t\t}\n\n\t\tthis.ws.onmessage = (event) => {\n\t\t\tthis.lastMessageAt = new Date()\n\t\t\ttry {\n\t\t\t\tconst record: W3NameRecord = JSON.parse(event.data as string)\n\t\t\t\tDEBUG('[IpnsWatcher] received update for', name, record)\n\n\t\t\t\tconst lastValue = this.lastKnownValue\n\t\t\t\tconst isNew = record.value !== lastValue\n\t\t\t\tconst cid = parseCidFromIpnsValue(record.value)\n\n\t\t\t\t// Skip unchanged values unless includeUnchanged is set\n\t\t\t\tif (!isNew && !options.includeUnchanged) {\n\t\t\t\t\tDEBUG('[IpnsWatcher] skipping unchanged value for', name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Update lastKnownValue after the skip check\n\t\t\t\tthis.lastKnownValue = record.value\n\n\t\t\t\tconst update: IpnsUpdate = {\n\t\t\t\t\tvalue: record.value,\n\t\t\t\t\tcid,\n\t\t\t\t\tlastValue,\n\t\t\t\t\tisNew,\n\t\t\t\t\trecord,\n\t\t\t\t}\n\n\t\t\t\tvoid options.onUpdate(update)\n\t\t\t} catch (err) {\n\t\t\t\tWARN('[IpnsWatcher] failed to parse message:', event.data, err)\n\t\t\t\toptions.onError?.(err instanceof Error ? err : new Error(String(err)))\n\t\t\t}\n\t\t}\n\n\t\tthis.ws.onerror = (event) => {\n\t\t\t// Extract meaningful error info instead of logging entire ErrorEvent\n\t\t\tconst errorMsg = event instanceof ErrorEvent ? event.message : 'WebSocket error'\n\n\t\t\t// \"Unexpected EOF\" is a normal disconnection - partysocket will auto-reconnect\n\t\t\t// Log at INFO level as it's expected behavior, not an error\n\t\t\tif (errorMsg === 'Unexpected EOF') {\n\t\t\t\tLOG('[IpnsWatcher] error for', name, ':', errorMsg, '(auto-reconnect enabled)')\n\t\t\t} else {\n\t\t\t\tWARN('[IpnsWatcher] error for', name, ':', errorMsg)\n\t\t\t}\n\n\t\t\t// Still call the error handler for unexpected errors\n\t\t\tif (errorMsg !== 'Unexpected EOF') {\n\t\t\t\toptions.onError?.(new Error(errorMsg))\n\t\t\t}\n\t\t}\n\n\t\tthis.ws.onclose = () => {\n\t\t\tDEBUG('[IpnsWatcher] disconnected from', name)\n\t\t\tthis.stopLivenessCheck()\n\t\t\tthis.connectedAt = null\n\t\t\tthis.lastMessageAt = null\n\t\t\toptions.onDisconnected?.()\n\t\t}\n\t}\n\n\t/**\n\t * Resolve current IPNS value via HTTP API to catch missed updates\n\t */\n\tprivate async checkForMissedUpdates(): Promise<void> {\n\t\ttry {\n\t\t\tDEBUG('[IpnsWatcher] checking for missed updates for', this.name)\n\t\t\tconst response = await fetch(buildHttpUrl(this.nameBaseUrl, this.name))\n\n\t\t\tif (!response.ok) {\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\tDEBUG('[IpnsWatcher] IPNS not yet published:', this.name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthrow new Error(`HTTP ${response.status}: ${response.statusText}`)\n\t\t\t}\n\n\t\t\tconst record: W3NameRecord = await response.json()\n\t\t\tconst lastValue = this.lastKnownValue\n\t\t\tconst isNew = record.value !== lastValue\n\t\t\tconst cid = parseCidFromIpnsValue(record.value)\n\n\t\t\t// Skip unchanged values unless includeUnchanged is set\n\t\t\tif (!isNew && !this.options.includeUnchanged) {\n\t\t\t\tDEBUG('[IpnsWatcher] no new updates for', this.name)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst logMsg = lastValue === null\n\t\t\t\t? '[IpnsWatcher] fetched initial state for'\n\t\t\t\t: '[IpnsWatcher] caught missed update for'\n\t\t\tLOG(logMsg, this.name, {\n\t\t\t\tprevious: lastValue,\n\t\t\t\tcurrent: record.value,\n\t\t\t})\n\n\t\t\t// Update lastKnownValue after the skip check\n\t\t\tthis.lastKnownValue = record.value\n\n\t\t\tconst update: IpnsUpdate = {\n\t\t\t\tvalue: record.value,\n\t\t\t\tcid,\n\t\t\t\tlastValue,\n\t\t\t\tisNew,\n\t\t\t\trecord,\n\t\t\t}\n\n\t\t\tvoid this.options.onUpdate(update)\n\t\t} catch (err) {\n\t\t\tWARN('[IpnsWatcher] failed to check for missed updates:', this.name, err)\n\t\t\tthis.options.onError?.(err instanceof Error ? err : new Error(String(err)))\n\t\t}\n\t}\n\n\t/**\n\t * Start periodic liveness checks to detect zombie connections.\n\t */\n\tprivate startLivenessCheck(): void {\n\t\tthis.stopLivenessCheck() // Clear any existing timer\n\t\tconst interval = this.options.livenessCheckInterval ?? DEFAULT_LIVENESS_INTERVAL\n\t\tDEBUG('[IpnsWatcher] starting liveness check for', this.name, 'interval:', interval)\n\n\t\tthis.livenessTimer = setInterval(() => {\n\t\t\tvoid this.performLivenessCheck()\n\t\t}, interval)\n\t}\n\n\t/**\n\t * Stop periodic liveness checks.\n\t */\n\tprivate stopLivenessCheck(): void {\n\t\tif (this.livenessTimer !== null) {\n\t\t\tDEBUG('[IpnsWatcher] stopping liveness check for', this.name)\n\t\t\tclearInterval(this.livenessTimer)\n\t\t\tthis.livenessTimer = null\n\t\t}\n\t}\n\n\t/**\n\t * Perform a single liveness check via HTTP.\n\t * If the HTTP value differs from lastKnownValue, the connection is stale.\n\t */\n\tprivate async performLivenessCheck(): Promise<void> {\n\t\ttry {\n\t\t\tDEBUG('[IpnsWatcher] performing liveness check for', this.name)\n\t\t\tconst response = await fetch(buildHttpUrl(this.nameBaseUrl, this.name))\n\n\t\t\tif (!response.ok) {\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\t// IPNS not published - if we also have null, that's consistent\n\t\t\t\t\tif (this.lastKnownValue === null) {\n\t\t\t\t\t\tDEBUG('[IpnsWatcher] liveness check OK (both null) for', this.name)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t// We have a value but HTTP says 404 - this shouldn't happen normally\n\t\t\t\t\tWARN('[IpnsWatcher] liveness check inconsistent (we have value, HTTP 404) for', this.name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthrow new Error(`HTTP ${response.status}: ${response.statusText}`)\n\t\t\t}\n\n\t\t\tconst record: W3NameRecord = await response.json()\n\n\t\t\t// Check if values match\n\t\t\tif (record.value === this.lastKnownValue) {\n\t\t\t\tDEBUG('[IpnsWatcher] liveness check OK for', this.name)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Stale connection detected!\n\t\t\tconst now = new Date()\n\t\t\tconst silenceDuration = this.lastMessageAt\n\t\t\t\t? now.getTime() - this.lastMessageAt.getTime()\n\t\t\t\t: this.connectedAt\n\t\t\t\t? now.getTime() - this.connectedAt.getTime()\n\t\t\t\t: 0\n\n\t\t\tconst staleInfo: StaleConnectionInfo = {\n\t\t\t\tconnectedAt: this.connectedAt ?? now,\n\t\t\t\tlastMessageAt: this.lastMessageAt,\n\t\t\t\tsilenceDuration,\n\t\t\t\tstaleValue: this.lastKnownValue,\n\t\t\t\tcurrentValue: record.value,\n\t\t\t}\n\n\t\t\tWARN('[IpnsWatcher] stale connection detected for', this.name, {\n\t\t\t\tconnectedAt: staleInfo.connectedAt.toISOString(),\n\t\t\t\tlastMessageAt: staleInfo.lastMessageAt?.toISOString() ?? 'never',\n\t\t\t\tsilenceDuration: `${Math.round(silenceDuration / 1000)}s`,\n\t\t\t\tstaleValue: staleInfo.staleValue,\n\t\t\t\tcurrentValue: staleInfo.currentValue,\n\t\t\t})\n\n\t\t\t// Notify via callback\n\t\t\tthis.options.onStaleConnection?.(staleInfo)\n\n\t\t\t// Fire immediate update with the current value\n\t\t\tconst lastValue = this.lastKnownValue\n\t\t\tconst cid = parseCidFromIpnsValue(record.value)\n\t\t\tthis.lastKnownValue = record.value\n\n\t\t\tconst update: IpnsUpdate = {\n\t\t\t\tvalue: record.value,\n\t\t\t\tcid,\n\t\t\t\tlastValue,\n\t\t\t\tisNew: true,\n\t\t\t\trecord,\n\t\t\t}\n\t\t\tvoid this.options.onUpdate(update)\n\n\t\t\t// Force reconnect to get a fresh connection\n\t\t\tLOG('[IpnsWatcher] forcing reconnect due to stale connection for', this.name)\n\t\t\tthis.ws.reconnect()\n\t\t} catch (err) {\n\t\t\t// Don't treat HTTP errors as stale - could be network issue\n\t\t\tWARN('[IpnsWatcher] liveness check failed for', this.name, err)\n\t\t}\n\t}\n\n\t/**\n\t * Manually start/reconnect the WebSocket.\n\t * Only needed if you used `wsOptions: { startClosed: true }`.\n\t */\n\tstart(): void {\n\t\tLOG('[IpnsWatcher] starting watcher for', this.name)\n\t\tthis.ws.reconnect()\n\t}\n\n\t/**\n\t * Alias for close() - for backward compatibility\n\t */\n\tstop(): void {\n\t\tthis.close()\n\t}\n\n\t/**\n\t * Close the WebSocket connection and stop watching\n\t */\n\tclose(): void {\n\t\tLOG('[IpnsWatcher] closing watcher for', this.name)\n\t\tthis.stopLivenessCheck()\n\t\tthis.ws.close()\n\t}\n\n\t/**\n\t * Get the last known IPNS value\n\t */\n\tget lastValue(): string | null {\n\t\treturn this.lastKnownValue\n\t}\n\n\t/**\n\t * Get the WebSocket ready state\n\t */\n\tget readyState(): number {\n\t\treturn this.ws.readyState\n\t}\n}\n\n/**\n * Create an IPNS watcher with auto-reconnect and catch-up logic.\n * Convenience function that creates and returns an IpnsWatcher instance.\n *\n * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)\n * @param name - The IPNS name/key to watch (e.g. \"k51qzi5u...\")\n * @param options - Callback options for handling events\n * @returns An IpnsWatcher instance with close() method\n */\nexport function watchName(nameBaseUrl: string, name: string, options: IpnsWatcherOptions): IpnsWatcher {\n\treturn new IpnsWatcher(nameBaseUrl, name, options)\n}\n\n/**\n * Watch an IPNS name and return updates as an async iterator.\n * Includes auto-reconnect - iterator continues through disconnections.\n *\n * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)\n * @param name - The IPNS name/key to watch\n * @param signal - Optional AbortSignal to stop the watch\n *\n * @example\n * ```ts\n * const controller = new AbortController()\n * for await (const update of watchNameIterator('https://name.example.com', 'k51qzi5u...', controller.signal)) {\n * console.log('Update:', update.cid?.toString())\n * }\n * ```\n */\nexport async function* watchNameIterator(\n\tnameBaseUrl: string,\n\tname: string,\n\tsignal?: AbortSignal,\n): AsyncGenerator<IpnsUpdate, void, unknown> {\n\tconst queue: IpnsUpdate[] = []\n\tlet resolve: (() => void) | null = null\n\tlet error: Error | null = null\n\n\tconst watcher = new IpnsWatcher(nameBaseUrl, name, {\n\t\tonUpdate: (update) => {\n\t\t\tqueue.push(update)\n\t\t\tresolve?.()\n\t\t},\n\t\tonError: (err) => {\n\t\t\terror = err instanceof Error ? err : new Error('WebSocket error')\n\t\t\tresolve?.()\n\t\t},\n\t})\n\n\tsignal?.addEventListener('abort', () => {\n\t\twatcher.close()\n\t})\n\n\ttry {\n\t\twhile (!signal?.aborted) {\n\t\t\tif (queue.length > 0) {\n\t\t\t\tyield queue.shift()!\n\t\t\t} else if (error) {\n\t\t\t\t// Log error but continue - partysocket will reconnect\n\t\t\t\tWARN('[watchNameIterator] error occurred, continuing:', error)\n\t\t\t\terror = null\n\t\t\t} else {\n\t\t\t\tawait new Promise<void>((r) => {\n\t\t\t\t\tresolve = r\n\t\t\t\t})\n\t\t\t\tresolve = null\n\t\t\t}\n\t\t}\n\t} finally {\n\t\twatcher.close()\n\t}\n}\n"],"mappings":"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","names":["Logger","base64pad","WARN","LOG","DEBUG","Logger","base64pad","Logger","CID","WARN","LOG","DEBUG","ERROR","resolve"]}
@@ -1 +1 @@
1
- {"version":3,"file":"snap-push.d.ts","sourceRoot":"","sources":["../../src/pubsub/snap-push.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAGtC,OAAO,KAAK,EACX,MAAM,EAEN,2BAA2B,EAC3B,gCAAgC,EAIhC,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,aAAa,EAA4C,MAAM,gBAAgB,CAAA;AAIxF,OAAO,EAAE,eAAe,EAAqB,MAAM,EAAE,MAAM,cAAc,CAAA;AAGzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAiB,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAehH,wBAAsB,sBAAsB,CAC3C,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,GAAG,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI;;;;;;GA+H1B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACxC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,gCAAgC,EACzC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,GAAG,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI;;;;;;GAiC1B;AAED,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,SAAQ;;;;;;;;GAatF;AACD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAapI;AACD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,IAAI,eAAe,CAE3G;AACD;;;GAGG;AACH,wBAAsB,0BAA0B,CAC/C,OAAO,EAAE,2BAA2B,iBAUpC"}
1
+ {"version":3,"file":"snap-push.d.ts","sourceRoot":"","sources":["../../src/pubsub/snap-push.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAItC,OAAO,KAAK,EACX,MAAM,EAEN,2BAA2B,EAC3B,gCAAgC,EAIhC,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,aAAa,EAA4C,MAAM,gBAAgB,CAAA;AAIxF,OAAO,EAAE,eAAe,EAAqB,MAAM,EAAE,MAAM,cAAc,CAAA;AAGzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAiB,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAehH,wBAAsB,sBAAsB,CAC3C,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,GAAG,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI;;;;;;GAoJ1B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACxC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,gCAAgC,EACzC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,WAAW,EAAE,GAAG,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI;;;;;;GAiC1B;AAED,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,SAAQ;;;;;;;;GAatF;AACD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAapI;AACD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,IAAI,eAAe,CAE3G;AACD;;;GAGG;AACH,wBAAsB,0BAA0B,CAC/C,OAAO,EAAE,2BAA2B,iBAUpC"}
package/dist/pubsub.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  integratePub,
4
4
  isShare,
5
5
  isSubscription
6
- } from "./chunk-H4YVJKB7.js";
6
+ } from "./chunk-ERVSWD63.js";
7
7
  import {
8
8
  chunkApplogs,
9
9
  encodeSnapshotApplogsAsCar,
@@ -11,10 +11,10 @@ import {
11
11
  isSnapBlockChunks,
12
12
  prepareSnapshotForPush,
13
13
  unchunkApplogsBlock
14
- } from "./chunk-H3JNNTVP.js";
14
+ } from "./chunk-PTZJ7LVV.js";
15
15
  import "./chunk-YDAKBU6Q.js";
16
- import "./chunk-N7SEGHU4.js";
17
- import "./chunk-4MKPGQIM.js";
16
+ import "./chunk-GQDLPZEZ.js";
17
+ import "./chunk-7VHIXHNF.js";
18
18
  import "./chunk-ZAADLBSB.js";
19
19
  export {
20
20
  agentToShortHash,
@@ -1 +1 @@
1
- {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/query/basic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/query/basic.ts"],"names":[],"mappings":"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"}
package/dist/query.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  queryDivergencesByPrev,
6
6
  resolveTimeSpec,
7
7
  serializeEpochSnapshot
8
- } from "./chunk-N5QPZNKD.js";
8
+ } from "./chunk-523IW54O.js";
9
9
  import {
10
10
  LiveQueryResult,
11
11
  QueryNode,
@@ -48,7 +48,7 @@ import {
48
48
  throwOnTimeout,
49
49
  withTimeout,
50
50
  withoutDeleted
51
- } from "./chunk-N7SEGHU4.js";
51
+ } from "./chunk-GQDLPZEZ.js";
52
52
  import {
53
53
  SubscribableArrayImpl,
54
54
  SubscribableImpl,
@@ -61,7 +61,7 @@ import {
61
61
  memoizedFn,
62
62
  prettifyThreadName,
63
63
  refCountedMemoizedFn
64
- } from "./chunk-4MKPGQIM.js";
64
+ } from "./chunk-7VHIXHNF.js";
65
65
  import "./chunk-ZAADLBSB.js";
66
66
  export {
67
67
  LiveQueryResult,
package/dist/retrieve.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  updateThreadFromSnapshot,
3
3
  withBlockCache
4
- } from "./chunk-6CSJTSQP.js";
5
- import "./chunk-H3JNNTVP.js";
4
+ } from "./chunk-OB7M55WA.js";
5
+ import "./chunk-PTZJ7LVV.js";
6
6
  import "./chunk-YDAKBU6Q.js";
7
- import "./chunk-N7SEGHU4.js";
8
- import "./chunk-4MKPGQIM.js";
7
+ import "./chunk-GQDLPZEZ.js";
8
+ import "./chunk-7VHIXHNF.js";
9
9
  import "./chunk-ZAADLBSB.js";
10
10
  export {
11
11
  updateThreadFromSnapshot,
@@ -1 +1 @@
1
- {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/thread/basic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/thread/basic.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapped.d.ts","sourceRoot":"","sources":["../../src/thread/mapped.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,EAAe,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAM7D,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAA;AAExF,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC5B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,8DAA8D;IAC9D,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAChC,gGAAgG;IAChG,OAAO,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;IAE7C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,YAAY,KAAK,UAAU,GAAG,IAAI,CAAA;CACtE;AAKD,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,KAAK,MAAM,EAAE,GAAG,eAAe,EAAE,GAAG,IAAI,CAAA;AAIlI,qBAAa,YAAa,SAAQ,MAAM;IAwBtC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAGrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS,CAAC;IA5BnB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB;IASxE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM;IAWhC,OAAO,CAAC,oBAAoB,CAAkC;gBAGpD,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EACnC,OAAO,EAAE,SAAS,MAAM,EAAE,EAClB,WAAW,EAAE,gBAAgB,GAAG,IAAI,EACpC,YAAY,GAAE,iBAAwB,EACtC,SAAS,CAAC,EAAE,OAAO;IAwBrB,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE;IAMzC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE;IAO1C,OAAO,CAAC,kBAAkB;IAe1B,8DAA8D;IAC9D,OAAO;IASP,2FAA2F;IAC3F,UAAU,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE;IAOxC,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU;IAO/E,sDAAsD;IACtD,YAAY;IASZ,SAAS,CAAC,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW;IA0DjE,IAAI,QAAQ,YAEX;CACD"}
1
+ {"version":3,"file":"mapped.d.ts","sourceRoot":"","sources":["../../src/thread/mapped.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAGlE,OAAO,EAAe,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAY7D,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAA;AAExF,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC5B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,8DAA8D;IAC9D,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAChC,gGAAgG;IAChG,OAAO,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;IAE7C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,YAAY,KAAK,UAAU,GAAG,IAAI,CAAA;CACtE;AAKD,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,KAAK,MAAM,EAAE,GAAG,eAAe,EAAE,GAAG,IAAI,CAAA;AAIlI,qBAAa,YAAa,SAAQ,MAAM;IAwBtC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAGrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS,CAAC;IA5BnB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB;IASxE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM;IAWhC,OAAO,CAAC,oBAAoB,CAAkC;gBAGpD,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EACnC,OAAO,EAAE,SAAS,MAAM,EAAE,EAClB,WAAW,EAAE,gBAAgB,GAAG,IAAI,EACpC,YAAY,GAAE,iBAAwB,EACtC,SAAS,CAAC,EAAE,OAAO;IAwBrB,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE;IAMzC,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE;IAO1C,OAAO,CAAC,kBAAkB;IAe1B,8DAA8D;IAC9D,OAAO;IASP,2FAA2F;IAC3F,UAAU,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE;IAOxC,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU;IAO/E,sDAAsD;IACtD,YAAY;IASZ,SAAS,CAAC,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW;IA2DjE,IAAI,QAAQ,YAEX;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/thread/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAElC,OAAO,EAAE,oBAAoB,EAAsC,MAAM,2BAA2B,CAAA;AACpG,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAY,MAAM,0BAA0B,CAAA;AACvF,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,UAEzC;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,eAE1C;AAcD,wBAAgB,cAAc,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,SAAM,EACV,oBAAoB,0CAAuB,gBA4B3C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,eAAe,EAAE,EAChC,IAAI,EAAE;IACL,wBAAwB,CAAC,EAAE,OAAO,oBAAoB,CAAA;IACtD,YAAY,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS,CAAA;CAClE,gBAyCD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,sCAEvC;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACrC,SAAS,SAAS,MAAM,EAAE,EAC1B,SAAS,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,KACxD,MAAM,EAcR,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/thread/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAElC,OAAO,EAAkB,oBAAoB,EAAsC,MAAM,2BAA2B,CAAA;AACpH,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAY,MAAM,0BAA0B,CAAA;AACvF,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,UAEzC;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,eAE1C;AAcD,wBAAgB,cAAc,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,SAAM,EACV,oBAAoB,0CAAuB,gBA4B3C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,eAAe,EAAE,EAChC,IAAI,EAAE;IACL,wBAAwB,CAAC,EAAE,OAAO,oBAAoB,CAAA;IACtD,YAAY,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS,CAAA;CAClE,gBAyCD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,sCAEvC;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACrC,SAAS,SAAS,MAAM,EAAE,EAC1B,SAAS,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,KACxD,MAAM,EAcR,CAAA"}
package/dist/thread.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  rollingFilter,
27
27
  rollingMapper,
28
28
  simpleApplogMapper
29
- } from "./chunk-4MKPGQIM.js";
29
+ } from "./chunk-7VHIXHNF.js";
30
30
  import "./chunk-ZAADLBSB.js";
31
31
  export {
32
32
  MappedThread,
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  lastWriteWins,
15
15
  liveEntityAt
16
- } from "../chunk-N7SEGHU4.js";
16
+ } from "../chunk-GQDLPZEZ.js";
17
17
  import {
18
18
  EntityID_LENGTH,
19
19
  SubscribableImpl,
@@ -22,7 +22,7 @@ import {
22
22
  isInitEvent,
23
23
  mintNewEntity,
24
24
  rollingFilter
25
- } from "../chunk-4MKPGQIM.js";
25
+ } from "../chunk-7VHIXHNF.js";
26
26
  import "../chunk-ZAADLBSB.js";
27
27
 
28
28
  // src/viewmodel/builder.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wovin/core",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -5,7 +5,9 @@ import { isEqual } from 'lodash-es'
5
5
  import stringify from 'safe-stable-stringify'
6
6
  import type {
7
7
  Applog,
8
+ ApplogEnc,
8
9
  ApplogForInsert,
10
+ ApplogOfSomeSort,
9
11
  ApplogValue,
10
12
  DatalogQueryPattern,
11
13
  DatalogQueryResultEntry,
@@ -13,9 +15,39 @@ import type {
13
15
  SearchContext,
14
16
  ValueOrMatcher,
15
17
  } from './datom-types.ts'
18
+ import { isEncryptedApplog } from './datom-types.ts'
16
19
 
17
20
  const { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line no-unused-vars
18
21
 
22
+ /**
23
+ * One-line, bounded summary of a single applog — enough to trace it in logs
24
+ * (`en/at=vl@ts#cid`) without dumping the full object (and, for arrays, the whole thread).
25
+ * Handles encrypted applogs and falsy entries so it's safe on error paths.
26
+ */
27
+ export const applogSummary = (log: ApplogOfSomeSort | null | undefined): string => {
28
+ if (!log) return '∅'
29
+ const a = log as Partial<Applog> & Partial<ApplogEnc>
30
+ const cid = a.cid ? `#${String(a.cid).slice(-6)}` : ''
31
+ if (isEncryptedApplog(log)) return `enc[${log.enc.length}B]${cid}`
32
+ const vl = a.vl === undefined ? '∅' : JSON.stringify(a.vl) ?? String(a.vl)
33
+ const vlStr = vl.length > 32 ? `${vl.slice(0, 32)}…` : vl
34
+ return `${a.en}/${a.at}=${vlStr}${a.ts ? `@${a.ts}` : ''}${cid}`
35
+ }
36
+
37
+ /**
38
+ * Bounded summary of an applog array: `[count] first, few, summaries …+N`.
39
+ * Keeps enough identity to debug (which logs, how many) while preventing log explosion.
40
+ */
41
+ export const applogsSummary = (
42
+ logs: readonly (ApplogOfSomeSort | null | undefined)[] | null | undefined,
43
+ sample = 3,
44
+ ): string => {
45
+ if (!logs) return '∅'
46
+ if (!logs.length) return '[0]'
47
+ const shown = logs.slice(0, sample).map(applogSummary).join(', ')
48
+ return `[${logs.length}] ${shown}${logs.length > sample ? ` …+${logs.length - sample}` : ''}`
49
+ }
50
+
19
51
  export const isoDateStrCompare = (strA: string, strB: string, dir: 'asc' | 'desc' = 'asc') =>
20
52
  dir === 'asc'
21
53
  ? strA.localeCompare(strB, 'en-US')
@@ -159,7 +191,7 @@ function topoSortByPv(logs: Applog[], dir: 'asc' | 'desc'): Applog[] {
159
191
  visited.add(log.cid)
160
192
  result.push(log)
161
193
  const children = childrenByPv.get(log.cid)
162
- if (children) for (let i = children.length - 1; i >= 0; i--) stack.push(children[i])
194
+ if (children) { for (let i = children.length - 1; i >= 0; i--) stack.push(children[i]) }
163
195
  }
164
196
  // Defensive: cycle (shouldn't happen with content-addressed pv) — append unvisited
165
197
  if (result.length < logs.length) {
@@ -0,0 +1,72 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { generateKeyPair } from '@libp2p/crypto/keys'
3
+ import { CID } from 'multiformats/cid'
4
+ import { publishIPNSRecord, unmarshalIPNSRecord, type IPNSPublishTarget } from './ipns-record.ts'
5
+
6
+ const CID_A = CID.parse('bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi')
7
+
8
+ async function freshKeyBytes(): Promise<Uint8Array> {
9
+ const key = await generateKeyPair('Ed25519')
10
+ return key.raw
11
+ }
12
+
13
+ /**
14
+ * The storage proxy relays Kubo's error verbatim, and Go's JSON encoder
15
+ * HTML-escapes `>` to `>` — so the conflict string that reaches
16
+ * `publishIPNSRecord` reads `... sequence N >= new record sequence M ...`
17
+ * rather than using a literal `>=`. This is the exact wire form we must match.
18
+ */
19
+ function seqConflictError(existing: number, attempted: number): string {
20
+ return (
21
+ `Kubo RPC IPNS put failed (500 Internal Server Error): ` +
22
+ `{"Message":"existing IPNS record has sequence ${existing} ` +
23
+ `\\u003e= new record sequence ${attempted}, use 'ipfs name put --force' ` +
24
+ `to skip this check","Code":0,"Type":"error"}`
25
+ )
26
+ }
27
+
28
+ describe('publishIPNSRecord sequence-coherence retry', () => {
29
+ it('bumps past an escaped (\\u003e=) Kubo sequence conflict and succeeds', async () => {
30
+ const privateKey = await freshKeyBytes()
31
+ const publishedSequences: bigint[] = []
32
+
33
+ // Server is already at sequence 406, but resolveSequence undershoots
34
+ // (reports 405, e.g. due to a race / stale read), so the first publish
35
+ // attempts 406 and is rejected. The retry must parse the escaped error,
36
+ // bump to 407, and succeed.
37
+ const target: IPNSPublishTarget = {
38
+ name: 'fake-kubo',
39
+ resolveSequence: async () => 405n,
40
+ publish: async (_ipnsName, recordBytes) => {
41
+ const { sequence } = unmarshalIPNSRecord(recordBytes)
42
+ publishedSequences.push(sequence)
43
+ if (sequence <= 406n) {
44
+ throw new Error(seqConflictError(406, Number(sequence)))
45
+ }
46
+ },
47
+ }
48
+
49
+ const signed = await publishIPNSRecord(privateKey, CID_A, [target])
50
+
51
+ expect(publishedSequences).toEqual([406n, 407n])
52
+ expect(signed.sequence).toBe(407n)
53
+ })
54
+
55
+ it('surfaces a non-conflict failure without retrying', async () => {
56
+ const privateKey = await freshKeyBytes()
57
+ let attempts = 0
58
+ const target: IPNSPublishTarget = {
59
+ name: 'fake-kubo',
60
+ resolveSequence: async () => null,
61
+ publish: async () => {
62
+ attempts++
63
+ throw new Error('boom: unrelated network error')
64
+ },
65
+ }
66
+
67
+ await expect(publishIPNSRecord(privateKey, CID_A, [target])).rejects.toThrow(
68
+ /All IPNS publish targets failed/,
69
+ )
70
+ expect(attempts).toBe(1)
71
+ })
72
+ })