@peerbit/blocks
Advanced tools
+11
-0
@@ -17,2 +17,12 @@ import type { GetOptions, Blocks as IBlocks } from "@peerbit/blocks-interface"; | ||
| }; | ||
| resolveProviders?: (cid: string, options?: { | ||
| signal?: AbortSignal; | ||
| }) => Promise<string[] | undefined> | string[] | undefined; | ||
| onPut?: (cid: string) => Promise<void> | void; | ||
| providerCache?: boolean | { | ||
| maxEntries?: number; | ||
| ttlMs?: number; | ||
| maxProvidersPerCid?: number; | ||
| }; | ||
| requeryOnReachable?: number; | ||
| }); | ||
@@ -22,2 +32,3 @@ put(bytes: Uint8Array): Promise<string>; | ||
| get(cid: string, options?: GetOptions | undefined): Promise<Uint8Array | undefined>; | ||
| hintProviders(cid: string, providers: string[]): void; | ||
| rm(cid: string): Promise<void>; | ||
@@ -24,0 +35,0 @@ iterator(): AsyncGenerator<[string, Uint8Array], void, void>; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"libp2p.d.ts","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAQ9D,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE3D,qBAAa,WAAY,SAAQ,YAAa,YAAW,OAAO;IAC/D,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,iBAAiB,CAAM;gBAG9B,UAAU,EAAE,qBAAqB,EACjC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;QACtC,WAAW,CAAC,EAAE,OAAO,GAAG;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/C;IAgCI,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM;IAGf,GAAG,CACR,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,GAC9B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI5B,EAAE,CAAC,GAAG,EAAE,MAAM;IAIb,QAAQ,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;IAM7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,IAAI;IAGV,IAAI,MAAM,mDAET;IAED,SAAS,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAGvC"} | ||
| {"version":3,"file":"libp2p.d.ts","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAQ9D,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE3D,qBAAa,WAAY,SAAQ,YAAa,YAAW,OAAO;IAC/D,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,iBAAiB,CAAM;gBAG9B,UAAU,EAAE,qBAAqB,EACjC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;QACtC,WAAW,CAAC,EAAE,OAAO,GAAG;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/C,gBAAgB,CAAC,EAAE,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,KAC9B,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1D,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC9C,aAAa,CAAC,EACX,OAAO,GACP;YACA,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;SAC3B,CAAC;QACL,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B;IAmEI,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM;IAGf,GAAG,CACR,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,GAC9B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIlC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;IAIxC,EAAE,CAAC,GAAG,EAAE,MAAM;IAIb,QAAQ,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;IAM7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,IAAI;IAGV,IAAI,MAAM,mDAET;IAED,SAAS,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAGvC"} |
+42
-2
| import { deserialize, serialize } from "@dao-xyz/borsh"; | ||
| import { createStore } from "@peerbit/any-store"; | ||
| import {} from "@peerbit/crypto"; | ||
| import { getPublicKeyFromPeerId } from "@peerbit/crypto"; | ||
| import { DirectStream } from "@peerbit/stream"; | ||
@@ -14,3 +14,3 @@ import {} from "@peerbit/stream"; | ||
| constructor(components, options) { | ||
| super(components, ["/lazyblock/0.0.0"], { | ||
| super(components, ["/peerbit/direct-block/1.0.0"], { | ||
| messageProcessingConcurrency: options?.messageProcessingConcurrency || 10, | ||
@@ -23,2 +23,35 @@ canRelayMessage: options?.canRelayMessage ?? true, | ||
| }); | ||
| const defaultResolveProviders = () => { | ||
| const out = []; | ||
| const push = (hash) => { | ||
| if (!hash) | ||
| return; | ||
| if (hash === this.publicKeyHash) | ||
| return; | ||
| // Small bounded list; avoid Set allocations on hot paths. | ||
| if (out.includes(hash)) | ||
| return; | ||
| out.push(hash); | ||
| }; | ||
| // Prefer peers we've already negotiated streams with for this protocol. | ||
| for (const h of this.peers.keys()) { | ||
| push(h); | ||
| if (out.length >= 32) | ||
| return out; | ||
| } | ||
| // Fall back to currently connected libp2p peers (even if we haven't opened | ||
| // a `/peerbit/direct-block` stream yet). This makes "join by hash" flows work | ||
| // without requiring an explicit `remote.from` list. | ||
| for (const conn of this.components.connectionManager.getConnections()) { | ||
| try { | ||
| push(getPublicKeyFromPeerId(conn.remotePeer).hashcode()); | ||
| } | ||
| catch { | ||
| // ignore unexpected key types | ||
| } | ||
| if (out.length >= 32) | ||
| break; | ||
| } | ||
| return out; | ||
| }; | ||
| this.remoteBlocks = new RemoteBlocks({ | ||
@@ -32,2 +65,6 @@ local: new AnyBlockStore(createStore(options?.directory)), | ||
| eagerBlocks: options?.eagerBlocks, | ||
| resolveProviders: options?.resolveProviders ?? defaultResolveProviders, | ||
| onPut: options?.onPut, | ||
| providerCache: options?.providerCache, | ||
| requeryOnReachable: options?.requeryOnReachable, | ||
| }); | ||
@@ -50,2 +87,5 @@ this.onDataFn = (data) => { | ||
| } | ||
| hintProviders(cid, providers) { | ||
| this.remoteBlocks.hintProviders(cid, providers); | ||
| } | ||
| async rm(cid) { | ||
@@ -52,0 +92,0 @@ return this.remoteBlocks.rm(cid); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"libp2p.js","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"libp2p.js","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,sBAAsB,EAAsB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAA+B,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAGN,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIzD,MAAM,OAAO,WAAY,SAAQ,YAAY;IACpC,YAAY,CAAe;IAC3B,QAAQ,CAAM;IACd,iBAAiB,CAAM;IAE/B,YACC,UAAiC,EACjC,OAmBC;QAED,KAAK,CAAC,UAAU,EAAE,CAAC,6BAA6B,CAAC,EAAE;YAClD,4BAA4B,EAAE,OAAO,EAAE,4BAA4B,IAAI,EAAE;YACzE,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,IAAI;YACjD,iBAAiB,EAAE;gBAClB,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,KAAK;aACb;SACD,CAAC,CAAC;QAEH,MAAM,uBAAuB,GAAG,GAAG,EAAE;YACpC,MAAM,GAAG,GAAa,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,EAAE;gBAC9B,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAClB,IAAI,IAAI,KAAK,IAAI,CAAC,aAAa;oBAAE,OAAO;gBACxC,0DAA0D;gBAC1D,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAC/B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC;YAEF,wEAAwE;YACxE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;gBACnC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACR,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE;oBAAE,OAAO,GAAG,CAAC;YAClC,CAAC;YAED,2EAA2E;YAC3E,8EAA8E;YAC9E,oDAAoD;YACpD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,CAAC;gBACvE,IAAI,CAAC;oBACJ,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC1D,CAAC;gBAAC,MAAM,CAAC;oBACR,8BAA8B;gBAC/B,CAAC;gBACD,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE;oBAAE,MAAM;YAC7B,CAAC;YAED,OAAO,GAAG,CAAC;QACZ,CAAC,CAAC;QACF,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,KAAK,EAAE,IAAI,aAAa,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACzD,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;YACxE,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,IAAI;YAC3C,4BAA4B,EAAE,OAAO,EAAE,4BAA4B,IAAI,EAAE;YACzE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAmB;YAClD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,IAAI,uBAAuB;YACtE,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,aAAa,EAAE,OAAO,EAAE,aAAa;YACrC,kBAAkB,EAAE,OAAO,EAAE,kBAAkB;SAC/C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,GAAG,CAAC,IAA8B,EAAE,EAAE;YAClD,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM;gBACxB,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC;gBAC5B,IAAI,CAAC,YAAY,CAAC,SAAS,CAC1B,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAK,EAAE,YAAY,CAAC,EAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CACxD,CAAC;QACJ,CAAC,CAAC;QACF,IAAI,CAAC,iBAAiB,GAAG,CAAC,GAA+B,EAAE,EAAE,CAC5D,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAiB;QAC1B,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IACD,KAAK,CAAC,GAAG,CACR,GAAW,EACX,OAAgC;QAEhC,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,aAAa,CAAC,GAAW,EAAE,SAAmB;QAC7C,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,EAAE,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,CAAC,QAAQ;QACd,IAAI,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC/D,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChE,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,IAAI;QACT,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACnE,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,IAAI;QACT,OAAO,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,YAAY,EAAE,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;IAClD,CAAC;IAED,SAAS;QACR,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;IACtC,CAAC;CACD"} |
+75
-0
@@ -29,2 +29,35 @@ import { type GetOptions, type Blocks as IBlocks } from "@peerbit/blocks-interface"; | ||
| }; | ||
| /** | ||
| * Optional provider resolver used when `remote: true` is used without `remote.from`. | ||
| * | ||
| * This is intentionally best-effort and must be bounded; returning large lists is | ||
| * counterproductive at scale. | ||
| */ | ||
| resolveProviders?: (cid: string, options?: { | ||
| signal?: AbortSignal; | ||
| }) => Promise<string[] | undefined> | string[] | undefined; | ||
| /** | ||
| * Optional hook called after a block is stored locally (best-effort). | ||
| * | ||
| * Intended for wiring in discovery/provider announcements without coupling | ||
| * this transport to a specific directory implementation. | ||
| */ | ||
| onPut?: (cid: string) => Promise<void> | void; | ||
| /** | ||
| * Cache of learned/suggested providers per CID to reduce repeated lookups and avoid | ||
| * expensive "search" behaviors. | ||
| */ | ||
| providerCache?: boolean | { | ||
| /** Max distinct CIDs kept in memory. */ | ||
| maxEntries?: number; | ||
| /** Entry TTL in milliseconds. */ | ||
| ttlMs?: number; | ||
| /** Max provider hashes stored per CID. */ | ||
| maxProvidersPerCid?: number; | ||
| }; | ||
| /** | ||
| * When a request is in-flight and new peers become reachable, re-issue the request | ||
| * a limited number of times (helps "get before connect" workflows). | ||
| */ | ||
| requeryOnReachable?: number; | ||
| publish: (data: BlockRequest | BlockResponse, options: PublishOptions) => Promise<Uint8Array | undefined | void>; | ||
@@ -37,2 +70,6 @@ waitFor: WaitForPeersFn; | ||
| private _blockCache?; | ||
| private _providerCache?; | ||
| private readonly publicKeyHash; | ||
| private readonly maxProviderHintsPerCid; | ||
| private readonly maxRequeryOnReachable; | ||
| private _loadFetchQueue; | ||
@@ -51,5 +88,42 @@ private _readFromPeersPromises; | ||
| }; | ||
| /** | ||
| * Optional provider resolver used when `remote: true` is used without `remote.from`. | ||
| * | ||
| * This is intentionally best-effort and must be bounded; returning large lists is | ||
| * counterproductive at scale. | ||
| */ | ||
| resolveProviders?: (cid: string, options?: { | ||
| signal?: AbortSignal; | ||
| }) => Promise<string[] | undefined> | string[] | undefined; | ||
| /** | ||
| * Optional hook called after a block is stored locally (best-effort). | ||
| * | ||
| * Intended for wiring in discovery/provider announcements without coupling | ||
| * this transport to a specific directory implementation. | ||
| */ | ||
| onPut?: (cid: string) => Promise<void> | void; | ||
| /** | ||
| * Cache of learned/suggested providers per CID to reduce repeated lookups and avoid | ||
| * expensive "search" behaviors. | ||
| */ | ||
| providerCache?: boolean | { | ||
| /** Max distinct CIDs kept in memory. */ | ||
| maxEntries?: number; | ||
| /** Entry TTL in milliseconds. */ | ||
| ttlMs?: number; | ||
| /** Max provider hashes stored per CID. */ | ||
| maxProvidersPerCid?: number; | ||
| }; | ||
| /** | ||
| * When a request is in-flight and new peers become reachable, re-issue the request | ||
| * a limited number of times (helps "get before connect" workflows). | ||
| */ | ||
| requeryOnReachable?: number; | ||
| publish: (data: BlockRequest | BlockResponse, options: PublishOptions) => Promise<Uint8Array | undefined | void>; | ||
| waitFor: WaitForPeersFn; | ||
| }); | ||
| private normalizeProviderHints; | ||
| private rememberProvider; | ||
| private rememberProviderHints; | ||
| private resolveRemoteProviders; | ||
| put(bytes: Uint8Array | { | ||
@@ -61,2 +135,3 @@ block: Block<any, any, any, any>; | ||
| get(cid: string, options?: GetOptions | undefined): Promise<Uint8Array | undefined>; | ||
| hintProviders(cid: string, providers: string[]): void; | ||
| rm(cid: string): Promise<void>; | ||
@@ -63,0 +138,0 @@ iterator(): AsyncGenerator<[string, Uint8Array], void, void>; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"} |
+214
-38
@@ -42,3 +42,3 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { | ||
| import { dontThrowIfDeliveryError } from "@peerbit/stream"; | ||
| import { AnyWhere, SilentDelivery, } from "@peerbit/stream-interface"; | ||
| import { SilentDelivery, } from "@peerbit/stream-interface"; | ||
| import { AbortError } from "@peerbit/time"; | ||
@@ -126,10 +126,15 @@ import { CID } from "multiformats"; | ||
| _blockCache; | ||
| _providerCache; | ||
| publicKeyHash; | ||
| maxProviderHintsPerCid; | ||
| maxRequeryOnReachable; | ||
| _loadFetchQueue; | ||
| _readFromPeersPromises; | ||
| _open = false; | ||
| _events; | ||
| closeController; | ||
| _events = new TypedEventEmitter(); | ||
| closeController = new AbortController(); | ||
| constructor(options) { | ||
| this.options = options; | ||
| const localTimeout = options?.localTimeout || 1000; | ||
| this.publicKeyHash = options.publicKey.hashcode(); | ||
| this._loadFetchQueue = new PQueue({ | ||
@@ -149,2 +154,15 @@ concurrency: options?.messageProcessingConcurrency || 10, | ||
| : undefined; | ||
| const providerCache = options.providerCache === false | ||
| ? undefined | ||
| : typeof options.providerCache === "object" | ||
| ? options.providerCache | ||
| : {}; | ||
| this._providerCache = providerCache | ||
| ? new Cache({ | ||
| max: providerCache.maxEntries ?? 2048, | ||
| ttl: providerCache.ttlMs ?? 10 * 60 * 1000, | ||
| }) | ||
| : undefined; | ||
| this.maxProviderHintsPerCid = providerCache?.maxProvidersPerCid ?? 8; | ||
| this.maxRequeryOnReachable = options.requeryOnReachable ?? 4; | ||
| this._responseHandler = async (message, from) => { | ||
@@ -166,2 +184,5 @@ try { | ||
| // TODO make sure we are not storing too much bytes in ram (like filter large blocks) | ||
| if (from) { | ||
| this.rememberProvider(message.cid, from); | ||
| } | ||
| let resolver = this._resolvers.get(message.cid); | ||
@@ -185,2 +206,67 @@ if (!resolver) { | ||
| } | ||
| normalizeProviderHints(providers, limit = this.maxProviderHintsPerCid || 8) { | ||
| if (!providers || providers.length === 0) | ||
| return []; | ||
| const out = []; | ||
| for (const p of providers) { | ||
| if (!p) | ||
| continue; | ||
| if (p === this.publicKeyHash) | ||
| continue; | ||
| // Small bounded list; avoid Set allocations on hot paths. | ||
| if (out.includes(p)) | ||
| continue; | ||
| out.push(p); | ||
| if (out.length >= limit) | ||
| break; | ||
| } | ||
| return out; | ||
| } | ||
| rememberProvider(cidString, providerHash) { | ||
| if (!this._providerCache) | ||
| return; | ||
| if (!providerHash || providerHash === this.publicKeyHash) | ||
| return; | ||
| const current = this._providerCache.get(cidString) ?? []; | ||
| const next = [providerHash]; | ||
| for (const p of current) { | ||
| if (p === providerHash) | ||
| continue; | ||
| if (!p || p === this.publicKeyHash) | ||
| continue; | ||
| next.push(p); | ||
| if (next.length >= this.maxProviderHintsPerCid) | ||
| break; | ||
| } | ||
| this._providerCache.add(cidString, next); | ||
| } | ||
| rememberProviderHints(cidString, providers) { | ||
| if (!this._providerCache) | ||
| return; | ||
| const normalized = this.normalizeProviderHints(providers); | ||
| if (normalized.length === 0) | ||
| return; | ||
| this._providerCache.add(cidString, normalized); | ||
| } | ||
| async resolveRemoteProviders(cidString, options) { | ||
| // Priority: | ||
| // 1. cached providers (from previous reads) | ||
| // 2. resolveProviders hook (e.g. program-level replicators, DHT, tracker) | ||
| const cached = this.normalizeProviderHints(this._providerCache?.get(cidString) ?? undefined); | ||
| if (cached.length > 0) | ||
| return cached; | ||
| if (!this.options.resolveProviders) | ||
| return []; | ||
| try { | ||
| const resolved = await this.options.resolveProviders(cidString, options); | ||
| const normalized = this.normalizeProviderHints(resolved); | ||
| if (normalized.length > 0) { | ||
| this.rememberProviderHints(cidString, normalized); | ||
| } | ||
| return normalized; | ||
| } | ||
| catch { | ||
| return []; | ||
| } | ||
| } | ||
| async put(bytes) { | ||
@@ -190,3 +276,10 @@ if (!this.localStore) { | ||
| } | ||
| return this.localStore.put(bytes); | ||
| const cid = await this.localStore.put(bytes); | ||
| try { | ||
| await this.options.onPut?.(cid); | ||
| } | ||
| catch { | ||
| // ignore best-effort hooks | ||
| } | ||
| return cid; | ||
| } | ||
@@ -197,3 +290,2 @@ async has(cid) { | ||
| async get(cid, options) { | ||
| const cidObject = cidifyString(cid); | ||
| let value = this.localStore | ||
@@ -204,7 +296,8 @@ ? await this.localStore.get(cid, options) | ||
| // try to get it remotelly | ||
| let remoteOptions = options?.remote === true ? {} : options?.remote; | ||
| const remoteOptions = options?.remote === true ? {} : options?.remote; | ||
| if (remoteOptions) { | ||
| const cidObject = cidifyString(cid); | ||
| value = await this._readFromPeers(cid, cidObject, remoteOptions); | ||
| if (remoteOptions?.replicate && value) { | ||
| await this.localStore.put(value); | ||
| await this.put(value); | ||
| } | ||
@@ -215,2 +308,7 @@ } | ||
| } | ||
| hintProviders(cid, providers) { | ||
| const cidString = stringifyCid(cid); | ||
| this.rememberProviderHints(cidString, providers); | ||
| this._events.dispatchEvent(new CustomEvent("providers:hints", { detail: { cid: cidString } })); | ||
| } | ||
| async rm(cid) { | ||
@@ -242,3 +340,3 @@ await this.localStore?.rm(cid); | ||
| const cid = stringifyCid(request.cid); | ||
| const bytes = await this.localStore.get(cid, { | ||
| let bytes = await this.localStore.get(cid, { | ||
| remote: { | ||
@@ -249,4 +347,38 @@ timeout: localTimeout, | ||
| if (!bytes) { | ||
| // Best-effort relay/proxy: if we don't have the block locally, try to fetch it | ||
| // from other reachable peers and then respond to the requester. | ||
| // | ||
| // This keeps multi-hop topologies working (e.g. A <-> relay <-> B) without | ||
| // requiring the requester to know an explicit `remote.from` provider set. | ||
| try { | ||
| const cidObject = cidifyString(cid); | ||
| const proxyTimeoutMs = Math.max(1_000, Math.floor(localTimeout) || 0); | ||
| const controller = new AbortController(); | ||
| const timer = setTimeout(() => controller.abort(), proxyTimeoutMs); | ||
| try { | ||
| const candidates = await this.resolveRemoteProviders(cid, { | ||
| signal: controller.signal, | ||
| }); | ||
| // Never bounce the request back to the requester; keep the fanout bounded. | ||
| const providers = candidates | ||
| .filter((p) => p && p !== from) | ||
| .slice(0, this.maxProviderHintsPerCid); | ||
| if (providers.length > 0) { | ||
| bytes = await this._readFromPeers(cid, cidObject, { | ||
| signal: controller.signal, | ||
| timeout: proxyTimeoutMs, | ||
| from: providers, | ||
| }); | ||
| } | ||
| } | ||
| finally { | ||
| clearTimeout(timer); | ||
| } | ||
| } | ||
| catch { | ||
| // ignore proxy failures | ||
| } | ||
| } | ||
| if (!bytes) | ||
| return; | ||
| } | ||
| await this.options | ||
@@ -278,15 +410,35 @@ .publish(new BlockResponse(cid, bytes), { to: [from] }) | ||
| } | ||
| const explicitFrom = this.normalizeProviderHints(options.from); | ||
| let providers = explicitFrom.length > 0 | ||
| ? explicitFrom | ||
| : await this.resolveRemoteProviders(cidString, { signal: options.signal }); | ||
| const canResolveLater = explicitFrom.length === 0 && typeof this.options.resolveProviders === "function"; | ||
| if (providers.length === 0 && !canResolveLater) { | ||
| // Without an explicit provider set (or a resolver), we intentionally do not | ||
| // fall back to network-wide flooding. Scalable deployments must provide a | ||
| // discovery mechanism (program-level hints, DHT/tracker, etc). | ||
| return undefined; | ||
| } | ||
| if (explicitFrom.length > 0 && providers.length > 0) { | ||
| this.rememberProviderHints(cidString, providers); | ||
| } | ||
| let promise = this._readFromPeersPromises.get(cidString); | ||
| if (!promise) { | ||
| promise = new Promise((resolve, reject) => { | ||
| const timeoutCallback = setTimeout(() => { | ||
| resolve(undefined); | ||
| }, options.timeout || 30 * 1000); | ||
| let timeoutCallback; | ||
| const abortHandler = () => { | ||
| clearTimeout(timeoutCallback); | ||
| cleanup(); | ||
| reject(new AbortError()); | ||
| }; | ||
| const cleanup = () => { | ||
| if (timeoutCallback) | ||
| clearTimeout(timeoutCallback); | ||
| this._resolvers.delete(cidString); | ||
| this.closeController.signal.removeEventListener("abort", abortHandler); | ||
| options?.signal?.removeEventListener("abort", abortHandler); | ||
| reject(new AbortError()); | ||
| }; | ||
| timeoutCallback = setTimeout(() => { | ||
| cleanup(); | ||
| resolve(undefined); | ||
| }, options.timeout || 30 * 1000); | ||
| this.closeController.signal.addEventListener("abort", abortHandler); | ||
@@ -296,5 +448,3 @@ options?.signal?.addEventListener("abort", abortHandler); | ||
| const value = await tryDecode(bytes); | ||
| clearTimeout(timeoutCallback); | ||
| this._resolvers.delete(cidString); // TODO concurrency might not work as expected here | ||
| this.closeController.signal.removeEventListener("abort", abortHandler); | ||
| cleanup(); | ||
| resolve(value); | ||
@@ -304,26 +454,51 @@ }); | ||
| this._readFromPeersPromises.set(cidString, promise); | ||
| const publishOnNewPeers = (e) => { | ||
| const to = e.detail.hashcode(); | ||
| if (!options?.from || options.from.includes(to)) { | ||
| this.options | ||
| .publish(new BlockRequest(cidString), { | ||
| // We dont sent explicitly to 'to' here because we want the message to propagate beyond the first peer | ||
| to: [to], | ||
| mode: new AnyWhere(), | ||
| }) | ||
| .catch(dontThrowIfDeliveryError); | ||
| let requeryCount = 0; | ||
| const tryPublishRequest = async () => { | ||
| if (requeryCount >= this.maxRequeryOnReachable) | ||
| return; | ||
| if (providers.length === 0) { | ||
| providers = await this.resolveRemoteProviders(cidString, { | ||
| signal: options.signal, | ||
| }); | ||
| } | ||
| if (providers.length === 0) | ||
| return; | ||
| try { | ||
| await this.options.publish(new BlockRequest(cidString), { | ||
| mode: new SilentDelivery({ to: providers, redundancy: 1 }), | ||
| }); | ||
| requeryCount += 1; | ||
| } | ||
| catch (e) { | ||
| dontThrowIfDeliveryError(e); | ||
| } | ||
| }; | ||
| const publishOnNewPeers = () => { | ||
| // Re-issue when reachability changes to handle "get before connect". | ||
| // Bounded to avoid accidental amplification at large scale. | ||
| if (requeryCount >= this.maxRequeryOnReachable) | ||
| return; | ||
| tryPublishRequest().catch(dontThrowIfDeliveryError); | ||
| }; | ||
| const publishOnProviderHints = (ev) => { | ||
| if (requeryCount >= this.maxRequeryOnReachable) | ||
| return; | ||
| if (!ev?.detail?.cid) | ||
| return; | ||
| if (ev.detail.cid !== cidString) | ||
| return; | ||
| tryPublishRequest().catch(dontThrowIfDeliveryError); | ||
| }; | ||
| this._events.addEventListener("peer:reachable", publishOnNewPeers); | ||
| await this.options.publish(new BlockRequest(cidString), { | ||
| mode: options.from | ||
| ? new SilentDelivery({ to: options.from, redundancy: 1 }) | ||
| : new AnyWhere(), | ||
| }); | ||
| // we want to make sure that if some new peers join, we also try to ask them | ||
| const result = await promise; | ||
| this._readFromPeersPromises.delete(cidString); | ||
| // stop asking new peers, because we already got an response | ||
| this._events.removeEventListener("peer:reachable", publishOnNewPeers); | ||
| return result?.bytes; | ||
| this._events.addEventListener("providers:hints", publishOnProviderHints); | ||
| try { | ||
| await tryPublishRequest(); | ||
| const result = await promise; | ||
| return result?.bytes; | ||
| } | ||
| finally { | ||
| this._readFromPeersPromises.delete(cidString); | ||
| this._events.removeEventListener("peer:reachable", publishOnNewPeers); | ||
| this._events.removeEventListener("providers:hints", publishOnProviderHints); | ||
| } | ||
| } | ||
@@ -345,2 +520,3 @@ else { | ||
| this._blockCache?.clear(); | ||
| this._providerCache?.clear(); | ||
| this._open = false; | ||
@@ -347,0 +523,0 @@ // we dont cleanup subscription because we dont know if someone else is sbuscribing also |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"} |
+12
-12
| { | ||
| "name": "@peerbit/blocks", | ||
| "version": "3.1.8", | ||
| "version": "4.0.0-b712c6b", | ||
| "description": "Block store streaming", | ||
@@ -71,3 +71,3 @@ "type": "module", | ||
| "devDependencies": { | ||
| "@peerbit/libp2p-test-utils": "2.2.0" | ||
| "@peerbit/libp2p-test-utils": "3.0.0-b712c6b" | ||
| }, | ||
@@ -79,2 +79,11 @@ "dependencies": { | ||
| "@libp2p/websockets": "^10.1.0", | ||
| "@peerbit/any-store": "2.2.5-b712c6b", | ||
| "@peerbit/any-store-interface": "1.1.0-b712c6b", | ||
| "@peerbit/cache": "3.0.0-b712c6b", | ||
| "@peerbit/logger": "2.0.0-b712c6b", | ||
| "@peerbit/stream": "5.0.0-b712c6b", | ||
| "@peerbit/stream-interface": "6.0.0-b712c6b", | ||
| "@peerbit/time": "3.0.0-b712c6b", | ||
| "@peerbit/blocks-interface": "2.0.0-b712c6b", | ||
| "@peerbit/crypto": "3.0.0-b712c6b", | ||
| "@ipld/dag-cbor": "^9.2.1", | ||
@@ -84,12 +93,3 @@ "multiformats": "^13.4.1", | ||
| "p-queue": "^8.0.1", | ||
| "uint8arrays": "^5.1.0", | ||
| "@peerbit/any-store": "2.2.4", | ||
| "@peerbit/any-store-interface": "1.1.0", | ||
| "@peerbit/logger": "2.0.0", | ||
| "@peerbit/stream": "4.6.0", | ||
| "@peerbit/stream-interface": "5.4.0", | ||
| "@peerbit/time": "2.3.0", | ||
| "@peerbit/blocks-interface": "1.5.2", | ||
| "@peerbit/cache": "2.2.0", | ||
| "@peerbit/crypto": "2.4.1" | ||
| "uint8arrays": "^5.1.0" | ||
| }, | ||
@@ -96,0 +96,0 @@ "scripts": { |
+54
-2
| import { deserialize, serialize } from "@dao-xyz/borsh"; | ||
| import { createStore } from "@peerbit/any-store"; | ||
| import type { GetOptions, Blocks as IBlocks } from "@peerbit/blocks-interface"; | ||
| import { type PublicSignKey } from "@peerbit/crypto"; | ||
| import { getPublicKeyFromPeerId, type PublicSignKey } from "@peerbit/crypto"; | ||
| import { DirectStream } from "@peerbit/stream"; | ||
@@ -29,5 +29,18 @@ import { type DirectStreamComponents } from "@peerbit/stream"; | ||
| eagerBlocks?: boolean | { cacheSize?: number }; | ||
| resolveProviders?: ( | ||
| cid: string, | ||
| options?: { signal?: AbortSignal }, | ||
| ) => Promise<string[] | undefined> | string[] | undefined; | ||
| onPut?: (cid: string) => Promise<void> | void; | ||
| providerCache?: | ||
| | boolean | ||
| | { | ||
| maxEntries?: number; | ||
| ttlMs?: number; | ||
| maxProvidersPerCid?: number; | ||
| }; | ||
| requeryOnReachable?: number; | ||
| }, | ||
| ) { | ||
| super(components, ["/lazyblock/0.0.0"], { | ||
| super(components, ["/peerbit/direct-block/1.0.0"], { | ||
| messageProcessingConcurrency: options?.messageProcessingConcurrency || 10, | ||
@@ -40,2 +53,33 @@ canRelayMessage: options?.canRelayMessage ?? true, | ||
| }); | ||
| const defaultResolveProviders = () => { | ||
| const out: string[] = []; | ||
| const push = (hash?: string) => { | ||
| if (!hash) return; | ||
| if (hash === this.publicKeyHash) return; | ||
| // Small bounded list; avoid Set allocations on hot paths. | ||
| if (out.includes(hash)) return; | ||
| out.push(hash); | ||
| }; | ||
| // Prefer peers we've already negotiated streams with for this protocol. | ||
| for (const h of this.peers.keys()) { | ||
| push(h); | ||
| if (out.length >= 32) return out; | ||
| } | ||
| // Fall back to currently connected libp2p peers (even if we haven't opened | ||
| // a `/peerbit/direct-block` stream yet). This makes "join by hash" flows work | ||
| // without requiring an explicit `remote.from` list. | ||
| for (const conn of this.components.connectionManager.getConnections()) { | ||
| try { | ||
| push(getPublicKeyFromPeerId(conn.remotePeer).hashcode()); | ||
| } catch { | ||
| // ignore unexpected key types | ||
| } | ||
| if (out.length >= 32) break; | ||
| } | ||
| return out; | ||
| }; | ||
| this.remoteBlocks = new RemoteBlocks({ | ||
@@ -49,2 +93,6 @@ local: new AnyBlockStore(createStore(options?.directory)), | ||
| eagerBlocks: options?.eagerBlocks, | ||
| resolveProviders: options?.resolveProviders ?? defaultResolveProviders, | ||
| onPut: options?.onPut, | ||
| providerCache: options?.providerCache, | ||
| requeryOnReachable: options?.requeryOnReachable, | ||
| }); | ||
@@ -78,2 +126,6 @@ | ||
| hintProviders(cid: string, providers: string[]) { | ||
| this.remoteBlocks.hintProviders(cid, providers); | ||
| } | ||
| async rm(cid: string) { | ||
@@ -80,0 +132,0 @@ return this.remoteBlocks.rm(cid); |
+253
-46
@@ -16,3 +16,2 @@ import { field, variant } from "@dao-xyz/borsh"; | ||
| import { | ||
| AnyWhere, | ||
| type PeerRefs, | ||
@@ -68,2 +67,6 @@ SilentDelivery, | ||
| private _blockCache?: Cache<Uint8Array>; | ||
| private _providerCache?: Cache<string[]>; | ||
| private readonly publicKeyHash: string; | ||
| private readonly maxProviderHintsPerCid: number; | ||
| private readonly maxRequeryOnReachable: number; | ||
@@ -78,4 +81,5 @@ private _loadFetchQueue: PQueue; | ||
| "peer:reachable": CustomEvent<PublicSignKey>; | ||
| }>; | ||
| private closeController: AbortController; | ||
| "providers:hints": CustomEvent<{ cid: string }>; | ||
| }> = new TypedEventEmitter(); | ||
| private closeController: AbortController = new AbortController(); | ||
@@ -89,2 +93,38 @@ constructor( | ||
| eagerBlocks?: boolean | { cacheSize?: number }; | ||
| /** | ||
| * Optional provider resolver used when `remote: true` is used without `remote.from`. | ||
| * | ||
| * This is intentionally best-effort and must be bounded; returning large lists is | ||
| * counterproductive at scale. | ||
| */ | ||
| resolveProviders?: ( | ||
| cid: string, | ||
| options?: { signal?: AbortSignal }, | ||
| ) => Promise<string[] | undefined> | string[] | undefined; | ||
| /** | ||
| * Optional hook called after a block is stored locally (best-effort). | ||
| * | ||
| * Intended for wiring in discovery/provider announcements without coupling | ||
| * this transport to a specific directory implementation. | ||
| */ | ||
| onPut?: (cid: string) => Promise<void> | void; | ||
| /** | ||
| * Cache of learned/suggested providers per CID to reduce repeated lookups and avoid | ||
| * expensive "search" behaviors. | ||
| */ | ||
| providerCache?: | ||
| | boolean | ||
| | { | ||
| /** Max distinct CIDs kept in memory. */ | ||
| maxEntries?: number; | ||
| /** Entry TTL in milliseconds. */ | ||
| ttlMs?: number; | ||
| /** Max provider hashes stored per CID. */ | ||
| maxProvidersPerCid?: number; | ||
| }; | ||
| /** | ||
| * When a request is in-flight and new peers become reachable, re-issue the request | ||
| * a limited number of times (helps "get before connect" workflows). | ||
| */ | ||
| requeryOnReachable?: number; | ||
| publish: ( | ||
@@ -98,2 +138,3 @@ data: BlockRequest | BlockResponse, | ||
| const localTimeout = options?.localTimeout || 1000; | ||
| this.publicKeyHash = options.publicKey.hashcode(); | ||
| this._loadFetchQueue = new PQueue({ | ||
@@ -114,2 +155,21 @@ concurrency: options?.messageProcessingConcurrency || 10, | ||
| : undefined; | ||
| type ProviderCacheOptions = { | ||
| maxEntries?: number; | ||
| ttlMs?: number; | ||
| maxProvidersPerCid?: number; | ||
| }; | ||
| const providerCache: ProviderCacheOptions | undefined = | ||
| options.providerCache === false | ||
| ? undefined | ||
| : typeof options.providerCache === "object" | ||
| ? options.providerCache | ||
| : {}; | ||
| this._providerCache = providerCache | ||
| ? new Cache<string[]>({ | ||
| max: providerCache.maxEntries ?? 2048, | ||
| ttl: providerCache.ttlMs ?? 10 * 60 * 1000, | ||
| }) | ||
| : undefined; | ||
| this.maxProviderHintsPerCid = providerCache?.maxProvidersPerCid ?? 8; | ||
| this.maxRequeryOnReachable = options.requeryOnReachable ?? 4; | ||
@@ -130,2 +190,5 @@ this._responseHandler = async (message: BlockMessage, from?: string) => { | ||
| // TODO make sure we are not storing too much bytes in ram (like filter large blocks) | ||
| if (from) { | ||
| this.rememberProvider(message.cid, from); | ||
| } | ||
| let resolver = this._resolvers.get(message.cid); | ||
@@ -148,2 +211,64 @@ if (!resolver) { | ||
| private normalizeProviderHints( | ||
| providers: string[] | undefined, | ||
| limit = this.maxProviderHintsPerCid || 8, | ||
| ): string[] { | ||
| if (!providers || providers.length === 0) return []; | ||
| const out: string[] = []; | ||
| for (const p of providers) { | ||
| if (!p) continue; | ||
| if (p === this.publicKeyHash) continue; | ||
| // Small bounded list; avoid Set allocations on hot paths. | ||
| if (out.includes(p)) continue; | ||
| out.push(p); | ||
| if (out.length >= limit) break; | ||
| } | ||
| return out; | ||
| } | ||
| private rememberProvider(cidString: string, providerHash: string) { | ||
| if (!this._providerCache) return; | ||
| if (!providerHash || providerHash === this.publicKeyHash) return; | ||
| const current = this._providerCache.get(cidString) ?? []; | ||
| const next: string[] = [providerHash]; | ||
| for (const p of current) { | ||
| if (p === providerHash) continue; | ||
| if (!p || p === this.publicKeyHash) continue; | ||
| next.push(p); | ||
| if (next.length >= this.maxProviderHintsPerCid) break; | ||
| } | ||
| this._providerCache.add(cidString, next); | ||
| } | ||
| private rememberProviderHints(cidString: string, providers: string[]) { | ||
| if (!this._providerCache) return; | ||
| const normalized = this.normalizeProviderHints(providers); | ||
| if (normalized.length === 0) return; | ||
| this._providerCache.add(cidString, normalized); | ||
| } | ||
| private async resolveRemoteProviders( | ||
| cidString: string, | ||
| options?: { signal?: AbortSignal }, | ||
| ): Promise<string[]> { | ||
| // Priority: | ||
| // 1. cached providers (from previous reads) | ||
| // 2. resolveProviders hook (e.g. program-level replicators, DHT, tracker) | ||
| const cached = this.normalizeProviderHints( | ||
| this._providerCache?.get(cidString) ?? undefined, | ||
| ); | ||
| if (cached.length > 0) return cached; | ||
| if (!this.options.resolveProviders) return []; | ||
| try { | ||
| const resolved = await this.options.resolveProviders(cidString, options); | ||
| const normalized = this.normalizeProviderHints(resolved); | ||
| if (normalized.length > 0) { | ||
| this.rememberProviderHints(cidString, normalized); | ||
| } | ||
| return normalized; | ||
| } catch { | ||
| return []; | ||
| } | ||
| } | ||
| async put( | ||
@@ -155,3 +280,9 @@ bytes: Uint8Array | { block: Block<any, any, any, any>; cid: string }, | ||
| } | ||
| return this.localStore!.put(bytes); | ||
| const cid = await this.localStore!.put(bytes); | ||
| try { | ||
| await this.options.onPut?.(cid); | ||
| } catch { | ||
| // ignore best-effort hooks | ||
| } | ||
| return cid; | ||
| } | ||
@@ -162,2 +293,3 @@ | ||
| } | ||
| async get( | ||
@@ -167,3 +299,2 @@ cid: string, | ||
| ): Promise<Uint8Array | undefined> { | ||
| const cidObject = cidifyString(cid); | ||
| let value = this.localStore | ||
@@ -175,13 +306,23 @@ ? await this.localStore.get(cid, options) | ||
| // try to get it remotelly | ||
| let remoteOptions = options?.remote === true ? {} : options?.remote; | ||
| const remoteOptions = options?.remote === true ? {} : options?.remote; | ||
| if (remoteOptions) { | ||
| const cidObject = cidifyString(cid); | ||
| value = await this._readFromPeers(cid, cidObject, remoteOptions); | ||
| if (remoteOptions?.replicate && value) { | ||
| await this.localStore!.put(value); | ||
| await this.put(value); | ||
| } | ||
| } | ||
| } | ||
| return value; | ||
| } | ||
| hintProviders(cid: string, providers: string[]) { | ||
| const cidString = stringifyCid(cid); | ||
| this.rememberProviderHints(cidString, providers); | ||
| this._events.dispatchEvent( | ||
| new CustomEvent("providers:hints", { detail: { cid: cidString } }), | ||
| ); | ||
| } | ||
| async rm(cid: string) { | ||
@@ -223,3 +364,3 @@ await this.localStore?.rm(cid); | ||
| const cid = stringifyCid(request.cid); | ||
| const bytes = await this.localStore.get(cid, { | ||
| let bytes = await this.localStore.get(cid, { | ||
| remote: { | ||
@@ -231,4 +372,36 @@ timeout: localTimeout, | ||
| if (!bytes) { | ||
| return; | ||
| // Best-effort relay/proxy: if we don't have the block locally, try to fetch it | ||
| // from other reachable peers and then respond to the requester. | ||
| // | ||
| // This keeps multi-hop topologies working (e.g. A <-> relay <-> B) without | ||
| // requiring the requester to know an explicit `remote.from` provider set. | ||
| try { | ||
| const cidObject = cidifyString(cid); | ||
| const proxyTimeoutMs = Math.max(1_000, Math.floor(localTimeout) || 0); | ||
| const controller = new AbortController(); | ||
| const timer = setTimeout(() => controller.abort(), proxyTimeoutMs); | ||
| try { | ||
| const candidates = await this.resolveRemoteProviders(cid, { | ||
| signal: controller.signal, | ||
| }); | ||
| // Never bounce the request back to the requester; keep the fanout bounded. | ||
| const providers = candidates | ||
| .filter((p) => p && p !== from) | ||
| .slice(0, this.maxProviderHintsPerCid); | ||
| if (providers.length > 0) { | ||
| bytes = await this._readFromPeers(cid, cidObject, { | ||
| signal: controller.signal, | ||
| timeout: proxyTimeoutMs, | ||
| from: providers, | ||
| }); | ||
| } | ||
| } finally { | ||
| clearTimeout(timer); | ||
| } | ||
| } catch { | ||
| // ignore proxy failures | ||
| } | ||
| } | ||
| if (!bytes) return; | ||
| await this.options | ||
@@ -272,2 +445,19 @@ .publish(new BlockResponse(cid, bytes), { to: [from] }) | ||
| const explicitFrom = this.normalizeProviderHints(options.from); | ||
| let providers = | ||
| explicitFrom.length > 0 | ||
| ? explicitFrom | ||
| : await this.resolveRemoteProviders(cidString, { signal: options.signal }); | ||
| const canResolveLater = | ||
| explicitFrom.length === 0 && typeof this.options.resolveProviders === "function"; | ||
| if (providers.length === 0 && !canResolveLater) { | ||
| // Without an explicit provider set (or a resolver), we intentionally do not | ||
| // fall back to network-wide flooding. Scalable deployments must provide a | ||
| // discovery mechanism (program-level hints, DHT/tracker, etc). | ||
| return undefined; | ||
| } | ||
| if (explicitFrom.length > 0 && providers.length > 0) { | ||
| this.rememberProviderHints(cidString, providers); | ||
| } | ||
| let promise = this._readFromPeersPromises.get(cidString); | ||
@@ -277,10 +467,10 @@ if (!promise) { | ||
| (resolve, reject) => { | ||
| const timeoutCallback = setTimeout( | ||
| () => { | ||
| resolve(undefined); | ||
| }, | ||
| options.timeout || 30 * 1000, | ||
| ); | ||
| let timeoutCallback: ReturnType<typeof setTimeout> | undefined; | ||
| const abortHandler = () => { | ||
| clearTimeout(timeoutCallback); | ||
| cleanup(); | ||
| reject(new AbortError()); | ||
| }; | ||
| const cleanup = () => { | ||
| if (timeoutCallback) clearTimeout(timeoutCallback); | ||
| this._resolvers.delete(cidString); | ||
@@ -292,4 +482,9 @@ this.closeController.signal.removeEventListener( | ||
| options?.signal?.removeEventListener("abort", abortHandler); | ||
| reject(new AbortError()); | ||
| }; | ||
| timeoutCallback = setTimeout(() => { | ||
| cleanup(); | ||
| resolve(undefined); | ||
| }, options.timeout || 30 * 1000); | ||
| this.closeController.signal.addEventListener("abort", abortHandler); | ||
@@ -300,9 +495,3 @@ options?.signal?.addEventListener("abort", abortHandler); | ||
| const value = await tryDecode(bytes); | ||
| clearTimeout(timeoutCallback); | ||
| this._resolvers.delete(cidString); // TODO concurrency might not work as expected here | ||
| this.closeController.signal.removeEventListener( | ||
| "abort", | ||
| abortHandler, | ||
| ); | ||
| cleanup(); | ||
| resolve(value); | ||
@@ -315,29 +504,46 @@ }); | ||
| const publishOnNewPeers = (e: CustomEvent<PublicSignKey>) => { | ||
| const to = e.detail.hashcode(); | ||
| if (!options?.from || options.from.includes(to)) { | ||
| this.options | ||
| .publish(new BlockRequest(cidString), { | ||
| // We dont sent explicitly to 'to' here because we want the message to propagate beyond the first peer | ||
| to: [to], | ||
| mode: new AnyWhere(), | ||
| }) | ||
| .catch(dontThrowIfDeliveryError); | ||
| let requeryCount = 0; | ||
| const tryPublishRequest = async () => { | ||
| if (requeryCount >= this.maxRequeryOnReachable) return; | ||
| if (providers.length === 0) { | ||
| providers = await this.resolveRemoteProviders(cidString, { | ||
| signal: options.signal, | ||
| }); | ||
| } | ||
| if (providers.length === 0) return; | ||
| try { | ||
| await this.options.publish(new BlockRequest(cidString), { | ||
| mode: new SilentDelivery({ to: providers, redundancy: 1 }), | ||
| }); | ||
| requeryCount += 1; | ||
| } catch (e) { | ||
| dontThrowIfDeliveryError(e); | ||
| } | ||
| }; | ||
| this._events.addEventListener("peer:reachable", publishOnNewPeers); | ||
| await this.options.publish(new BlockRequest(cidString), { | ||
| mode: options.from | ||
| ? new SilentDelivery({ to: options.from, redundancy: 1 }) | ||
| : new AnyWhere(), | ||
| }); | ||
| // we want to make sure that if some new peers join, we also try to ask them | ||
| const publishOnNewPeers = () => { | ||
| // Re-issue when reachability changes to handle "get before connect". | ||
| // Bounded to avoid accidental amplification at large scale. | ||
| if (requeryCount >= this.maxRequeryOnReachable) return; | ||
| tryPublishRequest().catch(dontThrowIfDeliveryError); | ||
| }; | ||
| const result = await promise; | ||
| this._readFromPeersPromises.delete(cidString); | ||
| const publishOnProviderHints = (ev: CustomEvent<{ cid: string }>) => { | ||
| if (requeryCount >= this.maxRequeryOnReachable) return; | ||
| if (!ev?.detail?.cid) return; | ||
| if (ev.detail.cid !== cidString) return; | ||
| tryPublishRequest().catch(dontThrowIfDeliveryError); | ||
| }; | ||
| // stop asking new peers, because we already got an response | ||
| this._events.removeEventListener("peer:reachable", publishOnNewPeers); | ||
| return result?.bytes; | ||
| this._events.addEventListener("peer:reachable", publishOnNewPeers); | ||
| this._events.addEventListener("providers:hints", publishOnProviderHints); | ||
| try { | ||
| await tryPublishRequest(); | ||
| const result = await promise; | ||
| return result?.bytes; | ||
| } finally { | ||
| this._readFromPeersPromises.delete(cidString); | ||
| this._events.removeEventListener("peer:reachable", publishOnNewPeers); | ||
| this._events.removeEventListener("providers:hints", publishOnProviderHints); | ||
| } | ||
| } else { | ||
@@ -360,2 +566,3 @@ const result = await promise; | ||
| this._blockCache?.clear(); | ||
| this._providerCache?.clear(); | ||
| this._open = false; | ||
@@ -362,0 +569,0 @@ // we dont cleanup subscription because we dont know if someone else is sbuscribing also |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
124587
31.02%2007
37.28%1
Infinity%2
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated