@pkcprotocol/pkc-js 0.0.73 → 0.0.75

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 (151) hide show
  1. package/README.md +25 -1
  2. package/dist/browser/clients/base-client-manager.d.ts +1 -0
  3. package/dist/browser/clients/base-client-manager.js +9 -2
  4. package/dist/browser/clients/base-client-manager.js.map +1 -1
  5. package/dist/browser/clients/rpc-client/rpc-schema-util.d.ts +1 -0
  6. package/dist/browser/clients/rpc-client/schema.d.ts +1 -0
  7. package/dist/browser/community/community-client-manager.d.ts +1 -0
  8. package/dist/browser/community/community-client-manager.js +7 -0
  9. package/dist/browser/community/community-client-manager.js.map +1 -1
  10. package/dist/browser/community/remote-community.js +18 -9
  11. package/dist/browser/community/remote-community.js.map +1 -1
  12. package/dist/browser/community/schema.d.ts +6 -0
  13. package/dist/browser/community/schema.js +4 -1
  14. package/dist/browser/community/schema.js.map +1 -1
  15. package/dist/browser/community/types.d.ts +1 -0
  16. package/dist/browser/errors.d.ts +2 -0
  17. package/dist/browser/errors.js +2 -0
  18. package/dist/browser/errors.js.map +1 -1
  19. package/dist/browser/generated-version.d.ts +1 -1
  20. package/dist/browser/generated-version.js +1 -1
  21. package/dist/browser/helia/helia-for-pkc.d.ts +1 -1
  22. package/dist/browser/helia/helia-for-pkc.js +41 -5
  23. package/dist/browser/helia/helia-for-pkc.js.map +1 -1
  24. package/dist/browser/helia/lru-blockstore.d.ts +92 -0
  25. package/dist/browser/helia/lru-blockstore.js +224 -0
  26. package/dist/browser/helia/lru-blockstore.js.map +1 -0
  27. package/dist/browser/pkc/pkc.js +4 -1
  28. package/dist/browser/pkc/pkc.js.map +1 -1
  29. package/dist/browser/pkc-error.d.ts +1 -1
  30. package/dist/browser/publications/community-edit/schema.d.ts +4 -0
  31. package/dist/browser/publications/publication.d.ts +2 -1
  32. package/dist/browser/publications/publication.js +63 -24
  33. package/dist/browser/publications/publication.js.map +1 -1
  34. package/dist/browser/pubsub-messages/schema.d.ts +2 -0
  35. package/dist/browser/rpc/src/schema.d.ts +16 -0
  36. package/dist/browser/runtime/browser/blockstore.d.ts +25 -0
  37. package/dist/browser/runtime/browser/blockstore.js +40 -0
  38. package/dist/browser/runtime/browser/blockstore.js.map +1 -0
  39. package/dist/browser/runtime/node/blockstore.d.ts +32 -0
  40. package/dist/browser/runtime/node/blockstore.js +42 -0
  41. package/dist/browser/runtime/node/blockstore.js.map +1 -0
  42. package/dist/browser/runtime/node/community/db-handler.d.ts +1 -0
  43. package/dist/browser/runtime/node/community/local-community/challenges.js +26 -25
  44. package/dist/browser/runtime/node/community/local-community/challenges.js.map +1 -1
  45. package/dist/browser/runtime/node/community/local-community/comment-updates.d.ts +2 -1
  46. package/dist/browser/runtime/node/community/local-community/comment-updates.js +14 -2
  47. package/dist/browser/runtime/node/community/local-community/comment-updates.js.map +1 -1
  48. package/dist/browser/runtime/node/community/local-community/db-state.js +12 -1
  49. package/dist/browser/runtime/node/community/local-community/db-state.js.map +1 -1
  50. package/dist/browser/runtime/node/community/local-community/ipns-publishing.js +22 -1
  51. package/dist/browser/runtime/node/community/local-community/ipns-publishing.js.map +1 -1
  52. package/dist/browser/runtime/node/community/local-community/lifecycle.js +17 -5
  53. package/dist/browser/runtime/node/community/local-community/lifecycle.js.map +1 -1
  54. package/dist/browser/runtime/node/community/local-community/pubsub.js +42 -4
  55. package/dist/browser/runtime/node/community/local-community/pubsub.js.map +1 -1
  56. package/dist/browser/runtime/node/community/local-community.d.ts +1 -0
  57. package/dist/browser/runtime/node/community/local-community.js +10 -1
  58. package/dist/browser/runtime/node/community/local-community.js.map +1 -1
  59. package/dist/browser/schema/schema-util.d.ts +4 -0
  60. package/dist/browser/schema.d.ts +20 -0
  61. package/dist/browser/schema.js +11 -1
  62. package/dist/browser/schema.js.map +1 -1
  63. package/dist/browser/signer/signatures.d.ts +4 -4
  64. package/dist/browser/signer/signatures.js +23 -4
  65. package/dist/browser/signer/signatures.js.map +1 -1
  66. package/dist/browser/test/test-util.d.ts +3 -0
  67. package/dist/browser/test/test-util.js +15 -1
  68. package/dist/browser/test/test-util.js.map +1 -1
  69. package/dist/bundled/bundle-manifest.json +201 -94
  70. package/dist/bundled/chunks/helia-for-pkc-BPj1zAUb.js +6915 -0
  71. package/dist/bundled/chunks/{local-community-EFv2VpQI.js → local-community-ChTkd8lH.js} +1 -1
  72. package/dist/bundled/chunks/{local-community-DLVCXKMM.js → local-community-D4efR9XJ.js} +92 -55
  73. package/dist/bundled/chunks/{node-Dpuw7iSW.js → node-BK6GBM0d.js} +55 -28
  74. package/dist/bundled/chunks/{rpc-local-community-8CqOzaX3.js → rpc-local-community-O94vseOA.js} +45 -34
  75. package/dist/bundled/chunks/{schema-DMHTAMSM.js → schema-wNdSno5O.js} +11 -4
  76. package/dist/bundled/chunks/{src-o_MYSn-E.js → src-B2CwDTfy.js} +2 -142
  77. package/dist/bundled/chunks/{src-4u0f92eE.js → src-BKg5Lhod.js} +2 -127
  78. package/dist/bundled/chunks/src-Cpx2Sts8.js +127 -0
  79. package/dist/bundled/chunks/src-DKntVmyX.js +142 -0
  80. package/dist/bundled/chunks/{util-hdyyy-HI.js → util-iNnH2bP5.js} +1 -1
  81. package/dist/bundled/index.js +1 -1
  82. package/dist/bundled/rpc/src/index.js +4 -4
  83. package/dist/node/clients/base-client-manager.d.ts +1 -0
  84. package/dist/node/clients/base-client-manager.js +9 -2
  85. package/dist/node/clients/base-client-manager.js.map +1 -1
  86. package/dist/node/clients/rpc-client/rpc-schema-util.d.ts +1 -0
  87. package/dist/node/clients/rpc-client/schema.d.ts +1 -0
  88. package/dist/node/community/community-client-manager.d.ts +1 -0
  89. package/dist/node/community/community-client-manager.js +7 -0
  90. package/dist/node/community/community-client-manager.js.map +1 -1
  91. package/dist/node/community/remote-community.js +18 -9
  92. package/dist/node/community/remote-community.js.map +1 -1
  93. package/dist/node/community/schema.d.ts +6 -0
  94. package/dist/node/community/schema.js +4 -1
  95. package/dist/node/community/schema.js.map +1 -1
  96. package/dist/node/community/types.d.ts +1 -0
  97. package/dist/node/errors.d.ts +2 -0
  98. package/dist/node/errors.js +2 -0
  99. package/dist/node/errors.js.map +1 -1
  100. package/dist/node/generated-version.d.ts +1 -1
  101. package/dist/node/generated-version.js +1 -1
  102. package/dist/node/helia/helia-for-pkc.d.ts +1 -1
  103. package/dist/node/helia/helia-for-pkc.js +41 -5
  104. package/dist/node/helia/helia-for-pkc.js.map +1 -1
  105. package/dist/node/helia/lru-blockstore.d.ts +92 -0
  106. package/dist/node/helia/lru-blockstore.js +224 -0
  107. package/dist/node/helia/lru-blockstore.js.map +1 -0
  108. package/dist/node/pkc/pkc.js +4 -1
  109. package/dist/node/pkc/pkc.js.map +1 -1
  110. package/dist/node/pkc-error.d.ts +1 -1
  111. package/dist/node/publications/community-edit/schema.d.ts +4 -0
  112. package/dist/node/publications/publication.d.ts +2 -1
  113. package/dist/node/publications/publication.js +63 -24
  114. package/dist/node/publications/publication.js.map +1 -1
  115. package/dist/node/pubsub-messages/schema.d.ts +2 -0
  116. package/dist/node/rpc/src/schema.d.ts +16 -0
  117. package/dist/node/runtime/browser/blockstore.d.ts +25 -0
  118. package/dist/node/runtime/browser/blockstore.js +40 -0
  119. package/dist/node/runtime/browser/blockstore.js.map +1 -0
  120. package/dist/node/runtime/node/blockstore.d.ts +32 -0
  121. package/dist/node/runtime/node/blockstore.js +42 -0
  122. package/dist/node/runtime/node/blockstore.js.map +1 -0
  123. package/dist/node/runtime/node/community/db-handler.d.ts +1 -0
  124. package/dist/node/runtime/node/community/local-community/challenges.js +26 -25
  125. package/dist/node/runtime/node/community/local-community/challenges.js.map +1 -1
  126. package/dist/node/runtime/node/community/local-community/comment-updates.d.ts +2 -1
  127. package/dist/node/runtime/node/community/local-community/comment-updates.js +14 -2
  128. package/dist/node/runtime/node/community/local-community/comment-updates.js.map +1 -1
  129. package/dist/node/runtime/node/community/local-community/db-state.js +12 -1
  130. package/dist/node/runtime/node/community/local-community/db-state.js.map +1 -1
  131. package/dist/node/runtime/node/community/local-community/ipns-publishing.js +22 -1
  132. package/dist/node/runtime/node/community/local-community/ipns-publishing.js.map +1 -1
  133. package/dist/node/runtime/node/community/local-community/lifecycle.js +17 -5
  134. package/dist/node/runtime/node/community/local-community/lifecycle.js.map +1 -1
  135. package/dist/node/runtime/node/community/local-community/pubsub.js +42 -4
  136. package/dist/node/runtime/node/community/local-community/pubsub.js.map +1 -1
  137. package/dist/node/runtime/node/community/local-community.d.ts +1 -0
  138. package/dist/node/runtime/node/community/local-community.js +10 -1
  139. package/dist/node/runtime/node/community/local-community.js.map +1 -1
  140. package/dist/node/schema/schema-util.d.ts +4 -0
  141. package/dist/node/schema.d.ts +20 -0
  142. package/dist/node/schema.js +11 -1
  143. package/dist/node/schema.js.map +1 -1
  144. package/dist/node/signer/signatures.d.ts +4 -4
  145. package/dist/node/signer/signatures.js +23 -4
  146. package/dist/node/signer/signatures.js.map +1 -1
  147. package/dist/node/test/test-util.d.ts +3 -0
  148. package/dist/node/test/test-util.js +15 -1
  149. package/dist/node/test/test-util.js.map +1 -1
  150. package/package.json +8 -5
  151. package/dist/bundled/chunks/helia-for-pkc-DooZDxJi.js +0 -495
@@ -1,495 +0,0 @@
1
- import { L as hideClassPrivateProps, R as ipnsNameToIpnsOverPubsubTopic, _r as PKCError, yr as logger_default } from "./schema-DMHTAMSM.js";
2
- import { a as fetchBlockWithStalledSessionFailover, i as directFetchIpnsRecordFromProviders, n as cacheIpnsRecordInPubsubLocalStore, o as getHeliaDebugContext, r as connectToPubsubPeers, s as selectBitswapSessionSeedPeers } from "./util-hdyyy-HI.js";
3
- import { CID } from "multiformats/cid";
4
- import { peerIdFromString } from "@libp2p/peer-id";
5
- import { EventEmitter as EventEmitter$1 } from "events";
6
- import { createHelia, libp2pDefaults } from "helia";
7
- import { ipns } from "@helia/ipns";
8
- import { multihashToIPNSRoutingKey, unmarshalIPNSRecord } from "ipns";
9
- import { ipnsValidator } from "ipns/validator";
10
- import { gossipsub } from "@libp2p/gossipsub";
11
- import { identify } from "@libp2p/identify";
12
- import { bitswap } from "@helia/block-brokers";
13
- import { MemoryBlockstore } from "blockstore-core";
14
- import { delegatedRoutingV1HttpApiClientContentRouting } from "@helia/delegated-routing-v1-http-api-client";
15
- import { NotFoundError } from "@libp2p/interface";
16
- import { unixfs } from "@helia/unixfs";
17
- import { fetch } from "@libp2p/fetch";
18
- import { pubsub } from "@helia/ipns/routing";
19
- //#region dist/node/runtime/node/libp2p-extra-transports.js
20
- const extraLibp2pTransports = [];
21
- //#endregion
22
- //#region dist/node/helia/libp2pjsClient.js
23
- var Libp2pJsClient = class {
24
- /**
25
- * The running Helia node backing this libp2p-js client — the public, semver-covered way for
26
- * consumers that share the node (e.g. @bitsocial/pubsub-voting, bitsocial-seeder) to reach it,
27
- * instead of the private `_helia` field (issue #221).
28
- *
29
- * The returned node is guaranteed to carry, in addition to Helia's own surface:
30
- * - `libp2p.services.pubsub` — the gossipsub service registered at node construction
31
- * - `libp2p.services.fetch` — the `@libp2p/fetch` service registered at node construction
32
- * - `blockstore` — the node's block storage (bitswap-backed retrieval)
33
- * - `libp2p.contentRouting` — the delegated-routing aggregation over `httpRoutersOptions`
34
- *
35
- * A breaking change to what this accessor returns is a breaking pkc-js release.
36
- */
37
- get heliaNode() {
38
- return this._helia;
39
- }
40
- constructor(libp2pJsClientOptions) {
41
- this._helia = libp2pJsClientOptions.helia;
42
- this._heliaUnixfs = libp2pJsClientOptions.heliaUnixfs;
43
- this._heliaIpnsRouter = libp2pJsClientOptions.heliaIpnsRouter;
44
- this.heliaWithKuboRpcClientFunctions = libp2pJsClientOptions.heliaWithKuboRpcClientFunctions;
45
- this._libp2pJsClientsOptions = libp2pJsClientOptions.libp2pJsClientsOptions;
46
- this._mergedHeliaOptions = libp2pJsClientOptions.mergedHeliaOptions;
47
- this.key = libp2pJsClientOptions.key;
48
- this.countOfUsesOfInstance = libp2pJsClientOptions.countOfUsesOfInstance;
49
- hideClassPrivateProps(this);
50
- }
51
- };
52
- //#endregion
53
- //#region dist/node/helia/dial-transport-filter.js
54
- const DENIED_DIAL_TRANSPORTS_BY_DEFAULT = [
55
- "webrtc",
56
- "webrtc-direct",
57
- "webtransport"
58
- ];
59
- function multiaddrUsesDeniedTransport(multiaddr) {
60
- const componentNames = multiaddr.getComponents().map((component) => component.name);
61
- return DENIED_DIAL_TRANSPORTS_BY_DEFAULT.some((deniedProto) => componentNames.includes(deniedProto));
62
- }
63
- function createDefaultDialTransportGater() {
64
- return { denyDialMultiaddr: (multiaddr) => multiaddrUsesDeniedTransport(multiaddr) };
65
- }
66
- //#endregion
67
- //#region dist/node/helia/helia-for-pkc.js
68
- const log = logger_default("pkc-js:libp2p-js");
69
- const libp2pJsClients = {};
70
- const creatingLibp2pJsClients = {};
71
- const DELEGATED_ROUTING_CONCURRENT_REQUESTS = 32;
72
- function getDelegatedRoutingFields(routers) {
73
- const routersObj = {};
74
- for (let i = 0; i < routers.length; i++) {
75
- const factory = delegatedRoutingV1HttpApiClientContentRouting({
76
- url: routers[i],
77
- concurrentRequests: DELEGATED_ROUTING_CONCURRENT_REQUESTS
78
- });
79
- routersObj["delegatedRouting" + i] = (components) => {
80
- const routing = factory(components);
81
- routing.get = async () => {
82
- throw new NotFoundError("pkc HTTP routers do not serve IPNS records");
83
- };
84
- routing.put = async () => {};
85
- const routerUrl = routers[i];
86
- const originalFindProviders = routing.findProviders.bind(routing);
87
- routing.findProviders = async function* (cid, options) {
88
- try {
89
- yield* originalFindProviders(cid, options);
90
- } catch (e) {
91
- log.trace("Content router", routerUrl, "errored during findProviders; treating it as returning no providers", e);
92
- }
93
- };
94
- return routing;
95
- };
96
- }
97
- return routersObj;
98
- }
99
- async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
100
- if (!pkcOptions.httpRoutersOptions?.length) throw Error("You need to have pkc.httpRouterOptions to set up helia");
101
- const existingClient = libp2pJsClients[pkcOptions.key];
102
- if (existingClient) {
103
- existingClient.countOfUsesOfInstance++;
104
- return existingClient;
105
- }
106
- const creatingClientPromise = creatingLibp2pJsClients[pkcOptions.key];
107
- if (creatingClientPromise) {
108
- const client = await creatingClientPromise;
109
- client.countOfUsesOfInstance++;
110
- return client;
111
- }
112
- creatingLibp2pJsClients[pkcOptions.key] = (async () => {
113
- const mergedHeliaInit = {
114
- libp2p: {
115
- addresses: { listen: [] },
116
- peerDiscovery: void 0,
117
- transports: [...libp2pDefaults().transports ?? [], ...extraLibp2pTransports],
118
- connectionMonitor: { abortConnectionOnPingFailure: false },
119
- connectionGater: createDefaultDialTransportGater(),
120
- ...pkcOptions.libp2pOptions,
121
- services: {
122
- identify: identify(),
123
- pubsub: gossipsub(),
124
- fetch: fetch(),
125
- ...getDelegatedRoutingFields(pkcOptions.httpRoutersOptions),
126
- ...pkcOptions.libp2pOptions?.services
127
- }
128
- },
129
- blockstore: new MemoryBlockstore(),
130
- blockBrokers: [bitswap()],
131
- start: false,
132
- ...pkcOptions.heliaOptions
133
- };
134
- const helia = await createHelia(mergedHeliaInit);
135
- helia.routing.routers = helia.routing.routers.filter((r) => r.constructor.name !== "HTTPGatewayRouter");
136
- log("Initialized libp2pjs helia with key", pkcOptions.key, "peer id", helia.libp2p.peerId.toString());
137
- const pubsubEventHandler = new EventEmitter$1();
138
- helia.libp2p.services.pubsub.addEventListener("message", (evt) => {
139
- log.trace(`Event from helia libp2p pubsub: on pubsub topic (string, e.g. community address) ${evt.detail.topic}`);
140
- const msgFormatted = {
141
- data: evt.detail.data,
142
- topic: evt.detail.topic,
143
- type: evt.detail.type
144
- };
145
- pubsubEventHandler.emit(evt.detail.topic, msgFormatted);
146
- });
147
- const heliaFs = unixfs(helia);
148
- const asHeliaCatCid = (ipfsPathOrCid) => {
149
- CID.parse(ipfsPathOrCid.split("/")[0]);
150
- return ipfsPathOrCid;
151
- };
152
- const MAX_BITSWAP_SESSION_SEED_PEERS = 3;
153
- const getBitswapSessionSeedPeers = (scopeIpnsPubsubTopic) => {
154
- const pubsub = helia.libp2p.services.pubsub;
155
- return selectBitswapSessionSeedPeers({
156
- connectedPeers: helia.libp2p.getPeers(),
157
- scopedPubsubSubscriberPeerIdStrings: scopeIpnsPubsubTopic ? pubsub.getSubscribers(scopeIpnsPubsubTopic).map(String) : [],
158
- pubsubSubscriberPeerIdStrings: pubsub.getTopics().flatMap((topic) => pubsub.getSubscribers(topic).map(String)),
159
- maxSeeds: MAX_BITSWAP_SESSION_SEED_PEERS
160
- });
161
- };
162
- const KUBO_DURATION_UNIT_TO_MS = {
163
- ns: 1e-6,
164
- us: .001,
165
- µs: .001,
166
- ms: 1,
167
- s: 1e3,
168
- m: 6e4,
169
- h: 36e5
170
- };
171
- const parseKuboStyleTimeoutMs = (timeout) => {
172
- if (timeout === void 0 || timeout === null) return void 0;
173
- if (typeof timeout === "number" && Number.isFinite(timeout) && timeout > 0) return timeout;
174
- if (typeof timeout === "string") {
175
- let totalMs = 0;
176
- let matchedLength = 0;
177
- for (const component of timeout.matchAll(/(\d+(?:\.\d+)?)(ns|us|µs|ms|s|m|h)/g)) {
178
- totalMs += parseFloat(component[1]) * KUBO_DURATION_UNIT_TO_MS[component[2]];
179
- matchedLength += component[0].length;
180
- }
181
- if (matchedLength === timeout.length && totalMs > 0) return totalMs;
182
- }
183
- throw new PKCError("ERR_INVALID_KUBO_STYLE_TIMEOUT", { invalidTimeout: timeout });
184
- };
185
- const SESSION_NO_PROVIDERS_RETRY_BASE_DELAY_MS = 500;
186
- const isCausedByInsufficientProviders = (error) => {
187
- if (!(error instanceof Error)) return false;
188
- if (error.name === "InsufficientProvidersError") return true;
189
- if (error instanceof AggregateError && error.errors.some(isCausedByInsufficientProviders)) return true;
190
- return isCausedByInsufficientProviders(error.cause);
191
- };
192
- const delayAbortable = (ms, signal) => new Promise((resolve) => {
193
- if (signal.aborted) return resolve();
194
- const onAbort = () => {
195
- clearTimeout(timer);
196
- resolve();
197
- };
198
- const timer = setTimeout(() => {
199
- signal.removeEventListener("abort", onAbort);
200
- resolve();
201
- }, ms);
202
- signal.addEventListener("abort", onAbort, { once: true });
203
- });
204
- const ipnsPubsubRouter = pubsub(helia);
205
- const ipnsPubsubLocalStore = ipnsPubsubRouter.localStore;
206
- const ipnsNameResolver = ipns(helia, { routers: [ipnsPubsubRouter] });
207
- ipnsNameResolver.routers = ipnsNameResolver.routers.filter((r) => r?.constructor?.name !== "LocalStoreRouting");
208
- const WARMUP_MAX_PEERS = 4;
209
- const warmupPromisesByTopic = /* @__PURE__ */ new Map();
210
- const warmupForTopic = (topic, options) => {
211
- if (helia.libp2p.services.pubsub.getSubscribers(topic).length > 0) return Promise.resolve();
212
- const existing = warmupPromisesByTopic.get(topic);
213
- if (existing) return existing;
214
- const p = connectToPubsubPeers({
215
- helia,
216
- pubsubTopic: topic,
217
- maxPeers: WARMUP_MAX_PEERS,
218
- options,
219
- log: logger_default("pkc-js:helia:pubsub:warmup")
220
- }).then(() => void 0).finally(() => {
221
- warmupPromisesByTopic.delete(topic);
222
- });
223
- warmupPromisesByTopic.set(topic, p);
224
- return p;
225
- };
226
- const throwIfHeliaIsStoppingOrStopped = () => {
227
- if (helia.libp2p.status === "stopped" || helia.libp2p.status === "stopping") throw new PKCError("ERR_HELIAS_STOPPING_OR_STOPPED", {
228
- heliaKey: pkcOptions.key,
229
- helia,
230
- ...getHeliaDebugContext(helia)
231
- });
232
- };
233
- const heliaWithKuboRpcClientShape = {
234
- name: { resolve: (ipnsName, options) => {
235
- throwIfHeliaIsStoppingOrStopped();
236
- async function* generator() {
237
- const currentName = typeof ipnsName === "string" ? ipnsName : ipnsName.toString();
238
- const ipnsNameAsPeerId = peerIdFromString(currentName);
239
- log.trace("Resolving ipns name", currentName, "with options", options);
240
- const ipnsPubsubTopic = ipnsNameToIpnsOverPubsubTopic(ipnsNameAsPeerId.toString());
241
- const routingKey = multihashToIPNSRoutingKey(ipnsNameAsPeerId.toMultihash());
242
- let directFetchOutcome = { attempted: false };
243
- {
244
- if (!helia.libp2p.services.pubsub.getTopics().includes(ipnsPubsubTopic)) helia.libp2p.services.pubsub.subscribe(ipnsPubsubTopic);
245
- warmupForTopic(ipnsPubsubTopic, options).catch((e) => log.trace("Fire-and-forget warmup failed for", ipnsPubsubTopic, e));
246
- const directStart = Date.now();
247
- try {
248
- const direct = await directFetchIpnsRecordFromProviders({
249
- helia,
250
- pubsubTopic: ipnsPubsubTopic,
251
- routingKey,
252
- maxPeers: WARMUP_MAX_PEERS,
253
- validate: ipnsValidator,
254
- options,
255
- log: logger_default("pkc-js:helia:ipns:direct-fetch")
256
- });
257
- if (direct) {
258
- directFetchOutcome = {
259
- attempted: true,
260
- hit: true,
261
- durationMs: direct.durationMs,
262
- source: direct.source,
263
- peerId: direct.peerId
264
- };
265
- const record = unmarshalIPNSRecord(direct.recordBytes);
266
- try {
267
- await cacheIpnsRecordInPubsubLocalStore({
268
- localStore: ipnsPubsubLocalStore,
269
- routingKey,
270
- marshalledRecord: direct.recordBytes
271
- });
272
- } catch (cacheErr) {
273
- log.trace("Failed to cache direct-fetched IPNS record at the pubsub routing layer for", ipnsPubsubTopic, cacheErr);
274
- }
275
- yield record.value;
276
- return;
277
- }
278
- directFetchOutcome = {
279
- attempted: true,
280
- hit: false,
281
- durationMs: Date.now() - directStart
282
- };
283
- } catch (directErr) {
284
- if (options?.signal?.aborted) throw directErr;
285
- directFetchOutcome = {
286
- attempted: true,
287
- hit: false,
288
- durationMs: Date.now() - directStart,
289
- error: directErr
290
- };
291
- log.trace("Direct IPNS fetch path errored for", ipnsPubsubTopic, directErr);
292
- }
293
- }
294
- let warmupOutcome = { attempted: false };
295
- if (helia.libp2p.services.pubsub.getSubscribers(ipnsPubsubTopic).length === 0) {
296
- const warmupStart = Date.now();
297
- try {
298
- await warmupForTopic(ipnsPubsubTopic, options);
299
- warmupOutcome = {
300
- attempted: true,
301
- durationMs: Date.now() - warmupStart,
302
- subscribersAfterWarmup: helia.libp2p.services.pubsub.getSubscribers(ipnsPubsubTopic).length
303
- };
304
- } catch (warmupErr) {
305
- warmupOutcome = {
306
- attempted: true,
307
- durationMs: Date.now() - warmupStart,
308
- error: warmupErr
309
- };
310
- log.error("Pre-resolve peer warmup failed for", ipnsPubsubTopic, warmupErr);
311
- }
312
- }
313
- let recordBytes;
314
- const routerErrors = [];
315
- for (const router of ipnsNameResolver.routers) try {
316
- const got = await router.get(routingKey, {
317
- ...options,
318
- validate: false
319
- });
320
- if (got) {
321
- recordBytes = got;
322
- break;
323
- }
324
- } catch (err) {
325
- routerErrors.push(err);
326
- }
327
- if (!recordBytes) throw new PKCError("ERR_RESOLVED_IPNS_P2P_TO_UNDEFINED", {
328
- ipnsName,
329
- currentName,
330
- ipnsPubsubTopic,
331
- ipnsResolveOptions: options,
332
- directFetchOutcome,
333
- warmupOutcome,
334
- routerErrors,
335
- subscribersAtResolveTime: helia.libp2p.services.pubsub.getSubscribers(ipnsPubsubTopic).length,
336
- httpRouters: pkcOptions.httpRoutersOptions,
337
- ...getHeliaDebugContext(helia)
338
- });
339
- await ipnsValidator(routingKey, recordBytes);
340
- yield unmarshalIPNSRecord(recordBytes).value;
341
- }
342
- return generator();
343
- } },
344
- cat(ipfsPath, options) {
345
- throwIfHeliaIsStoppingOrStopped();
346
- const rootCid = CID.parse(ipfsPath.split("/")[0]);
347
- const timeoutMs = parseKuboStyleTimeoutMs(options?.timeout);
348
- const { bitswapSessionSeedScopeIpnsPubsubTopic, ...unixfsCatOptions } = options ?? {};
349
- return (async function* () {
350
- const controller = new AbortController();
351
- const callerSignal = options?.signal;
352
- const abortFromCallerSignal = () => controller.abort(callerSignal?.reason);
353
- if (callerSignal?.aborted) abortFromCallerSignal();
354
- else callerSignal?.addEventListener("abort", abortFromCallerSignal, { once: true });
355
- const timeoutTimer = timeoutMs !== void 0 ? setTimeout(() => controller.abort(new PKCError("ERR_FETCH_CID_P2P_TIMEOUT", {
356
- ipfsPath,
357
- timeoutMs
358
- })), timeoutMs) : void 0;
359
- try {
360
- for (let attempt = 0;; attempt++) {
361
- const session = helia.blockstore.createSession(rootCid, { providers: getBitswapSessionSeedPeers(bitswapSessionSeedScopeIpnsPubsubTopic) });
362
- const sessionGet = session.get.bind(session);
363
- const fallbackGet = helia.blockstore.get.bind(helia.blockstore);
364
- session.get = (blockCid, blockGetOptions) => fetchBlockWithStalledSessionFailover({
365
- cid: blockCid,
366
- sessionGet,
367
- fallbackGet,
368
- stallTimeoutMs: heliaWithKuboRpcClientShape._bitswapSessionStalledGetFailoverMs ?? 2500,
369
- options: blockGetOptions,
370
- log
371
- });
372
- let yieldedAnyBytes = false;
373
- try {
374
- const catIterable = unixfs({ blockstore: session }).cat(asHeliaCatCid(ipfsPath), {
375
- ...unixfsCatOptions,
376
- signal: controller.signal
377
- });
378
- for await (const chunk of catIterable) {
379
- yieldedAnyBytes = true;
380
- yield chunk;
381
- }
382
- return;
383
- } catch (catError) {
384
- if (controller.signal.aborted) throw controller.signal.reason instanceof Error ? controller.signal.reason : catError;
385
- if (yieldedAnyBytes || !isCausedByInsufficientProviders(catError)) throw catError;
386
- log.trace("Bitswap session found no providers for", ipfsPath, "- retrying, attempt", attempt + 1);
387
- } finally {
388
- session.close();
389
- }
390
- await delayAbortable(Math.min(SESSION_NO_PROVIDERS_RETRY_BASE_DELAY_MS * 2 ** attempt, 8e3), controller.signal);
391
- if (controller.signal.aborted) {
392
- if (controller.signal.reason instanceof Error) throw controller.signal.reason;
393
- throw new PKCError("ERR_FETCH_CID_P2P_TIMEOUT", {
394
- ipfsPath,
395
- timeoutMs
396
- });
397
- }
398
- }
399
- } finally {
400
- if (timeoutTimer !== void 0) clearTimeout(timeoutTimer);
401
- callerSignal?.removeEventListener("abort", abortFromCallerSignal);
402
- }
403
- })();
404
- },
405
- pubsub: {
406
- ls: async () => helia.libp2p.services.pubsub.getTopics(),
407
- peers: async (topic, options) => helia.libp2p.services.pubsub.getSubscribers(topic),
408
- publish: async (topic, data, options) => {
409
- throwIfHeliaIsStoppingOrStopped();
410
- const wasAlreadySubscribed = helia.libp2p.services.pubsub.getTopics().includes(topic);
411
- if (!wasAlreadySubscribed) helia.libp2p.services.pubsub.subscribe(topic);
412
- try {
413
- await warmupForTopic(topic, options);
414
- log("Published new data to pubsub topic (string, e.g. community address)", topic, "Direct gossipsub recipients (libp2p peer IDs, NOT signer/community addresses):", (await helia.libp2p.services.pubsub.publish(topic, data)).recipients.map((p) => p.toString()));
415
- } finally {
416
- if (!wasAlreadySubscribed) helia.libp2p.services.pubsub.unsubscribe(topic);
417
- }
418
- },
419
- subscribe: async (topic, handler, options) => {
420
- throwIfHeliaIsStoppingOrStopped();
421
- pubsubEventHandler.on(topic, handler);
422
- const warmupPromise = warmupForTopic(topic, options);
423
- helia.libp2p.services.pubsub.subscribe(topic);
424
- await warmupPromise;
425
- },
426
- unsubscribe: async (topic, handler, options) => {
427
- throwIfHeliaIsStoppingOrStopped();
428
- pubsubEventHandler.removeListener(topic, handler);
429
- if (pubsubEventHandler.listenerCount(topic) === 0) helia.libp2p.services.pubsub.unsubscribe(topic);
430
- }
431
- },
432
- async add(entry, options) {
433
- throw Error("Helia 'add' is not supported at the moment in pkc-js API");
434
- },
435
- async stop(options) {
436
- const clientFromMap = libp2pJsClients[pkcOptions.key];
437
- if (!clientFromMap) return;
438
- if (clientFromMap.countOfUsesOfInstance <= 0) return;
439
- clientFromMap.countOfUsesOfInstance--;
440
- if (clientFromMap.countOfUsesOfInstance === 0) {
441
- delete libp2pJsClients[pkcOptions.key];
442
- for (const router of ipnsNameResolver.routers) {
443
- const lifecycle = router;
444
- if (typeof lifecycle.stop === "function") try {
445
- await lifecycle.stop();
446
- } catch (e) {
447
- log.error("Error stopping IPNS router", router?.constructor?.name, e);
448
- }
449
- }
450
- for (const topic of helia.libp2p.services.pubsub.getTopics()) helia.libp2p.services.pubsub.unsubscribe(topic);
451
- for (const connection of helia.libp2p.getConnections()) try {
452
- connection.abort(/* @__PURE__ */ new Error("pkc-js libp2p instance is stopping"));
453
- } catch (e) {
454
- log.error("Error aborting libp2p connection during stop", e);
455
- }
456
- try {
457
- await helia.stop();
458
- } catch (e) {
459
- log.error("Error stopping helia", e);
460
- }
461
- log("Helia/libp2p-js stopped with key", pkcOptions.key, "and peer id", helia.libp2p.peerId.toString());
462
- }
463
- }
464
- };
465
- const originalSubscribe = helia.libp2p.services.pubsub.subscribe.bind(helia.libp2p.services.pubsub);
466
- helia.libp2p.services.pubsub.subscribe = (topic) => {
467
- throwIfHeliaIsStoppingOrStopped();
468
- warmupForTopic(topic).catch((err) => log.error("warmup failed for topic", topic, err));
469
- originalSubscribe(topic);
470
- };
471
- const client = new Libp2pJsClient({
472
- helia,
473
- heliaWithKuboRpcClientFunctions: heliaWithKuboRpcClientShape,
474
- heliaUnixfs: heliaFs,
475
- heliaIpnsRouter: ipnsNameResolver,
476
- mergedHeliaOptions: mergedHeliaInit,
477
- countOfUsesOfInstance: 1,
478
- libp2pJsClientsOptions: pkcOptions,
479
- key: pkcOptions.key
480
- });
481
- await helia.start();
482
- log("Helia/libp2p-js started with key", pkcOptions.key, "and peer id", helia.libp2p.peerId.toString());
483
- libp2pJsClients[pkcOptions.key] = client;
484
- return client;
485
- })();
486
- const createdClientPromise = creatingLibp2pJsClients[pkcOptions.key];
487
- if (!createdClientPromise) throw new Error("Missing creation promise after initialization");
488
- try {
489
- return await createdClientPromise;
490
- } finally {
491
- delete creatingLibp2pJsClients[pkcOptions.key];
492
- }
493
- }
494
- //#endregion
495
- export { createLibp2pJsClientOrUseExistingOne };