@pkcprotocol/pkc-js 0.0.88 → 0.0.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/browser/generated-version.d.ts +1 -1
- package/dist/browser/generated-version.js +1 -1
- package/dist/browser/helia/helia-for-pkc.d.ts +2 -0
- package/dist/browser/helia/helia-for-pkc.js +158 -55
- package/dist/browser/helia/helia-for-pkc.js.map +1 -1
- package/dist/browser/helia/libp2pjsClient.d.ts +1 -1
- package/dist/browser/helia/lru-blockstore.d.ts +9 -8
- package/dist/browser/helia/lru-blockstore.js.map +1 -1
- package/dist/browser/helia/types.d.ts +10 -10
- package/dist/browser/rpc/src/schema.d.ts +148 -22
- package/dist/browser/runtime/node/community/local-community/cleanup.js +31 -1
- package/dist/browser/runtime/node/community/local-community/cleanup.js.map +1 -1
- package/dist/browser/schema.d.ts +8 -6
- package/dist/browser/schema.js +8 -1
- package/dist/browser/schema.js.map +1 -1
- package/dist/browser/test/test-util.js +3 -1
- package/dist/browser/test/test-util.js.map +1 -1
- package/dist/bundled/bundle-manifest.json +165 -146
- package/dist/bundled/chunks/{helia-for-pkc-CgG0H5g2.js → helia-for-pkc-BKXOmklx.js} +70 -39
- package/dist/bundled/chunks/{local-community-rFE0QOdJ.js → local-community-C7tTEYDD.js} +1 -1
- package/dist/bundled/chunks/{local-community-6_MVz1cc.js → local-community-D5fzgPCr.js} +32 -3
- package/dist/bundled/chunks/{node-BjSTVzbx.js → node-C9RpmtmM.js} +5 -5
- package/dist/bundled/chunks/{rpc-local-community-Bu6Wp-tO.js → rpc-local-community-Dq00OHRf.js} +432 -6
- package/dist/bundled/chunks/{schema-By3Sh-uW.js → schema-bDrzx9EZ.js} +3 -3
- package/dist/bundled/chunks/{src-WLgFbUwZ.js → src-629pKfxo.js} +2731 -415
- package/dist/bundled/chunks/{src-B2CwDTfy.js → src-Dz9wtvrK.js} +18 -18
- package/dist/bundled/chunks/{util-BxLdjyTF.js → util-DuJcVQ7Y.js} +1 -1
- package/dist/bundled/index.js +1 -1
- package/dist/bundled/rpc/src/index.js +4 -4
- package/dist/node/generated-version.d.ts +1 -1
- package/dist/node/generated-version.js +1 -1
- package/dist/node/helia/helia-for-pkc.d.ts +2 -0
- package/dist/node/helia/helia-for-pkc.js +158 -55
- package/dist/node/helia/helia-for-pkc.js.map +1 -1
- package/dist/node/helia/libp2pjsClient.d.ts +1 -1
- package/dist/node/helia/lru-blockstore.d.ts +9 -8
- package/dist/node/helia/lru-blockstore.js.map +1 -1
- package/dist/node/helia/types.d.ts +10 -10
- package/dist/node/rpc/src/schema.d.ts +148 -22
- package/dist/node/runtime/node/community/local-community/cleanup.js +31 -1
- package/dist/node/runtime/node/community/local-community/cleanup.js.map +1 -1
- package/dist/node/schema.d.ts +8 -6
- package/dist/node/schema.js +8 -1
- package/dist/node/schema.js.map +1 -1
- package/dist/node/test/test-util.js +3 -1
- package/dist/node/test/test-util.js.map +1 -1
- package/package.json +17 -16
|
@@ -5,10 +5,10 @@ import { CID } from "multiformats/cid";
|
|
|
5
5
|
import { fromString } from "uint8arrays/from-string";
|
|
6
6
|
import { concat } from "uint8arrays/concat";
|
|
7
7
|
import { equals } from "uint8arrays/equals";
|
|
8
|
+
import { sha256 } from "multiformats/hashes/sha2";
|
|
8
9
|
import * as raw from "multiformats/codecs/raw";
|
|
9
10
|
import { alloc, allocUnsafe } from "uint8arrays/alloc";
|
|
10
11
|
import { withArrayBuffer } from "uint8arrays/with-array-buffer";
|
|
11
|
-
import { sha256 } from "multiformats/hashes/sha2";
|
|
12
12
|
import { murmur3128 } from "@multiformats/murmur3";
|
|
13
13
|
import { BlackHoleBlockstore } from "blockstore-core/black-hole";
|
|
14
14
|
//#region node_modules/ipfs-unixfs-importer/node_modules/uint8arraylist/dist/src/index.js
|
|
@@ -485,7 +485,7 @@ const fixedSize = (options = {}) => {
|
|
|
485
485
|
};
|
|
486
486
|
};
|
|
487
487
|
//#endregion
|
|
488
|
-
//#region node_modules/ipfs-unixfs
|
|
488
|
+
//#region node_modules/ipfs-unixfs/dist/src/errors.js
|
|
489
489
|
var InvalidTypeError = class InvalidTypeError extends Error {
|
|
490
490
|
static name = "InvalidTypeError";
|
|
491
491
|
static code = "ERR_INVALID_TYPE";
|
|
@@ -496,7 +496,7 @@ var InvalidTypeError = class InvalidTypeError extends Error {
|
|
|
496
496
|
}
|
|
497
497
|
};
|
|
498
498
|
//#endregion
|
|
499
|
-
//#region node_modules/ipfs-unixfs
|
|
499
|
+
//#region node_modules/ipfs-unixfs/node_modules/uint8-varint/dist/src/index.js
|
|
500
500
|
const N1 = Math.pow(2, 7);
|
|
501
501
|
const N2 = Math.pow(2, 14);
|
|
502
502
|
const N3 = Math.pow(2, 21);
|
|
@@ -579,7 +579,7 @@ function decodeUint8Array(buf, offset) {
|
|
|
579
579
|
throw new RangeError("Could not decode varint");
|
|
580
580
|
}
|
|
581
581
|
//#endregion
|
|
582
|
-
//#region node_modules/ipfs-unixfs
|
|
582
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/utils/float.js
|
|
583
583
|
const f32 = new Float32Array([-0]);
|
|
584
584
|
const f8b = new Uint8Array(f32.buffer);
|
|
585
585
|
/**
|
|
@@ -633,7 +633,7 @@ function readDoubleLE(buf, pos) {
|
|
|
633
633
|
return f64[0];
|
|
634
634
|
}
|
|
635
635
|
//#endregion
|
|
636
|
-
//#region node_modules/ipfs-unixfs
|
|
636
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/utils/longbits.js
|
|
637
637
|
const MAX_SAFE_NUMBER_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);
|
|
638
638
|
const MIN_SAFE_NUMBER_INTEGER = BigInt(Number.MIN_SAFE_INTEGER);
|
|
639
639
|
/**
|
|
@@ -777,7 +777,7 @@ zero.length = function() {
|
|
|
777
777
|
};
|
|
778
778
|
const TWO_32 = 4294967296n;
|
|
779
779
|
//#endregion
|
|
780
|
-
//#region node_modules/ipfs-unixfs
|
|
780
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/utils/utf8.js
|
|
781
781
|
/**
|
|
782
782
|
* Calculates the UTF8 byte length of a string
|
|
783
783
|
*/
|
|
@@ -853,7 +853,7 @@ function write(string, buffer, offset) {
|
|
|
853
853
|
return offset - start;
|
|
854
854
|
}
|
|
855
855
|
//#endregion
|
|
856
|
-
//#region node_modules/ipfs-unixfs
|
|
856
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/utils/reader.js
|
|
857
857
|
/* istanbul ignore next */
|
|
858
858
|
function indexOutOfRange(reader, writeLength) {
|
|
859
859
|
return RangeError(`index out of range: ${reader.pos} + ${writeLength ?? 1} > ${reader.len}`);
|
|
@@ -1153,13 +1153,13 @@ function createReader(buf) {
|
|
|
1153
1153
|
return new Uint8ArrayReader(buf instanceof Uint8Array ? buf : buf.subarray());
|
|
1154
1154
|
}
|
|
1155
1155
|
//#endregion
|
|
1156
|
-
//#region node_modules/ipfs-unixfs
|
|
1156
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/decode.js
|
|
1157
1157
|
function decodeMessage(buf, codec, opts) {
|
|
1158
1158
|
const reader = createReader(buf);
|
|
1159
1159
|
return codec.decode(reader, void 0, opts);
|
|
1160
1160
|
}
|
|
1161
1161
|
//#endregion
|
|
1162
|
-
//#region node_modules/ipfs-unixfs
|
|
1162
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/utils/pool.js
|
|
1163
1163
|
/**
|
|
1164
1164
|
* A general purpose buffer pool
|
|
1165
1165
|
*/
|
|
@@ -1180,7 +1180,7 @@ function pool(size) {
|
|
|
1180
1180
|
};
|
|
1181
1181
|
}
|
|
1182
1182
|
//#endregion
|
|
1183
|
-
//#region node_modules/ipfs-unixfs
|
|
1183
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/utils/writer.js
|
|
1184
1184
|
/**
|
|
1185
1185
|
* Constructs a new writer operation instance.
|
|
1186
1186
|
*
|
|
@@ -1575,20 +1575,20 @@ function createWriter() {
|
|
|
1575
1575
|
return new Uint8ArrayWriter();
|
|
1576
1576
|
}
|
|
1577
1577
|
//#endregion
|
|
1578
|
-
//#region node_modules/ipfs-unixfs
|
|
1578
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/encode.js
|
|
1579
1579
|
function encodeMessage(message, codec) {
|
|
1580
1580
|
const w = createWriter();
|
|
1581
1581
|
codec.encode(message, w, { lengthDelimited: false });
|
|
1582
1582
|
return w.finish();
|
|
1583
1583
|
}
|
|
1584
1584
|
//#endregion
|
|
1585
|
-
//#region node_modules/ipfs-unixfs
|
|
1585
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/stream.js
|
|
1586
1586
|
function* streamMessage(buf, codec, opts) {
|
|
1587
1587
|
const reader = createReader(buf);
|
|
1588
1588
|
yield* codec.stream(reader, void 0, "$", opts);
|
|
1589
1589
|
}
|
|
1590
1590
|
//#endregion
|
|
1591
|
-
//#region node_modules/ipfs-unixfs
|
|
1591
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/codec.js
|
|
1592
1592
|
const CODEC_TYPES = {
|
|
1593
1593
|
VARINT: 0,
|
|
1594
1594
|
BIT64: 1,
|
|
@@ -1607,7 +1607,7 @@ function createCodec(name, type, encode, decode, stream) {
|
|
|
1607
1607
|
};
|
|
1608
1608
|
}
|
|
1609
1609
|
//#endregion
|
|
1610
|
-
//#region node_modules/ipfs-unixfs
|
|
1610
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/codecs/enum.js
|
|
1611
1611
|
function enumeration(v) {
|
|
1612
1612
|
function findValue(val) {
|
|
1613
1613
|
if (v[val.toString()] == null) throw new Error("Invalid enum value");
|
|
@@ -1623,12 +1623,12 @@ function enumeration(v) {
|
|
|
1623
1623
|
});
|
|
1624
1624
|
}
|
|
1625
1625
|
//#endregion
|
|
1626
|
-
//#region node_modules/ipfs-unixfs
|
|
1626
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/codecs/message.js
|
|
1627
1627
|
function message(encode, decode, stream) {
|
|
1628
1628
|
return createCodec("message", CODEC_TYPES.LENGTH_DELIMITED, encode, decode, stream);
|
|
1629
1629
|
}
|
|
1630
1630
|
//#endregion
|
|
1631
|
-
//#region node_modules/ipfs-unixfs
|
|
1631
|
+
//#region node_modules/ipfs-unixfs/node_modules/protons-runtime/dist/src/index.js
|
|
1632
1632
|
/**
|
|
1633
1633
|
* Thrown when a repeated field has too many elements
|
|
1634
1634
|
*/
|
|
@@ -1642,7 +1642,7 @@ var MaxLengthError = class extends Error {
|
|
|
1642
1642
|
name = "MaxLengthError";
|
|
1643
1643
|
};
|
|
1644
1644
|
//#endregion
|
|
1645
|
-
//#region node_modules/ipfs-unixfs
|
|
1645
|
+
//#region node_modules/ipfs-unixfs/dist/src/unixfs.js
|
|
1646
1646
|
var Data;
|
|
1647
1647
|
(function(Data) {
|
|
1648
1648
|
(function(DataType) {
|
|
@@ -1946,7 +1946,7 @@ var Metadata;
|
|
|
1946
1946
|
Metadata.stream = stream;
|
|
1947
1947
|
})(Metadata || (Metadata = {}));
|
|
1948
1948
|
//#endregion
|
|
1949
|
-
//#region node_modules/ipfs-unixfs
|
|
1949
|
+
//#region node_modules/ipfs-unixfs/dist/src/index.js
|
|
1950
1950
|
/**
|
|
1951
1951
|
* @packageDocumentation
|
|
1952
1952
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { br as PKCError, et as pubsubTopicToDhtKeyCid } from "./schema-
|
|
1
|
+
import { br as PKCError, et as pubsubTopicToDhtKeyCid } from "./schema-bDrzx9EZ.js";
|
|
2
2
|
import { ipnsSelector } from "ipns/selector";
|
|
3
3
|
import { equals } from "uint8arrays/equals";
|
|
4
4
|
//#region dist/node/helia/util.js
|
package/dist/bundled/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as getShortCid, i as getShortAddress, n as challenges, o as nativeFunctions, r as createAnchorIpnsRecord, s as setNativeFunctions, t as PKC } from "./chunks/node-
|
|
1
|
+
import { a as getShortCid, i as getShortAddress, n as challenges, o as nativeFunctions, r as createAnchorIpnsRecord, s as setNativeFunctions, t as PKC } from "./chunks/node-C9RpmtmM.js";
|
|
2
2
|
export { challenges, createAnchorIpnsRecord, PKC as default, getShortAddress, getShortCid, nativeFunctions, setNativeFunctions };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Ct as findStartedCommunity, L as hideClassPrivateProps, Sr as logger_default, br as PKCError, lt as replaceXWithY, rr as t, tr as n } from "../../chunks/schema-
|
|
2
|
-
import { _ as parseRpcPublishAnchorRecordParam, c as parseRpcAuthorNameParam, d as parseRpcCommentRepliesPageParam, f as parseRpcCommunityIdentifierParam, g as parseRpcExportCommunityParam, h as parseRpcExportCommunityModLogsParam, l as parseRpcCancelExportParam, m as parseRpcEditCommunityParam, p as parseRpcCommunityPageParam, t as PKC, u as parseRpcCidParam, v as parseRpcPublishChallengeAnswersParam, y as parseRpcUnsubscribeParam } from "../../chunks/node-
|
|
3
|
-
import { An as parseSetNewSettingsPKCWsServerSchemaWithPKCErrorIfItFails, Cn as parseDecryptedChallengeAnswerWithPKCErrorIfItFails, J as buildPagesRuntimeFields, ct as pRetry, dn as parseCommunityEditOptionsSchemaWithPKCErrorIfItFails, dt as require_lib, jn as parseVoteChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, lt as pLimit, nn as parseCommentChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, on as parseCommentModerationChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, q as buildPageRuntimeFields, rn as parseCommentEditChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, rr as t$1, rt as extractCrosspostRuntimeFields, un as parseCommunityEditChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, ur as stringify, vn as parseCreateNewLocalCommunityUserOptionsSchemaWithPKCErrorIfItFails, yn as parseCreatePKCWsServerOptionsSchemaWithPKCErrorIfItFails } from "../../chunks/rpc-local-community-
|
|
4
|
-
import { t as LocalCommunity } from "../../chunks/local-community-
|
|
1
|
+
import { Ct as findStartedCommunity, L as hideClassPrivateProps, Sr as logger_default, br as PKCError, lt as replaceXWithY, rr as t, tr as n } from "../../chunks/schema-bDrzx9EZ.js";
|
|
2
|
+
import { _ as parseRpcPublishAnchorRecordParam, c as parseRpcAuthorNameParam, d as parseRpcCommentRepliesPageParam, f as parseRpcCommunityIdentifierParam, g as parseRpcExportCommunityParam, h as parseRpcExportCommunityModLogsParam, l as parseRpcCancelExportParam, m as parseRpcEditCommunityParam, p as parseRpcCommunityPageParam, t as PKC, u as parseRpcCidParam, v as parseRpcPublishChallengeAnswersParam, y as parseRpcUnsubscribeParam } from "../../chunks/node-C9RpmtmM.js";
|
|
3
|
+
import { An as parseSetNewSettingsPKCWsServerSchemaWithPKCErrorIfItFails, Cn as parseDecryptedChallengeAnswerWithPKCErrorIfItFails, J as buildPagesRuntimeFields, ct as pRetry, dn as parseCommunityEditOptionsSchemaWithPKCErrorIfItFails, dt as require_lib, jn as parseVoteChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, lt as pLimit, nn as parseCommentChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, on as parseCommentModerationChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, q as buildPageRuntimeFields, rn as parseCommentEditChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, rr as t$1, rt as extractCrosspostRuntimeFields, un as parseCommunityEditChallengeRequestToEncryptSchemaWithPKCErrorIfItFails, ur as stringify, vn as parseCreateNewLocalCommunityUserOptionsSchemaWithPKCErrorIfItFails, yn as parseCreatePKCWsServerOptionsSchemaWithPKCErrorIfItFails } from "../../chunks/rpc-local-community-Dq00OHRf.js";
|
|
4
|
+
import { t as LocalCommunity } from "../../chunks/local-community-D5fzgPCr.js";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import assert from "assert";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.0.
|
|
1
|
+
export declare const version = "0.0.89";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { ParsedPKCOptions } from "../types.js";
|
|
2
2
|
import { Libp2pJsClient } from "./libp2pjsClient.js";
|
|
3
|
+
export declare function ipnsRouterTag(router: unknown): string;
|
|
4
|
+
export declare function isLocalStoreIpnsRouter(router: unknown): boolean;
|
|
3
5
|
export declare function createLibp2pJsClientOrUseExistingOne(pkcOptions: Required<Pick<ParsedPKCOptions, "httpRoutersOptions">> & Pick<ParsedPKCOptions, "dataPath"> & NonNullable<ParsedPKCOptions["libp2pJsClientsOptions"]>[number]): Promise<Libp2pJsClient>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHeliaLight } from "helia";
|
|
2
|
+
import { libp2pDefaults, withLibp2p } from "@helia/libp2p";
|
|
3
|
+
import { withBitswap } from "@helia/bitswap";
|
|
2
4
|
import { ipns } from "@helia/ipns";
|
|
3
5
|
import { unmarshalIPNSRecord, multihashToIPNSRoutingKey } from "ipns";
|
|
4
6
|
import { ipnsValidator } from "ipns/validator";
|
|
@@ -6,15 +8,15 @@ import { gossipsub } from "@libp2p/gossipsub";
|
|
|
6
8
|
import { identify } from "@libp2p/identify";
|
|
7
9
|
import extraLibp2pTransports from "../runtime/node/libp2p-extra-transports.js";
|
|
8
10
|
import { CID } from "multiformats/cid";
|
|
11
|
+
import { sha512 } from "multiformats/hashes/sha2";
|
|
9
12
|
import { peerIdFromString } from "@libp2p/peer-id";
|
|
10
|
-
import { bitswap } from "@helia/block-brokers";
|
|
11
13
|
import { createBlockstoreForLibp2pJsClient } from "../runtime/node/blockstore.js";
|
|
12
14
|
import { LruBlockstore } from "./lru-blockstore.js";
|
|
13
15
|
import { delegatedRoutingV1HttpApiClientContentRouting } from "@helia/delegated-routing-v1-http-api-client";
|
|
14
16
|
import { NotFoundError } from "@libp2p/interface";
|
|
15
17
|
import { unixfs } from "@helia/unixfs";
|
|
16
18
|
import { fetch as libp2pFetch } from "@libp2p/fetch";
|
|
17
|
-
import {
|
|
19
|
+
import { pubSubIPNSRouting as createIpnsPubusubRouter } from "@helia/ipns";
|
|
18
20
|
import Logger from "../logger.js";
|
|
19
21
|
import { EventEmitter } from "events";
|
|
20
22
|
import { PKCError } from "../pkc-error.js";
|
|
@@ -84,6 +86,16 @@ function getDelegatedRoutingFields(routers) {
|
|
|
84
86
|
}
|
|
85
87
|
return routersObj;
|
|
86
88
|
}
|
|
89
|
+
// @helia/ipns routers identify themselves through a literal toString() tag ("LocalStoreRouting()",
|
|
90
|
+
// "HeliaRouting()", "PubSubRouting()"). Use that, never `constructor.name`: the classes are
|
|
91
|
+
// module-private and bundlers mangle their names, which turned the old class-name filter into a
|
|
92
|
+
// silent no-op in production builds.
|
|
93
|
+
export function ipnsRouterTag(router) {
|
|
94
|
+
return String(router);
|
|
95
|
+
}
|
|
96
|
+
export function isLocalStoreIpnsRouter(router) {
|
|
97
|
+
return ipnsRouterTag(router) === "LocalStoreRouting()";
|
|
98
|
+
}
|
|
87
99
|
export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
88
100
|
if (!pkcOptions.httpRoutersOptions?.length)
|
|
89
101
|
throw Error("You need to have pkc.httpRouterOptions to set up helia");
|
|
@@ -98,11 +110,16 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
98
110
|
client.countOfUsesOfInstance++;
|
|
99
111
|
return client;
|
|
100
112
|
}
|
|
113
|
+
// Both are set from inside the factory so that the catch handler after it can tear down
|
|
114
|
+
// whatever got started when the wiring throws part-way through: until the client lands in
|
|
115
|
+
// libp2pJsClients nothing else holds a reference to the node, and a started-but-orphaned
|
|
116
|
+
// libp2p keeps gossipsub heartbeats, bitswap and open sockets alive past pkc.destroy().
|
|
117
|
+
let startedHelia;
|
|
118
|
+
let closeBlockstore = async () => { };
|
|
101
119
|
creatingLibp2pJsClients[pkcOptions.key] = (async () => {
|
|
102
120
|
// A caller supplying their own heliaOptions.blockstore owns block storage entirely, so skip
|
|
103
121
|
// ours rather than opening a directory or IndexedDB database nothing will read.
|
|
104
122
|
let lruBlockstore;
|
|
105
|
-
let closeBlockstore = async () => { };
|
|
106
123
|
if (!pkcOptions.heliaOptions?.blockstore) {
|
|
107
124
|
const { blockstore: childBlockstore, persistent, defaultMaxBytes, close } = await createBlockstoreForLibp2pJsClient({
|
|
108
125
|
dataPath: pkcOptions.dataPath,
|
|
@@ -165,17 +182,45 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
165
182
|
// instance ever removes one, so an unbounded store grows for the life of the process.
|
|
166
183
|
// See pkc-js#240 for the measurement behind the cap.
|
|
167
184
|
blockstore: lruBlockstore,
|
|
168
|
-
blockBrokers: [bitswap()],
|
|
169
|
-
start: false,
|
|
170
185
|
...pkcOptions.heliaOptions
|
|
171
186
|
};
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
helia
|
|
187
|
+
// helia 7's createHelia() composes withHTTP() in: a public trustless-gateway block broker
|
|
188
|
+
// plus public delegated HTTP routers and recursive gateways. We use our own gateway
|
|
189
|
+
// fan-out logic in base-client-manager and only the routers the user configured, so
|
|
190
|
+
// compose the node without any HTTP components (heliaOptions.http is excluded from the
|
|
191
|
+
// schema for that reason): bitswap is the only block broker and libp2p the only content
|
|
192
|
+
// router. withLibp2p applies libp2pDefaults with shallow per-key replace semantics (same
|
|
193
|
+
// as helia 6's createHelia): every key we set above wins outright (in particular our
|
|
194
|
+
// narrow `services` map fully replaces the default one), while keys we leave out
|
|
195
|
+
// (connectionEncrypters, streamMuxers, ...) come from helia's defaults.
|
|
196
|
+
//
|
|
197
|
+
// A caller-supplied heliaOptions.blockBrokers REPLACES bitswap, as it did under helia 6
|
|
198
|
+
// (`init.blockBrokers ?? [bitswap()]`): withBitswap() is additive, so applying it on top of
|
|
199
|
+
// the caller's list would hand a gateway-only/opt-out config bitswap sessions and dials anyway.
|
|
200
|
+
//
|
|
201
|
+
// createHeliaLight registers only sha2-256/identity and dag-pb/raw, where createHelia adds
|
|
202
|
+
// sha2-512 and the dag-cbor/dag-json/json codecs. pkc records are unixfs (dag-pb/raw) so
|
|
203
|
+
// the codecs are not needed, but nothing stops a community from publishing a sha2-512 CID
|
|
204
|
+
// (e.g. `ipfs add --hash sha2-512`) and helia looks the hasher up before the first block
|
|
205
|
+
// fetch, so keep sha2-512 to match what fetched under helia 6.
|
|
206
|
+
const { libp2p: mergedLibp2pInit, bitswap: bitswapInit, blockBrokers: callerBlockBrokers, ...heliaLightInit } = mergedHeliaInit;
|
|
207
|
+
const heliaWithLibp2p = withLibp2p(createHeliaLight({
|
|
208
|
+
...heliaLightInit,
|
|
209
|
+
blockBrokers: callerBlockBrokers,
|
|
210
|
+
hashers: [sha512, ...(heliaLightInit.hashers ?? [])]
|
|
211
|
+
}), mergedLibp2pInit ?? {});
|
|
212
|
+
// The composition is typed as helia's default service map (dht, relay, upnp, ...) while our
|
|
213
|
+
// `services` above replaces it; HeliaWithLibp2pPubsub is the narrow map we actually run.
|
|
214
|
+
const helia = (callerBlockBrokers === undefined ? withBitswap(heliaWithLibp2p, bitswapInit) : heliaWithLibp2p);
|
|
215
|
+
// helia 7 creates libp2p lazily inside start() — the `helia.libp2p` getter throws
|
|
216
|
+
// NotStartedError until then — so start the node before wiring anything that reads it.
|
|
217
|
+
// Nothing can race the wiring below: no topic is subscribed and no dial is made until
|
|
218
|
+
// this factory returns the client.
|
|
219
|
+
// Assigned before start(): helia 7's start() has no rollback, so if a later mixin throws
|
|
220
|
+
// (e.g. bitswap's network.start() after withLibp2p already started libp2p) the node is
|
|
221
|
+
// half-started and must still be stopped by the catch below.
|
|
222
|
+
startedHelia = helia;
|
|
223
|
+
await helia.start();
|
|
179
224
|
log("Initialized libp2pjs helia with key", pkcOptions.key, "peer id", helia.libp2p.peerId.toString());
|
|
180
225
|
const pubsubEventHandler = new EventEmitter();
|
|
181
226
|
helia.libp2p.services.pubsub.addEventListener("message", (evt) => {
|
|
@@ -185,10 +230,6 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
185
230
|
pubsubEventHandler.emit(evt.detail.topic, msgFormatted);
|
|
186
231
|
});
|
|
187
232
|
const heliaFs = unixfs(helia);
|
|
188
|
-
const asHeliaCatCid = (ipfsPathOrCid) => {
|
|
189
|
-
CID.parse(ipfsPathOrCid.split("/")[0]); // validate the root CID; throws on malformed input
|
|
190
|
-
return ipfsPathOrCid;
|
|
191
|
-
};
|
|
192
233
|
// Issue #189: without a session, every block fetched over bitswap fires its own
|
|
193
234
|
// network.findAndConnect — a findProviders query against ALL configured HTTP routers per
|
|
194
235
|
// block, plus stray dials to whatever providers it discovers mid-fetch. cat() therefore
|
|
@@ -272,20 +313,51 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
272
313
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
273
314
|
});
|
|
274
315
|
const ipnsPubsubRouter = createIpnsPubusubRouter(helia);
|
|
316
|
+
const ipnsNameResolver = ipns(helia, {
|
|
317
|
+
routers: [ipnsPubsubRouter]
|
|
318
|
+
});
|
|
319
|
+
// @helia/ipns constructs routers as [LocalStoreIPNSRouting, HeliaIPNSRouting, ...userRouters]
|
|
320
|
+
// and hands that SAME array to its resolver/publisher/republisher, so it must be mutated in
|
|
321
|
+
// place: reassigning `.routers` only changes what pkc's own loops below iterate, while
|
|
322
|
+
// ipnsNameResolver.resolve() keeps querying (and writing the local cache through) the
|
|
323
|
+
// original list. We drop LocalStoreIPNSRouting because pkc-js never publishes IPNS via
|
|
324
|
+
// @helia/ipns (kubo does that), so the local cache is always empty and just adds a wasted
|
|
325
|
+
// lookup. Keep HeliaIPNSRouting (HTTP delegated routing via helia.routing) and our pubsub
|
|
326
|
+
// router. Match by the router's toString() tag ("LocalStoreRouting()") rather than by
|
|
327
|
+
// `constructor.name`: the class is module-private and bundlers mangle its name (in 5chan's
|
|
328
|
+
// production build it becomes `dMe`), so a class-name match is a silent no-op there. The
|
|
329
|
+
// tag is a string literal and survives minification. Matching by identity (rather than
|
|
330
|
+
// by index) also means a future @helia/ipns release that re-orders the array can't make
|
|
331
|
+
// us drop the wrong router.
|
|
332
|
+
for (let i = ipnsNameResolver.routers.length - 1; i >= 0; i--) {
|
|
333
|
+
if (isLocalStoreIpnsRouter(ipnsNameResolver.routers[i]))
|
|
334
|
+
ipnsNameResolver.routers.splice(i, 1);
|
|
335
|
+
}
|
|
336
|
+
// The IPNS facade marks itself started (and runs its hourly republisher) from helia's
|
|
337
|
+
// 'start' event, which helia 7 dispatches exactly once at the end of start(), i.e. before the
|
|
338
|
+
// facade existed (its constructor walks helia's components, whose `libp2p` getter throws
|
|
339
|
+
// until start(), so it cannot be built earlier). helia 6 fell back to
|
|
340
|
+
// `libp2p.status === 'started'` and so ran the republisher; that fallback is gone in 7.
|
|
341
|
+
// Nothing in pkc depends on the facade being "started" (resolve() has no started check and
|
|
342
|
+
// pkc walks `routers` directly), so this only keeps helia-6 lifecycle parity for the
|
|
343
|
+
// republisher. start() is on the class but not on the exported IPNS interface.
|
|
344
|
+
ipnsNameResolver.start?.();
|
|
345
|
+
// The router is Startable but neither helia.start() (blockstore/datastore/routing/brokers
|
|
346
|
+
// only) nor the IPNS facade (republisher only) starts user-supplied routers. Its start()
|
|
347
|
+
// registers the libp2p/fetch topology that fills `fetchPeers`, which gates the
|
|
348
|
+
// subscription-change fast path: fetch the record over /libp2p/fetch from a server that
|
|
349
|
+
// joins the topic after our get() already ran (ipfs/helia#906) and republish it to the
|
|
350
|
+
// topic. NOTE: this path is newly enabled here, not restored. Under helia 6 nothing ever
|
|
351
|
+
// called start() on this router either, so `fetchPeers` stayed empty and the fast path
|
|
352
|
+
// never fired. It is largely redundant with the direct fetch below (issue #210) but bounded
|
|
353
|
+
// (one fetch per subscription-change event, into the router's own queue); its republish
|
|
354
|
+
// goes through raw libp2p pubsub, not pkc's mesh-gated wrapper, so a `could not publish
|
|
355
|
+
// record` error line is possible when no mesh peer exists. stop() is mirrored in stop() below.
|
|
356
|
+
await ipnsPubsubRouter.start?.();
|
|
275
357
|
// The router's localStore is where gossipsub-delivered records get cached (handleRecord).
|
|
276
358
|
// It's declared private but is a plain class field at runtime; the direct-fetch path below
|
|
277
359
|
// writes to it to keep the cached-record invariant (issue #210).
|
|
278
360
|
const ipnsPubsubLocalStore = ipnsPubsubRouter.localStore;
|
|
279
|
-
const ipnsNameResolver = ipns(helia, {
|
|
280
|
-
routers: [ipnsPubsubRouter]
|
|
281
|
-
});
|
|
282
|
-
// @helia/ipns constructs routers as [LocalStoreRouting, HeliaRouting, ...userRouters].
|
|
283
|
-
// We drop LocalStoreRouting because pkc-js never publishes IPNS via @helia/ipns (kubo
|
|
284
|
-
// does that), so the local cache is always empty and just adds a wasted lookup. Keep
|
|
285
|
-
// HeliaRouting (HTTP delegated routing via helia.routing.routers) and our PubSubRouting.
|
|
286
|
-
// Filter by class name so a future @helia/ipns release that re-orders the array can't
|
|
287
|
-
// silently drop our pubsub router.
|
|
288
|
-
ipnsNameResolver.routers = ipnsNameResolver.routers.filter((r) => r?.constructor?.name !== "LocalStoreRouting");
|
|
289
361
|
// Side-channel awaitable warmup: gossipsub's pubsub.subscribe(topic) is sync and returns
|
|
290
362
|
// void, so we can't make it awaitable without breaking @helia/ipns and other internal
|
|
291
363
|
// callers that expect the sync contract. Instead, we expose `warmupForTopic(topic)` and
|
|
@@ -427,22 +499,17 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
427
499
|
// See docs/protocol/delegated-ipns.md.
|
|
428
500
|
//
|
|
429
501
|
// Why call routers directly instead of ipnsNameResolver.resolve():
|
|
430
|
-
//
|
|
431
|
-
//
|
|
432
|
-
//
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
//
|
|
437
|
-
//
|
|
438
|
-
//
|
|
439
|
-
//
|
|
440
|
-
//
|
|
441
|
-
// us warm each pubsub topic between yields — but it's unreleased; npm latest 9.2.1 still
|
|
442
|
-
// collapses the chain to the terminal CID. So the per-hop walk stays for now.
|
|
443
|
-
// TODO: after the @helia/ipns upgrade, re-check this — once the generator resolve() is
|
|
444
|
-
// released, replace this router.get + ipnsValidator loop with
|
|
445
|
-
// `for await (const { record } of ipnsNameResolver.resolve(...))`.
|
|
502
|
+
// @helia/ipns 10 reworked resolve() into an async generator that yields one
|
|
503
|
+
// IPNSResolveResult per hop (ipfs/helia#1041), so a single-hop read is now
|
|
504
|
+
// technically reachable by taking the first yield. The per-hop walk stays anyway:
|
|
505
|
+
// - the direct-fetch fast path above (libp2p/fetch from subscribers + freshly
|
|
506
|
+
// discovered providers, with the issue #210 cache write) has no equivalent
|
|
507
|
+
// inside resolve();
|
|
508
|
+
// - per-hop pubsub warmup has to happen BEFORE that hop's record is requested, and
|
|
509
|
+
// resolve() requests the next hop's record internally as soon as it yields;
|
|
510
|
+
// - per-router error aggregation below is what the tests and callers report on.
|
|
511
|
+
// Equivalence of the resolved value with resolve() is pinned in
|
|
512
|
+
// test/node/community/helia-ipns-resolve-equivalence.unit.test.ts.
|
|
446
513
|
// This does NOT bypass an active cache/TTL: all cache-read + TTL logic lives in the
|
|
447
514
|
// resolver's #findIpnsRecord and is gated on `nocache !== true`, but pkc always
|
|
448
515
|
// resolves IPNS with nocache:true (see resolveIpnsToCidP2P in base-client-manager),
|
|
@@ -497,7 +564,13 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
497
564
|
// see MAX_BITSWAP_SESSION_SEED_PEERS above for the why. UnixFSComponents only
|
|
498
565
|
// needs a blockstore, and blocks fetched through the session land in the same
|
|
499
566
|
// underlying blockstore helia uses, so nothing else changes.
|
|
500
|
-
|
|
567
|
+
// ipfsPath is either a bare cid or a `<root-cid>/sub/path`; derive both parts here, once,
|
|
568
|
+
// so root and sub-path can never disagree. unixfs cat takes the root CID plus the sub-path
|
|
569
|
+
// via the `path` option. (The multiformats 13/14 split that used to force string-only cat
|
|
570
|
+
// input is gone: helia 7 and our tree share a single multiformats copy.)
|
|
571
|
+
const [rootCidString, ...ipfsSubPathSegments] = ipfsPath.split("/");
|
|
572
|
+
const rootCid = CID.parse(rootCidString);
|
|
573
|
+
const ipfsSubPath = ipfsSubPathSegments.length > 0 ? ipfsSubPathSegments.join("/") : undefined;
|
|
501
574
|
const timeoutMs = parseKuboStyleTimeoutMs(options?.timeout); // throws on unparseable timeout at call time
|
|
502
575
|
// Our own option, not kubo-rpc-client's — strip it so it never reaches unixfs cat.
|
|
503
576
|
const { bitswapSessionSeedScopeIpnsPubsubTopic, ...unixfsCatOptions } = options ?? {};
|
|
@@ -520,7 +593,8 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
520
593
|
try {
|
|
521
594
|
for (let attempt = 0;; attempt++) {
|
|
522
595
|
const session = helia.blockstore.createSession(rootCid, {
|
|
523
|
-
providers
|
|
596
|
+
// helia 7 sessions take providers as libp2p-key CIDs (or multiaddrs), not PeerIds
|
|
597
|
+
providers: getBitswapSessionSeedPeers(bitswapSessionSeedScopeIpnsPubsubTopic).map((peerId) => peerId.toCID())
|
|
524
598
|
});
|
|
525
599
|
// Issue #218: the session broker waits on a single elected HAVE peer per
|
|
526
600
|
// block with no stall timeout, so one slow seeder holding the only HAVE
|
|
@@ -542,12 +616,9 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
542
616
|
});
|
|
543
617
|
let yieldedAnyBytes = false;
|
|
544
618
|
try {
|
|
545
|
-
|
|
546
|
-
// thing to cat as one string and never split out a `path` option — see
|
|
547
|
-
// asHeliaCatCid above for why the `path` option would re-trip the
|
|
548
|
-
// exporter's CID identity check.
|
|
549
|
-
const catIterable = unixfs({ blockstore: session }).cat(asHeliaCatCid(ipfsPath), {
|
|
619
|
+
const catIterable = unixfs({ blockstore: session }).cat(rootCid, {
|
|
550
620
|
...unixfsCatOptions,
|
|
621
|
+
path: ipfsSubPath,
|
|
551
622
|
signal: controller.signal
|
|
552
623
|
});
|
|
553
624
|
for await (const chunk of catIterable) {
|
|
@@ -664,8 +735,8 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
664
735
|
// createLibp2pJsClientOrUseExistingOne() can't grab a mid-stopping client.
|
|
665
736
|
delete libp2pJsClients[pkcOptions.key];
|
|
666
737
|
// Tear down the IPNS pubsub router's internal subscription state.
|
|
667
|
-
//
|
|
668
|
-
//
|
|
738
|
+
// PubSubIPNSRouting (@helia/ipns) implements Startable and tracks its own
|
|
739
|
+
// subscriptions list and fetch topology — without stop() those leak past helia.
|
|
669
740
|
for (const router of ipnsNameResolver.routers) {
|
|
670
741
|
const lifecycle = router;
|
|
671
742
|
if (typeof lifecycle.stop === "function") {
|
|
@@ -673,7 +744,7 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
673
744
|
await lifecycle.stop();
|
|
674
745
|
}
|
|
675
746
|
catch (e) {
|
|
676
|
-
log.error("Error stopping IPNS router", router
|
|
747
|
+
log.error("Error stopping IPNS router", ipnsRouterTag(router), e);
|
|
677
748
|
}
|
|
678
749
|
}
|
|
679
750
|
}
|
|
@@ -735,11 +806,43 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
|
|
735
806
|
key: pkcOptions.key
|
|
736
807
|
};
|
|
737
808
|
const client = new Libp2pJsClient(fullInstanceWithOptions);
|
|
738
|
-
await helia.start();
|
|
739
809
|
log("Helia/libp2p-js started with key", pkcOptions.key, "and peer id", helia.libp2p.peerId.toString());
|
|
740
810
|
libp2pJsClients[pkcOptions.key] = client;
|
|
741
811
|
return client;
|
|
742
|
-
})()
|
|
812
|
+
})().catch(async (creationError) => {
|
|
813
|
+
// The client never reached libp2pJsClients, so stop() can't be called on it: release
|
|
814
|
+
// whatever this factory started before rethrowing (mirrors the final-release path in stop()).
|
|
815
|
+
if (startedHelia) {
|
|
816
|
+
// The `libp2p` getter throws NotStartedError if start() failed before the libp2p mixin
|
|
817
|
+
// ran, in which case there is nothing to abort.
|
|
818
|
+
let connections = [];
|
|
819
|
+
try {
|
|
820
|
+
connections = startedHelia.libp2p.getConnections();
|
|
821
|
+
}
|
|
822
|
+
catch { }
|
|
823
|
+
for (const connection of connections) {
|
|
824
|
+
try {
|
|
825
|
+
connection.abort(new Error("pkc-js libp2p instance failed to initialize"));
|
|
826
|
+
}
|
|
827
|
+
catch (e) {
|
|
828
|
+
log.error("Error aborting libp2p connection during failed initialization", e);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
try {
|
|
832
|
+
await startedHelia.stop();
|
|
833
|
+
}
|
|
834
|
+
catch (e) {
|
|
835
|
+
log.error("Error stopping helia after failed initialization", e);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
try {
|
|
839
|
+
await closeBlockstore();
|
|
840
|
+
}
|
|
841
|
+
catch (e) {
|
|
842
|
+
log.error("Error closing blockstore after failed initialization", e);
|
|
843
|
+
}
|
|
844
|
+
throw creationError;
|
|
845
|
+
});
|
|
743
846
|
const createdClientPromise = creatingLibp2pJsClients[pkcOptions.key];
|
|
744
847
|
if (!createdClientPromise)
|
|
745
848
|
throw new Error("Missing creation promise after initialization");
|