@wovin/core 0.2.2 → 0.3.2

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 (112) hide show
  1. package/dist/applog/applog-utils.d.ts +25 -1
  2. package/dist/applog/applog-utils.d.ts.map +1 -1
  3. package/dist/applog/datom-types.d.ts.map +1 -1
  4. package/dist/applog.js +5 -3
  5. package/dist/blockstore.js +2 -0
  6. package/dist/blockstore.js.map +1 -1
  7. package/dist/{chunk-SHUHRHOT.js → chunk-4MKPGQIM.js} +17 -18
  8. package/dist/chunk-4MKPGQIM.js.map +1 -0
  9. package/dist/chunk-64EJIJAJ.js +17 -0
  10. package/dist/chunk-64EJIJAJ.js.map +1 -0
  11. package/dist/{chunk-HUIQ54TT.js → chunk-6CSJTSQP.js} +3 -3
  12. package/dist/chunk-7QEGHKR4.js +17 -0
  13. package/dist/chunk-7QEGHKR4.js.map +1 -0
  14. package/dist/{chunk-BLF5MAWU.js → chunk-BIYQEX3N.js} +2 -2
  15. package/dist/{chunk-6ALNRM3J.js → chunk-H3JNNTVP.js} +21 -8
  16. package/dist/chunk-H3JNNTVP.js.map +1 -0
  17. package/dist/{chunk-OC6Z6CQW.js → chunk-H4YVJKB7.js} +2 -2
  18. package/dist/chunk-ICBK7NC4.js +27 -0
  19. package/dist/chunk-ICBK7NC4.js.map +1 -0
  20. package/dist/chunk-N5QPZNKD.js +288 -0
  21. package/dist/chunk-N5QPZNKD.js.map +1 -0
  22. package/dist/{chunk-3SUFNJEZ.js → chunk-N7SEGHU4.js} +7 -2
  23. package/dist/{chunk-3SUFNJEZ.js.map → chunk-N7SEGHU4.js.map} +1 -1
  24. package/dist/chunk-XF4DWOAE.js +25 -0
  25. package/dist/chunk-XF4DWOAE.js.map +1 -0
  26. package/dist/index.js +20 -10
  27. package/dist/ipfs/car.d.ts.map +1 -1
  28. package/dist/ipfs.js +4 -4
  29. package/dist/ipns/gateway-resolver.d.ts +21 -0
  30. package/dist/ipns/gateway-resolver.d.ts.map +1 -0
  31. package/dist/ipns/ipns-record.d.ts +46 -7
  32. package/dist/ipns/ipns-record.d.ts.map +1 -1
  33. package/dist/ipns/ipns-w3name.d.ts +45 -0
  34. package/dist/ipns/ipns-w3name.d.ts.map +1 -0
  35. package/dist/ipns/ipns-watcher.d.ts +190 -0
  36. package/dist/ipns/ipns-watcher.d.ts.map +1 -0
  37. package/dist/ipns.d.ts +3 -0
  38. package/dist/ipns.d.ts.map +1 -1
  39. package/dist/ipns.js +591 -14
  40. package/dist/ipns.js.map +1 -1
  41. package/dist/pubsub/snap-push.d.ts +2 -2
  42. package/dist/pubsub/snap-push.d.ts.map +1 -1
  43. package/dist/pubsub.js +4 -4
  44. package/dist/query/epoch-snapshot.d.ts +205 -0
  45. package/dist/query/epoch-snapshot.d.ts.map +1 -0
  46. package/dist/query.d.ts +1 -0
  47. package/dist/query.d.ts.map +1 -1
  48. package/dist/query.js +12 -4
  49. package/dist/retrieve.js +4 -4
  50. package/dist/thread.js +1 -1
  51. package/dist/viewmodel/adapters/arktype.d.ts +33 -0
  52. package/dist/viewmodel/adapters/arktype.d.ts.map +1 -0
  53. package/dist/viewmodel/adapters/arktype.js +7 -0
  54. package/dist/viewmodel/adapters/arktype.js.map +1 -0
  55. package/dist/viewmodel/adapters/typebox.d.ts +35 -0
  56. package/dist/viewmodel/adapters/typebox.d.ts.map +1 -0
  57. package/dist/viewmodel/adapters/typebox.js +7 -0
  58. package/dist/viewmodel/adapters/typebox.js.map +1 -0
  59. package/dist/viewmodel/adapters/typia.d.ts +40 -0
  60. package/dist/viewmodel/adapters/typia.d.ts.map +1 -0
  61. package/dist/viewmodel/adapters/typia.js +7 -0
  62. package/dist/viewmodel/adapters/typia.js.map +1 -0
  63. package/dist/viewmodel/adapters/zod.d.ts +30 -0
  64. package/dist/viewmodel/adapters/zod.d.ts.map +1 -0
  65. package/dist/viewmodel/adapters/zod.js +7 -0
  66. package/dist/viewmodel/adapters/zod.js.map +1 -0
  67. package/dist/viewmodel/builder.d.ts +40 -0
  68. package/dist/viewmodel/builder.d.ts.map +1 -0
  69. package/dist/viewmodel/examples/all-adapters.d.ts +26 -0
  70. package/dist/viewmodel/examples/all-adapters.d.ts.map +1 -0
  71. package/dist/viewmodel/factory.d.ts +38 -0
  72. package/dist/viewmodel/factory.d.ts.map +1 -0
  73. package/dist/viewmodel/index.d.ts +10 -0
  74. package/dist/viewmodel/index.d.ts.map +1 -0
  75. package/dist/viewmodel/index.js +313 -0
  76. package/dist/viewmodel/index.js.map +1 -0
  77. package/dist/viewmodel/schema-adapter.d.ts +16 -0
  78. package/dist/viewmodel/schema-adapter.d.ts.map +1 -0
  79. package/dist/viewmodel/types.d.ts +97 -0
  80. package/dist/viewmodel/types.d.ts.map +1 -0
  81. package/package.json +29 -3
  82. package/src/applog/applog-utils.test.ts +43 -1
  83. package/src/applog/applog-utils.ts +38 -21
  84. package/src/applog/datom-types.ts +2 -2
  85. package/src/applog/object-values.test.ts +9 -9
  86. package/src/ipfs/car.ts +14 -2
  87. package/src/ipns/gateway-resolver.ts +63 -0
  88. package/src/ipns/ipns-record.ts +158 -29
  89. package/src/ipns/ipns-w3name.ts +207 -0
  90. package/src/ipns/ipns-watcher.ts +608 -0
  91. package/src/ipns.ts +3 -0
  92. package/src/pubsub/snap-push.ts +6 -5
  93. package/src/query/epoch-snapshot.test.ts +594 -0
  94. package/src/query/epoch-snapshot.ts +392 -0
  95. package/src/query.ts +1 -0
  96. package/src/viewmodel/adapters/arktype.ts +44 -0
  97. package/src/viewmodel/adapters/typebox.ts +59 -0
  98. package/src/viewmodel/adapters/typia.ts +50 -0
  99. package/src/viewmodel/adapters/zod.ts +55 -0
  100. package/src/viewmodel/builder.ts +71 -0
  101. package/src/viewmodel/examples/all-adapters.ts +206 -0
  102. package/src/viewmodel/factory.ts +330 -0
  103. package/src/viewmodel/index.ts +22 -0
  104. package/src/viewmodel/schema-adapter.ts +27 -0
  105. package/src/viewmodel/types.ts +152 -0
  106. package/dist/chunk-22WDFLXO.js +0 -138
  107. package/dist/chunk-22WDFLXO.js.map +0 -1
  108. package/dist/chunk-6ALNRM3J.js.map +0 -1
  109. package/dist/chunk-SHUHRHOT.js.map +0 -1
  110. /package/dist/{chunk-HUIQ54TT.js.map → chunk-6CSJTSQP.js.map} +0 -0
  111. /package/dist/{chunk-BLF5MAWU.js.map → chunk-BIYQEX3N.js.map} +0 -0
  112. /package/dist/{chunk-OC6Z6CQW.js.map → chunk-H4YVJKB7.js.map} +0 -0
package/dist/ipfs.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  fetchSnapshotChainUntil
3
- } from "./chunk-BLF5MAWU.js";
3
+ } from "./chunk-BIYQEX3N.js";
4
4
  import {
5
5
  carFromBlob,
6
6
  collectDagBlocks,
@@ -11,9 +11,9 @@ import {
11
11
  makeCarBlob,
12
12
  makeCarOut,
13
13
  streamReaderToIterable
14
- } from "./chunk-6ALNRM3J.js";
14
+ } from "./chunk-H3JNNTVP.js";
15
15
  import "./chunk-YDAKBU6Q.js";
16
- import "./chunk-3SUFNJEZ.js";
16
+ import "./chunk-N7SEGHU4.js";
17
17
  import {
18
18
  MULTICODEC_IPNS_KEY,
19
19
  areCidsEqual,
@@ -29,7 +29,7 @@ import {
29
29
  prepareForPub,
30
30
  toIpnsString,
31
31
  tryParseCID
32
- } from "./chunk-SHUHRHOT.js";
32
+ } from "./chunk-4MKPGQIM.js";
33
33
  import "./chunk-ZAADLBSB.js";
34
34
  export {
35
35
  MULTICODEC_IPNS_KEY,
@@ -0,0 +1,21 @@
1
+ import { CID } from 'multiformats/cid';
2
+ /**
3
+ * Resolve an IPNS name to a CID using a public IPFS gateway's HTTP HEAD response.
4
+ *
5
+ * Mechanism: per the IPFS HTTP Gateway spec, `HEAD <gateway>/ipns/<name>/` returns the
6
+ * IPNS-resolved root CID in the `X-Ipfs-Roots` response header (space-separated, ordered
7
+ * from root to leaf). The first entry is the IPNS-resolved CID.
8
+ *
9
+ * This works against any gateway that follows the spec and exposes CORS for HEAD
10
+ * (most public gateways do, e.g. ipfs.zt.ax, ipfs.io, dweb.link).
11
+ *
12
+ * The legacy w3name HTTP endpoint (`GET <base>/name/<ipns>` returning `{value: "/ipfs/<cid>"}`)
13
+ * is also supported here for back-compat with self-hosted w3name-like services — but the
14
+ * X-Ipfs-Roots path is preferred since it's the standardised gateway mechanism.
15
+ *
16
+ * @param ipns - The IPNS name (k51... string)
17
+ * @param gateways - List of gateway base URLs (e.g. `["https://ipfs.zt.ax"]`)
18
+ * @returns The resolved CID, or null if no gateway could resolve the name
19
+ */
20
+ export declare function resolveIPNSViaGateway(ipns: string, gateways: string[]): Promise<CID | null>;
21
+ //# sourceMappingURL=gateway-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-resolver.d.ts","sourceRoot":"","sources":["../../src/ipns/gateway-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAKtC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAuCjG"}
@@ -14,21 +14,60 @@ export declare function ipnsNameFromPrivateKey(privKeyBytes: Uint8Array): string
14
14
  */
15
15
  export declare function createSignedIPNSRecord(privateKey: Uint8Array, cid: CID, sequence: bigint, lifetimeMs?: number): Promise<SignedIPNSRecord>;
16
16
  export { unmarshalIPNSRecord };
17
- /** A target that can receive a signed IPNS record */
17
+ /**
18
+ * A target that can receive a signed IPNS record, advertise its current
19
+ * sequence, or both.
20
+ *
21
+ * - `publish` is called by `publishIPNSRecord` to actually store the record
22
+ * on the target's backing service. Targets without `publish` are skipped
23
+ * during the fan-out (e.g. a sequence-only source).
24
+ * - `resolveSequence` is consulted by `publishIPNSRecord` to compute the
25
+ * next IPNS sequence. The first target to return a value (including
26
+ * `null` for "never published") wins. Throw to indicate a transient
27
+ * error — the caller will try the next target.
28
+ *
29
+ * Most real targets (e.g. a storage connector) provide both. A simple
30
+ * "track sequence in localStorage" target only needs `resolveSequence`.
31
+ */
18
32
  export interface IPNSPublishTarget {
19
33
  name: string;
20
- publish(ipnsName: string, recordBytes: Uint8Array): Promise<void>;
34
+ publish?(ipnsName: string, recordBytes: Uint8Array): Promise<void>;
35
+ resolveSequence?(ipnsName: string): Promise<bigint | null>;
21
36
  }
22
37
  /**
23
- * Resolve current IPNS sequence number from a naming service.
38
+ * Resolve the current IPNS sequence from a generic naming service.
24
39
  * Returns null if the name was never published (404).
25
- * Throws on network/server errors.
40
+ * Throws on network/server errors so the caller can try a different target.
26
41
  */
27
42
  export declare function resolveIPNSSequence(nameServiceUrl: string, ipnsName: string): Promise<bigint | null>;
43
+ /**
44
+ * Options for {@link publishIPNSRecord}.
45
+ */
46
+ export interface PublishIPNSRecordOptions {
47
+ /**
48
+ * Max number of times to bump the sequence on "existing >= new" conflict.
49
+ * Defaults to 3. Each bump re-signs the record with a higher sequence
50
+ * and retries all targets.
51
+ */
52
+ maxSequenceBumps?: number;
53
+ }
28
54
  /**
29
55
  * Create a signed IPNS record and publish to all configured targets.
30
- * Resolves sequence from sequenceServiceUrl, creates record once, fans out.
31
- * Throws if ALL targets fail; warns on partial failure.
56
+ *
57
+ * Sequence resolution: walks `targets` in order asking each one with a
58
+ * `resolveSequence` method. The first target to successfully return a value
59
+ * (including `null` for "never published") determines the next sequence.
60
+ * If every target throws or none supports `resolveSequence`, falls back to 0n.
61
+ *
62
+ * Publish fan-out: only targets with a `publish` method are called.
63
+ * Throws if every publish-capable target fails; partial failures are logged.
64
+ *
65
+ * **Sequence-coherence retry:** if a publish target rejects with the Kubo
66
+ * "existing IPNS record has sequence X >= new record sequence Y" error,
67
+ * the function parses `X`, bumps the sequence to `max(X + 1n, Y + 1n)`,
68
+ * re-signs the record, and retries (up to `maxSequenceBumps` times).
69
+ * This is the "increment and clobber" mechanism that recovers from
70
+ * sequence drift without requiring server-side `--force` support.
32
71
  */
33
- export declare function publishIPNSRecord(privateKey: Uint8Array, cid: CID, targets: IPNSPublishTarget[], sequenceServiceUrl?: string): Promise<SignedIPNSRecord>;
72
+ export declare function publishIPNSRecord(privateKey: Uint8Array, cid: CID, targets: IPNSPublishTarget[], options?: PublishIPNSRecordOptions): Promise<SignedIPNSRecord>;
34
73
  //# sourceMappingURL=ipns-record.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ipns-record.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,mBAAmB,EAAE,MAAM,MAAM,CAAA;AAI/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,UAAU,GAAG,MAAM,CAGvE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC3C,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,UAAU,SAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACjE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACxC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0BxB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,iBAAiB,EAAE,EAC5B,kBAAkB,SAA8B,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAuB3B"}
1
+ {"version":3,"file":"ipns-record.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,mBAAmB,EAAE,MAAM,MAAM,CAAA;AAI/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,UAAU,GAAG,MAAM,CAGvE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC3C,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,UAAU,SAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA;AAE9B;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,eAAe,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC1D;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACxC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2BxB;AAKD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,iBAAiB,EAAE,EAC5B,OAAO,CAAC,EAAE,wBAAwB,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAkF3B"}
@@ -0,0 +1,45 @@
1
+ import type { IPNSPublishTarget } from '@wovin/core/ipns';
2
+ import { CID } from 'multiformats/cid';
3
+ import * as W3Name from 'w3name';
4
+ /**
5
+ * Publish CID to IPNS, automatically handling increment vs v0.
6
+ * Returns the revision for further processing (e.g., Kubo integration).
7
+ */
8
+ export declare function publishIPNS(ipnsPrivateKey: Uint8Array, cid: CID): Promise<W3Name.Revision>;
9
+ /**
10
+ * Resolve the current IPNS sequence from a zt.ax-compatible naming service.
11
+ *
12
+ * The naming service API uses the simple W3NameRecord format:
13
+ * `GET <baseUrl>/<ipnsName>` → `{ value: "/ipfs/<cid>", seq?: number, validity?: string }`
14
+ *
15
+ * Also supports the legacy w3name record format (`{ record: "<base64>", value: "..." }`)
16
+ * for backward compatibility with hybrid services.
17
+ */
18
+ export declare function resolveZtaxSequence(baseUrl: string, ipnsName: string): Promise<bigint | null>;
19
+ /**
20
+ * Create an IPNSPublishTarget that publishes to a zt.ax naming service.
21
+ *
22
+ * Uses HTTP POST to publish signed IPNS records and HTTP GET to resolve
23
+ * the current sequence number, following the same wire format as the
24
+ * standard w3name API but at a configurable base URL.
25
+ *
26
+ * The naming service is expected to support:
27
+ * - `POST <baseUrl>/<ipnsName>` — publish signed IPNS record (base64-encoded body)
28
+ * - `GET <baseUrl>/<ipnsName>` — resolve current record (`{ value, seq?, record? }`)
29
+ *
30
+ * @param baseUrl - Base URL of the naming service (default: https://ipfs.zt.ax)
31
+ */
32
+ export declare function ztaxTarget(baseUrl?: string): IPNSPublishTarget;
33
+ /**
34
+ * Create an IPNSPublishTarget for the w3name service.
35
+ *
36
+ * @deprecated w3name is shut down for publishing. This target is kept as a
37
+ * read‑only backup for sequence resolution only (no publish method).
38
+ * Use {@link ztaxTarget} for all publishing.
39
+ *
40
+ * @param serviceUrl - Base URL of the w3name-compatible service (default: https://name.web3.storage)
41
+ */
42
+ export declare function w3nameTarget(serviceUrl?: string): IPNSPublishTarget;
43
+ export declare function generateIpnsKey(): Promise<W3Name.WritableName>;
44
+ export declare function getW3NamePublic(pk: Uint8Array): Promise<string>;
45
+ //# sourceMappingURL=ipns-w3name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipns-w3name.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-w3name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAIzD,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAwChC;;;GAGG;AACH,wBAAsB,WAAW,CAAC,cAAc,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAMhG;AA6BD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmCxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,OAAO,SAAuB,GAAG,iBAAiB,CA0B5E;AAMD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,UAAU,SAA8B,GAAG,iBAAiB,CAQxF;AAID,wBAAsB,eAAe,iCAEpC;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,UAAU,mBAGnD"}
@@ -0,0 +1,190 @@
1
+ import { CID } from 'multiformats/cid';
2
+ import { type Options as PartysocketOptions } from 'partysocket/ws';
3
+ export type { PartysocketOptions };
4
+ export interface W3NameRecord {
5
+ value: string;
6
+ seq?: number;
7
+ validity?: string;
8
+ }
9
+ /**
10
+ * Debug info provided when a stale WebSocket connection is detected.
11
+ */
12
+ export interface StaleConnectionInfo {
13
+ /** When the WebSocket connection was established */
14
+ connectedAt: Date;
15
+ /** When we last received a WebSocket message */
16
+ lastMessageAt: Date | null;
17
+ /** How long since last message (ms) */
18
+ silenceDuration: number;
19
+ /** The stale value from WebSocket */
20
+ staleValue: string | null;
21
+ /** The current value from HTTP */
22
+ currentValue: string;
23
+ }
24
+ /**
25
+ * Enriched IPNS update with parsed CID and change detection.
26
+ * Backwards compatible - `.value` still works as before.
27
+ */
28
+ export interface IpnsUpdate {
29
+ /** Raw IPNS value string (e.g. '/ipfs/bafy...') — same as W3NameRecord.value */
30
+ value: string;
31
+ /** Parsed CID if value is valid IPFS path, null otherwise */
32
+ cid: CID | null;
33
+ /** Previous value (null on first update) */
34
+ lastValue: string | null;
35
+ /** Whether this is a change from lastValue */
36
+ isNew: boolean;
37
+ /** Original W3NameRecord for access to seq/validity */
38
+ record: W3NameRecord;
39
+ }
40
+ export interface WatchRawOptions {
41
+ /** Called when the IPNS record is updated */
42
+ onUpdate: (record: W3NameRecord) => void;
43
+ /** Called when an error occurs */
44
+ onError?: (error: Event | Error) => void;
45
+ /** Called when the connection is opened */
46
+ onOpen?: () => void;
47
+ /** Called when the connection is closed */
48
+ onClose?: (event: CloseEvent) => void;
49
+ }
50
+ export interface WatchRawSubscription {
51
+ /** Close the WebSocket connection */
52
+ close: () => void;
53
+ /** The underlying WebSocket instance */
54
+ ws: WebSocket;
55
+ }
56
+ /**
57
+ * Low-level WebSocket watcher for IPNS (no reconnect logic).
58
+ * Use this when you want full control over connection lifecycle.
59
+ * For most cases, prefer `watchName` or `IpnsWatcher` which handle reconnection.
60
+ *
61
+ * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)
62
+ * @param name - The IPNS name/key to watch
63
+ * @param options - Callback options
64
+ * @returns Subscription with close() and ws
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const sub = watchNameRaw('https://name.example.com', 'k51qzi5u...', {
69
+ * onUpdate: (record) => console.log('Update:', record.value),
70
+ * onClose: () => console.log('Disconnected - handle reconnect yourself'),
71
+ * })
72
+ * ```
73
+ */
74
+ export declare function watchNameRaw(nameBaseUrl: string, name: string, options: WatchRawOptions): WatchRawSubscription;
75
+ export interface IpnsWatcherOptions {
76
+ /** Called when the IPNS record is updated (enriched payload with CID and change detection) */
77
+ onUpdate: (update: IpnsUpdate) => void | Promise<void>;
78
+ /** Called when an error occurs */
79
+ onError?: (error: Error | Event) => void;
80
+ /** Called when the connection is opened/reconnected */
81
+ onConnected?: () => void;
82
+ /** Called when the connection is closed */
83
+ onDisconnected?: () => void;
84
+ /** Fetch current IPNS state on first connect (default: false) */
85
+ fetchInitialState?: boolean;
86
+ /** Fetch current IPNS state on reconnect to catch missed updates (default: true) */
87
+ catchUpOnReconnect?: boolean;
88
+ /** If true, call onUpdate even when value hasn't changed (default: false) */
89
+ includeUnchanged?: boolean;
90
+ /**
91
+ * Enable periodic liveness checks via HTTP to detect zombie connections (default: true).
92
+ * When enabled, periodically fetches current IPNS value and forces reconnect if it
93
+ * differs from the last WebSocket update.
94
+ */
95
+ livenessCheck?: boolean;
96
+ /**
97
+ * Liveness check interval in milliseconds (default: 3600000 = 1 hour).
98
+ * Only used when livenessCheck is enabled.
99
+ */
100
+ livenessCheckInterval?: number;
101
+ /**
102
+ * Called when a stale connection is detected (WebSocket missed updates).
103
+ * Provides debug info about the connection state.
104
+ */
105
+ onStaleConnection?: (info: StaleConnectionInfo) => void;
106
+ /**
107
+ * Partysocket options (passed through to ReconnectingWebSocket).
108
+ * Useful options: startClosed, maxReconnectionDelay, minReconnectionDelay, etc.
109
+ * @see https://github.com/partykit/partykit/tree/main/packages/partysocket
110
+ */
111
+ wsOptions?: PartysocketOptions;
112
+ }
113
+ export declare class IpnsWatcher {
114
+ private name;
115
+ private nameBaseUrl;
116
+ private ws;
117
+ private lastKnownValue;
118
+ private options;
119
+ private isFirstConnect;
120
+ private livenessTimer;
121
+ private connectedAt;
122
+ private lastMessageAt;
123
+ constructor(nameBaseUrl: string, name: string, options: IpnsWatcherOptions);
124
+ /**
125
+ * Resolve current IPNS value via HTTP API to catch missed updates
126
+ */
127
+ private checkForMissedUpdates;
128
+ /**
129
+ * Start periodic liveness checks to detect zombie connections.
130
+ */
131
+ private startLivenessCheck;
132
+ /**
133
+ * Stop periodic liveness checks.
134
+ */
135
+ private stopLivenessCheck;
136
+ /**
137
+ * Perform a single liveness check via HTTP.
138
+ * If the HTTP value differs from lastKnownValue, the connection is stale.
139
+ */
140
+ private performLivenessCheck;
141
+ /**
142
+ * Manually start/reconnect the WebSocket.
143
+ * Only needed if you used `wsOptions: { startClosed: true }`.
144
+ */
145
+ start(): void;
146
+ /**
147
+ * Alias for close() - for backward compatibility
148
+ */
149
+ stop(): void;
150
+ /**
151
+ * Close the WebSocket connection and stop watching
152
+ */
153
+ close(): void;
154
+ /**
155
+ * Get the last known IPNS value
156
+ */
157
+ get lastValue(): string | null;
158
+ /**
159
+ * Get the WebSocket ready state
160
+ */
161
+ get readyState(): number;
162
+ }
163
+ /**
164
+ * Create an IPNS watcher with auto-reconnect and catch-up logic.
165
+ * Convenience function that creates and returns an IpnsWatcher instance.
166
+ *
167
+ * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)
168
+ * @param name - The IPNS name/key to watch (e.g. "k51qzi5u...")
169
+ * @param options - Callback options for handling events
170
+ * @returns An IpnsWatcher instance with close() method
171
+ */
172
+ export declare function watchName(nameBaseUrl: string, name: string, options: IpnsWatcherOptions): IpnsWatcher;
173
+ /**
174
+ * Watch an IPNS name and return updates as an async iterator.
175
+ * Includes auto-reconnect - iterator continues through disconnections.
176
+ *
177
+ * @param nameBaseUrl - Base URL of a naming service that supports `/name/<ipns>/watch` (WebSocket) and `/name/<ipns>` (HTTP)
178
+ * @param name - The IPNS name/key to watch
179
+ * @param signal - Optional AbortSignal to stop the watch
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * const controller = new AbortController()
184
+ * for await (const update of watchNameIterator('https://name.example.com', 'k51qzi5u...', controller.signal)) {
185
+ * console.log('Update:', update.cid?.toString())
186
+ * }
187
+ * ```
188
+ */
189
+ export declare function watchNameIterator(nameBaseUrl: string, name: string, signal?: AbortSignal): AsyncGenerator<IpnsUpdate, void, unknown>;
190
+ //# sourceMappingURL=ipns-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipns-watcher.d.ts","sourceRoot":"","sources":["../../src/ipns/ipns-watcher.ts"],"names":[],"mappings":"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"}
package/dist/ipns.d.ts CHANGED
@@ -1,2 +1,5 @@
1
+ export * from './ipns/gateway-resolver.ts';
1
2
  export * from './ipns/ipns-record.ts';
3
+ export * from './ipns/ipns-w3name.ts';
4
+ export * from './ipns/ipns-watcher.ts';
2
5
  //# sourceMappingURL=ipns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ipns.d.ts","sourceRoot":"","sources":["../src/ipns.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"ipns.d.ts","sourceRoot":"","sources":["../src/ipns.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA"}