@gethashd/bytecave-browser 1.0.1

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.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * ByteCave Browser Client
3
+ *
4
+ * WebRTC P2P client for connecting browsers directly to ByteCave storage nodes.
5
+ * No central gateway required - fully decentralized.
6
+ */
7
+ export declare const TEST_EXPORT = "ByteCave Browser Package v1.0.0";
8
+ export { ByteCaveClient } from './client.js';
9
+ export { ContractDiscovery } from './discovery.js';
10
+ export { p2pProtocolClient } from './p2p-protocols.js';
11
+ export { ByteCaveProvider, useByteCaveContext } from './provider.js';
12
+ export type { P2PHealthResponse, P2PInfoResponse } from './p2p-protocols.js';
13
+ export type { ByteCaveConfig, PeerInfo, StoreResult, RetrieveResult, ConnectionState } from './types.js';
14
+ export { parseHashdUrl, createHashdUrl, fetchHashdContent, prefetchHashdContent, clearHashdCache, getHashdCacheStats, revokeHashdUrl } from './protocol-handler.js';
15
+ export type { HashdUrl, FetchOptions, FetchResult } from './protocol-handler.js';
16
+ export { useHashdContent, useHashdImage, useHashdMedia, useHashdBatch } from './react/hooks.js';
17
+ export { HashdImage, HashdVideo, HashdAudio } from './react/components.js';
18
+ export { useHashdUrl } from './react/useHashdUrl.js';
package/dist/index.js ADDED
@@ -0,0 +1,50 @@
1
+ import {
2
+ ByteCaveClient,
3
+ ByteCaveProvider,
4
+ ContractDiscovery,
5
+ HashdAudio,
6
+ HashdImage,
7
+ HashdVideo,
8
+ p2pProtocolClient,
9
+ useByteCaveContext,
10
+ useHashdBatch,
11
+ useHashdContent,
12
+ useHashdImage,
13
+ useHashdMedia,
14
+ useHashdUrl
15
+ } from "./chunk-OJEETLZQ.js";
16
+ import {
17
+ clearHashdCache,
18
+ createHashdUrl,
19
+ fetchHashdContent,
20
+ getHashdCacheStats,
21
+ parseHashdUrl,
22
+ prefetchHashdContent,
23
+ revokeHashdUrl
24
+ } from "./chunk-EEZWRIUI.js";
25
+
26
+ // src/index.ts
27
+ var TEST_EXPORT = "ByteCave Browser Package v1.0.0";
28
+ export {
29
+ ByteCaveClient,
30
+ ByteCaveProvider,
31
+ ContractDiscovery,
32
+ HashdAudio,
33
+ HashdImage,
34
+ HashdVideo,
35
+ TEST_EXPORT,
36
+ clearHashdCache,
37
+ createHashdUrl,
38
+ fetchHashdContent,
39
+ getHashdCacheStats,
40
+ p2pProtocolClient,
41
+ parseHashdUrl,
42
+ prefetchHashdContent,
43
+ revokeHashdUrl,
44
+ useByteCaveContext,
45
+ useHashdBatch,
46
+ useHashdContent,
47
+ useHashdImage,
48
+ useHashdMedia,
49
+ useHashdUrl
50
+ };
@@ -0,0 +1,114 @@
1
+ /**
2
+ * ByteCave Browser - P2P Protocol Client
3
+ *
4
+ * Implements libp2p stream protocols for pure P2P communication from browser:
5
+ * - /bytecave/blob/1.0.0 - Blob storage and retrieval
6
+ * - /bytecave/health/1.0.0 - Health status
7
+ * - /bytecave/info/1.0.0 - Node info (for registration)
8
+ */
9
+ import { Libp2p } from 'libp2p';
10
+ export declare const PROTOCOL_BLOB = "/bytecave/blob/1.0.0";
11
+ export declare const PROTOCOL_HEALTH = "/bytecave/health/1.0.0";
12
+ export declare const PROTOCOL_INFO = "/bytecave/info/1.0.0";
13
+ export declare const PROTOCOL_PEER_DIRECTORY = "/bytecave/relay/peers/1.0.0";
14
+ export declare const PROTOCOL_HAVE_LIST = "/bytecave/have-list/1.0.0";
15
+ export interface BlobResponse {
16
+ success: boolean;
17
+ ciphertext?: string;
18
+ mimeType?: string;
19
+ error?: string;
20
+ }
21
+ export interface P2PHealthResponse {
22
+ peerId: string;
23
+ status: 'healthy' | 'degraded' | 'unhealthy';
24
+ blobCount: number;
25
+ storageUsed: number;
26
+ storageMax: number;
27
+ uptime: number;
28
+ version: string;
29
+ multiaddrs: string[];
30
+ nodeId?: string;
31
+ publicKey?: string;
32
+ ownerAddress?: string;
33
+ contentTypes?: string[] | 'all';
34
+ metrics?: {
35
+ requestsLastHour: number;
36
+ avgResponseTime: number;
37
+ successRate: number;
38
+ };
39
+ }
40
+ export interface P2PInfoResponse {
41
+ peerId: string;
42
+ publicKey: string;
43
+ ownerAddress?: string;
44
+ version: string;
45
+ contentTypes: string[] | 'all';
46
+ }
47
+ export interface PeerDirectoryResponse {
48
+ peers: Array<{
49
+ peerId: string;
50
+ multiaddrs: string[];
51
+ lastSeen: number;
52
+ }>;
53
+ timestamp: number;
54
+ }
55
+ export interface HaveListResponse {
56
+ cids: string[];
57
+ total: number;
58
+ hasMore: boolean;
59
+ }
60
+ export interface StoreRequest {
61
+ cid: string;
62
+ mimeType: string;
63
+ ciphertext: string;
64
+ appId?: string;
65
+ shouldVerifyOnChain?: boolean;
66
+ sender?: string;
67
+ timestamp?: number;
68
+ metadata?: Record<string, any>;
69
+ authorization?: any;
70
+ }
71
+ export interface StoreResponse {
72
+ success: boolean;
73
+ cid?: string;
74
+ error?: string;
75
+ }
76
+ /**
77
+ * P2P Protocol client for browser-to-node communication
78
+ */
79
+ export declare class P2PProtocolClient {
80
+ private node;
81
+ setNode(node: Libp2p): void;
82
+ /**
83
+ * Store a blob on a peer via P2P stream
84
+ */
85
+ storeToPeer(peerId: string, ciphertext: Uint8Array, mimeType: string, authorization?: any, shouldVerifyOnChain?: boolean): Promise<StoreResponse>;
86
+ /**
87
+ * Retrieve a blob from a peer via P2P stream
88
+ */
89
+ retrieveFromPeer(peerId: string, cid: string): Promise<{
90
+ data: Uint8Array;
91
+ mimeType: string;
92
+ } | null>;
93
+ /**
94
+ * Get health info from a peer via P2P stream
95
+ */
96
+ getHealthFromPeer(peerId: string): Promise<P2PHealthResponse | null>;
97
+ /**
98
+ * Query relay for peer directory
99
+ */
100
+ getPeerDirectoryFromRelay(relayPeerId: string): Promise<PeerDirectoryResponse | null>;
101
+ /**
102
+ * Get node info from a peer via P2P stream (for registration)
103
+ */
104
+ getInfoFromPeer(peerId: string): Promise<P2PInfoResponse | null>;
105
+ /**
106
+ * Check if a peer has a specific CID
107
+ */
108
+ peerHasCid(peerId: string, cid: string): Promise<boolean>;
109
+ private readMessage;
110
+ private writeMessage;
111
+ private uint8ArrayToBase64;
112
+ private base64ToUint8Array;
113
+ }
114
+ export declare const p2pProtocolClient: P2PProtocolClient;
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/protocol-handler.ts
21
+ var protocol_handler_exports = {};
22
+ __export(protocol_handler_exports, {
23
+ clearHashdCache: () => clearHashdCache,
24
+ createHashdUrl: () => createHashdUrl,
25
+ fetchHashdContent: () => fetchHashdContent,
26
+ getHashdCacheStats: () => getHashdCacheStats,
27
+ parseHashdUrl: () => parseHashdUrl,
28
+ prefetchHashdContent: () => prefetchHashdContent,
29
+ revokeHashdUrl: () => revokeHashdUrl
30
+ });
31
+ module.exports = __toCommonJS(protocol_handler_exports);
32
+ function parseHashdUrl(url) {
33
+ if (!url.startsWith("hashd://")) {
34
+ throw new Error(`Invalid hashd:// URL: ${url}`);
35
+ }
36
+ const withoutProtocol = url.slice(8);
37
+ const [cid, queryString] = withoutProtocol.split("?");
38
+ if (!cid || cid.length === 0) {
39
+ throw new Error(`Invalid hashd:// URL: missing CID`);
40
+ }
41
+ const result = {
42
+ protocol: "hashd:",
43
+ cid,
44
+ raw: url
45
+ };
46
+ if (queryString) {
47
+ const params = new URLSearchParams(queryString);
48
+ if (params.has("type")) {
49
+ result.mimeType = params.get("type");
50
+ }
51
+ if (params.has("decrypt")) {
52
+ result.decrypt = params.get("decrypt") === "true";
53
+ }
54
+ }
55
+ return result;
56
+ }
57
+ function createHashdUrl(cid, options) {
58
+ let url = `hashd://${cid}`;
59
+ if (options) {
60
+ const params = new URLSearchParams();
61
+ if (options.mimeType) {
62
+ params.set("type", options.mimeType);
63
+ }
64
+ if (options.decrypt !== void 0) {
65
+ params.set("decrypt", String(options.decrypt));
66
+ }
67
+ const queryString = params.toString();
68
+ if (queryString) {
69
+ url += `?${queryString}`;
70
+ }
71
+ }
72
+ return url;
73
+ }
74
+ var BlobUrlCache = class {
75
+ constructor() {
76
+ this.cache = /* @__PURE__ */ new Map();
77
+ this.maxAge = 60 * 60 * 1e3;
78
+ }
79
+ // 1 hour
80
+ set(cid, blobUrl, mimeType) {
81
+ this.cache.set(cid, { blobUrl, mimeType, timestamp: Date.now() });
82
+ }
83
+ get(cid) {
84
+ const entry = this.cache.get(cid);
85
+ if (!entry) {
86
+ return null;
87
+ }
88
+ if (Date.now() - entry.timestamp > this.maxAge) {
89
+ this.revoke(cid);
90
+ return null;
91
+ }
92
+ return { blobUrl: entry.blobUrl, mimeType: entry.mimeType };
93
+ }
94
+ revoke(cid) {
95
+ const entry = this.cache.get(cid);
96
+ if (entry) {
97
+ URL.revokeObjectURL(entry.blobUrl);
98
+ this.cache.delete(cid);
99
+ }
100
+ }
101
+ clear() {
102
+ for (const entry of this.cache.values()) {
103
+ URL.revokeObjectURL(entry.blobUrl);
104
+ }
105
+ this.cache.clear();
106
+ }
107
+ size() {
108
+ return this.cache.size;
109
+ }
110
+ };
111
+ var blobCache = new BlobUrlCache();
112
+ function detectMimeType(data) {
113
+ if (data.length < 4) {
114
+ return "application/octet-stream";
115
+ }
116
+ if (data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) {
117
+ return "image/png";
118
+ }
119
+ if (data[0] === 255 && data[1] === 216 && data[2] === 255) {
120
+ return "image/jpeg";
121
+ }
122
+ if (data[0] === 71 && data[1] === 73 && data[2] === 70) {
123
+ return "image/gif";
124
+ }
125
+ if (data[0] === 82 && data[1] === 73 && data[2] === 70 && data[3] === 70 && data[8] === 87 && data[9] === 69 && data[10] === 66 && data[11] === 80) {
126
+ return "image/webp";
127
+ }
128
+ if (data.length >= 12 && data[4] === 102 && data[5] === 116 && data[6] === 121 && data[7] === 112) {
129
+ return "video/mp4";
130
+ }
131
+ return "application/octet-stream";
132
+ }
133
+ async function fetchHashdContent(url, client, options) {
134
+ const parsed = typeof url === "string" ? parseHashdUrl(url) : url;
135
+ const cached = blobCache.get(parsed.cid);
136
+ if (cached) {
137
+ console.log(`[HashD] Cache hit for CID: ${parsed.cid.slice(0, 16)}...`);
138
+ return {
139
+ data: new Uint8Array(),
140
+ // Don't return data for cached items
141
+ mimeType: cached.mimeType,
142
+ blobUrl: cached.blobUrl,
143
+ cached: true
144
+ };
145
+ }
146
+ console.log(`[HashD] Fetching CID: ${parsed.cid.slice(0, 16)}...`);
147
+ const result = await client.retrieve(parsed.cid);
148
+ if (!result.success || !result.data) {
149
+ throw new Error(result.error || "Failed to retrieve content");
150
+ }
151
+ const mimeType = parsed.mimeType || detectMimeType(result.data);
152
+ const dataCopy = new Uint8Array(result.data);
153
+ const blob = new Blob([dataCopy], { type: mimeType });
154
+ const blobUrl = URL.createObjectURL(blob);
155
+ blobCache.set(parsed.cid, blobUrl, mimeType);
156
+ console.log(`[HashD] Retrieved and cached CID: ${parsed.cid.slice(0, 16)}... (${mimeType})`);
157
+ return {
158
+ data: result.data,
159
+ mimeType,
160
+ blobUrl,
161
+ cached: false
162
+ };
163
+ }
164
+ async function prefetchHashdContent(url, client) {
165
+ await fetchHashdContent(url, client);
166
+ }
167
+ function clearHashdCache() {
168
+ blobCache.clear();
169
+ }
170
+ function getHashdCacheStats() {
171
+ return { size: blobCache.size() };
172
+ }
173
+ function revokeHashdUrl(cid) {
174
+ blobCache.revoke(cid);
175
+ }
176
+ // Annotate the CommonJS export names for ESM import in node:
177
+ 0 && (module.exports = {
178
+ clearHashdCache,
179
+ createHashdUrl,
180
+ fetchHashdContent,
181
+ getHashdCacheStats,
182
+ parseHashdUrl,
183
+ prefetchHashdContent,
184
+ revokeHashdUrl
185
+ });
@@ -0,0 +1,57 @@
1
+ /**
2
+ * HashD Protocol Handler
3
+ *
4
+ * Handles hashd:// URLs for loading content from ByteCave network.
5
+ * Format: hashd://{cid}?type={mimeType}&decrypt={boolean}
6
+ */
7
+ import type { ByteCaveClient } from './client.js';
8
+ export interface HashdUrl {
9
+ protocol: 'hashd:';
10
+ cid: string;
11
+ mimeType?: string;
12
+ decrypt?: boolean;
13
+ raw: string;
14
+ }
15
+ export interface FetchOptions {
16
+ signal?: AbortSignal;
17
+ timeout?: number;
18
+ }
19
+ export interface FetchResult {
20
+ data: Uint8Array;
21
+ mimeType: string;
22
+ blobUrl: string;
23
+ cached: boolean;
24
+ }
25
+ /**
26
+ * Parse a hashd:// URL into its components
27
+ */
28
+ export declare function parseHashdUrl(url: string): HashdUrl;
29
+ /**
30
+ * Create a hashd:// URL from a CID and options
31
+ */
32
+ export declare function createHashdUrl(cid: string, options?: {
33
+ mimeType?: string;
34
+ decrypt?: boolean;
35
+ }): string;
36
+ /**
37
+ * Fetch content from ByteCave network using hashd:// URL
38
+ */
39
+ export declare function fetchHashdContent(url: string | HashdUrl, client: ByteCaveClient, options?: FetchOptions): Promise<FetchResult>;
40
+ /**
41
+ * Prefetch content and cache it
42
+ */
43
+ export declare function prefetchHashdContent(url: string | HashdUrl, client: ByteCaveClient): Promise<void>;
44
+ /**
45
+ * Clear the blob URL cache
46
+ */
47
+ export declare function clearHashdCache(): void;
48
+ /**
49
+ * Get cache statistics
50
+ */
51
+ export declare function getHashdCacheStats(): {
52
+ size: number;
53
+ };
54
+ /**
55
+ * Revoke a specific blob URL from cache
56
+ */
57
+ export declare function revokeHashdUrl(cid: string): void;
@@ -0,0 +1,18 @@
1
+ import {
2
+ clearHashdCache,
3
+ createHashdUrl,
4
+ fetchHashdContent,
5
+ getHashdCacheStats,
6
+ parseHashdUrl,
7
+ prefetchHashdContent,
8
+ revokeHashdUrl
9
+ } from "./chunk-EEZWRIUI.js";
10
+ export {
11
+ clearHashdCache,
12
+ createHashdUrl,
13
+ fetchHashdContent,
14
+ getHashdCacheStats,
15
+ parseHashdUrl,
16
+ prefetchHashdContent,
17
+ revokeHashdUrl
18
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * React Context Provider for ByteCave Client
3
+ *
4
+ * Provides P2P connectivity state and methods to React components
5
+ */
6
+ import React, { ReactNode } from 'react';
7
+ import type { PeerInfo, ConnectionState, StoreResult, RetrieveResult } from './types.js';
8
+ interface NodeHealth {
9
+ status: string;
10
+ blobCount: number;
11
+ storageUsed: number;
12
+ uptime: number;
13
+ nodeId?: string;
14
+ publicKey?: string;
15
+ secp256k1PublicKey?: string;
16
+ ownerAddress?: string;
17
+ metrics?: {
18
+ requestsLastHour: number;
19
+ avgResponseTime: number;
20
+ successRate: number;
21
+ };
22
+ integrity?: {
23
+ checked: number;
24
+ passed: number;
25
+ failed: number;
26
+ orphaned: number;
27
+ metadataTampered: number;
28
+ failedCids: string[];
29
+ };
30
+ }
31
+ interface ByteCaveContextValue {
32
+ connectionState: ConnectionState;
33
+ peers: PeerInfo[];
34
+ isConnected: boolean;
35
+ appId: string;
36
+ connect: () => Promise<void>;
37
+ disconnect: () => Promise<void>;
38
+ store: (data: Uint8Array, mimeType?: string, signer?: any) => Promise<StoreResult>;
39
+ retrieve: (cid: string) => Promise<RetrieveResult>;
40
+ registerContent: (cid: string, appId: string, signer: any) => Promise<{
41
+ success: boolean;
42
+ txHash?: string;
43
+ error?: string;
44
+ }>;
45
+ getNodeHealth: (peerId: string) => Promise<NodeHealth | null>;
46
+ error: string | null;
47
+ }
48
+ interface ByteCaveProviderProps {
49
+ children: ReactNode;
50
+ vaultNodeRegistryAddress: string;
51
+ contentRegistryAddress?: string;
52
+ rpcUrl: string;
53
+ appId: string;
54
+ relayPeers?: string[];
55
+ directNodeAddrs?: string[];
56
+ }
57
+ export declare function ByteCaveProvider({ children, vaultNodeRegistryAddress, contentRegistryAddress, rpcUrl, appId, relayPeers, directNodeAddrs }: ByteCaveProviderProps): React.JSX.Element;
58
+ export declare function useByteCaveContext(): ByteCaveContextValue;
59
+ export {};
@@ -0,0 +1,90 @@
1
+ /**
2
+ * React Components for HashD Protocol
3
+ *
4
+ * Drop-in components for loading content from ByteCave network
5
+ */
6
+ import React, { ImgHTMLAttributes, VideoHTMLAttributes, AudioHTMLAttributes } from 'react';
7
+ import { type UseHashdContentOptions } from './hooks.js';
8
+ export interface HashdImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src'> {
9
+ src: string;
10
+ client: UseHashdContentOptions['client'];
11
+ placeholder?: string;
12
+ loadingComponent?: React.ReactNode;
13
+ errorComponent?: React.ReactNode;
14
+ onHashdLoad?: () => void;
15
+ onHashdError?: (error: Error) => void;
16
+ }
17
+ /**
18
+ * Drop-in replacement for <img> that loads from hashd:// URLs
19
+ *
20
+ * @example
21
+ * <HashdImage
22
+ * src="hashd://abc123..."
23
+ * client={byteCaveClient}
24
+ * alt="Profile picture"
25
+ * className="w-32 h-32 rounded-full"
26
+ * />
27
+ */
28
+ export declare function HashdImage({ src, client, placeholder, loadingComponent, errorComponent, onHashdLoad, onHashdError, ...imgProps }: HashdImageProps): React.JSX.Element;
29
+ export interface HashdVideoProps extends Omit<VideoHTMLAttributes<HTMLVideoElement>, 'src'> {
30
+ src: string;
31
+ client: UseHashdContentOptions['client'];
32
+ loadingComponent?: React.ReactNode;
33
+ errorComponent?: React.ReactNode;
34
+ onHashdLoad?: () => void;
35
+ onHashdError?: (error: Error) => void;
36
+ }
37
+ /**
38
+ * Drop-in replacement for <video> that loads from hashd:// URLs
39
+ *
40
+ * @example
41
+ * <HashdVideo
42
+ * src="hashd://abc123..."
43
+ * client={byteCaveClient}
44
+ * controls
45
+ * className="w-full"
46
+ * />
47
+ */
48
+ export declare function HashdVideo({ src, client, loadingComponent, errorComponent, onHashdLoad, onHashdError, ...videoProps }: HashdVideoProps): React.JSX.Element;
49
+ export interface HashdAudioProps extends Omit<AudioHTMLAttributes<HTMLAudioElement>, 'src'> {
50
+ src: string;
51
+ client: UseHashdContentOptions['client'];
52
+ loadingComponent?: React.ReactNode;
53
+ errorComponent?: React.ReactNode;
54
+ onHashdLoad?: () => void;
55
+ onHashdError?: (error: Error) => void;
56
+ }
57
+ /**
58
+ * Drop-in replacement for <audio> that loads from hashd:// URLs
59
+ *
60
+ * @example
61
+ * <HashdAudio
62
+ * src="hashd://abc123..."
63
+ * client={byteCaveClient}
64
+ * controls
65
+ * />
66
+ */
67
+ export declare function HashdAudio({ src, client, loadingComponent, errorComponent, onHashdLoad, onHashdError, ...audioProps }: HashdAudioProps): React.JSX.Element;
68
+ export interface HashdContentProps {
69
+ url: string;
70
+ client: UseHashdContentOptions['client'];
71
+ children: (props: {
72
+ blobUrl: string | null;
73
+ loading: boolean;
74
+ error: Error | null;
75
+ mimeType: string | null;
76
+ }) => React.ReactNode;
77
+ }
78
+ /**
79
+ * Render prop component for custom content rendering
80
+ *
81
+ * @example
82
+ * <HashdContent url="hashd://abc123..." client={client}>
83
+ * {({ blobUrl, loading, error }) => {
84
+ * if (loading) return <Spinner />;
85
+ * if (error) return <Error message={error.message} />;
86
+ * return <img src={blobUrl} />;
87
+ * }}
88
+ * </HashdContent>
89
+ */
90
+ export declare function HashdContent({ url, client, children }: HashdContentProps): React.JSX.Element;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * React Hooks for HASHD Protocol
3
+ *
4
+ * Provides hooks for loading content from ByteCave network using hashd:// URLs
5
+ */
6
+ import type { ByteCaveClient } from '../client.js';
7
+ export interface UseHashdContentOptions {
8
+ client: ByteCaveClient | null;
9
+ enabled?: boolean;
10
+ onSuccess?: (blobUrl: string) => void;
11
+ onError?: (error: Error) => void;
12
+ }
13
+ export interface UseHashdContentResult {
14
+ blobUrl: string | null;
15
+ data: Uint8Array | null;
16
+ mimeType: string | null;
17
+ loading: boolean;
18
+ error: Error | null;
19
+ cached: boolean;
20
+ refetch: () => void;
21
+ }
22
+ /**
23
+ * Hook for loading content from hashd:// URLs
24
+ *
25
+ * @example
26
+ * const { blobUrl, loading, error } = useHashdContent('hashd://abc123...', { client });
27
+ * if (loading) return <Spinner />;
28
+ * if (error) return <Error message={error.message} />;
29
+ * return <img src={blobUrl} />;
30
+ */
31
+ export declare function useHashdContent(url: string | null | undefined, options: UseHashdContentOptions): UseHashdContentResult;
32
+ /**
33
+ * Hook specifically for loading images from hashd:// URLs
34
+ * Includes image-specific optimizations and error handling
35
+ *
36
+ * @example
37
+ * const { src, loading, error } = useHashdImage('hashd://abc123...', { client });
38
+ * return <img src={src || placeholderImage} alt="..." />;
39
+ */
40
+ export declare function useHashdImage(url: string | null | undefined, options: UseHashdContentOptions & {
41
+ placeholder?: string;
42
+ }): UseHashdContentResult & {
43
+ src: string;
44
+ };
45
+ /**
46
+ * Hook for loading video/audio content from hashd:// URLs
47
+ * Optimized for media playback
48
+ *
49
+ * @example
50
+ * const { src, loading } = useHashdMedia('hashd://abc123...', { client });
51
+ * return <video src={src} controls />;
52
+ */
53
+ export declare function useHashdMedia(url: string | null | undefined, options: UseHashdContentOptions): UseHashdContentResult & {
54
+ src: string;
55
+ };
56
+ /**
57
+ * Hook for batch loading multiple hashd:// URLs
58
+ * Useful for galleries or lists
59
+ *
60
+ * @example
61
+ * const { results, loading, errors } = useHashdBatch(urls, { client });
62
+ */
63
+ export declare function useHashdBatch(urls: (string | null | undefined)[], options: UseHashdContentOptions): {
64
+ results: Map<string, UseHashdContentResult>;
65
+ loading: boolean;
66
+ errors: Map<string, Error>;
67
+ };