@debros/orama 0.122.4-nightly
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/LICENSE +21 -0
- package/README.md +665 -0
- package/dist/index.d.ts +1334 -0
- package/dist/index.js +2553 -0
- package/dist/index.js.map +1 -0
- package/package.json +82 -0
- package/src/auth/client.ts +276 -0
- package/src/auth/index.ts +3 -0
- package/src/auth/types.ts +62 -0
- package/src/cache/client.ts +203 -0
- package/src/cache/index.ts +14 -0
- package/src/core/http.ts +541 -0
- package/src/core/index.ts +10 -0
- package/src/core/interfaces/IAuthStrategy.ts +28 -0
- package/src/core/interfaces/IHttpTransport.ts +73 -0
- package/src/core/interfaces/IRetryPolicy.ts +20 -0
- package/src/core/interfaces/IWebSocketClient.ts +60 -0
- package/src/core/interfaces/index.ts +4 -0
- package/src/core/transport/AuthHeaderStrategy.ts +108 -0
- package/src/core/transport/RequestLogger.ts +116 -0
- package/src/core/transport/RequestRetryPolicy.ts +53 -0
- package/src/core/transport/TLSConfiguration.ts +53 -0
- package/src/core/transport/index.ts +4 -0
- package/src/core/ws.ts +246 -0
- package/src/db/client.ts +126 -0
- package/src/db/index.ts +13 -0
- package/src/db/qb.ts +111 -0
- package/src/db/repository.ts +128 -0
- package/src/db/types.ts +67 -0
- package/src/errors.ts +38 -0
- package/src/functions/client.ts +62 -0
- package/src/functions/index.ts +2 -0
- package/src/functions/types.ts +21 -0
- package/src/index.ts +201 -0
- package/src/network/client.ts +119 -0
- package/src/network/index.ts +7 -0
- package/src/pubsub/client.ts +361 -0
- package/src/pubsub/index.ts +12 -0
- package/src/pubsub/types.ts +46 -0
- package/src/storage/client.ts +272 -0
- package/src/storage/index.ts +7 -0
- package/src/utils/codec.ts +68 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/platform.ts +44 -0
- package/src/utils/retry.ts +58 -0
- package/src/vault/auth.ts +98 -0
- package/src/vault/client.ts +197 -0
- package/src/vault/crypto/aes.ts +271 -0
- package/src/vault/crypto/hkdf.ts +42 -0
- package/src/vault/crypto/index.ts +27 -0
- package/src/vault/crypto/shamir.ts +173 -0
- package/src/vault/index.ts +65 -0
- package/src/vault/quorum.ts +16 -0
- package/src/vault/transport/fanout.ts +94 -0
- package/src/vault/transport/guardian.ts +285 -0
- package/src/vault/transport/index.ts +19 -0
- package/src/vault/transport/types.ts +101 -0
- package/src/vault/types.ts +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeBrosOfficial
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
# @debros/network-ts-sdk - TypeScript SDK for DeBros Network
|
|
2
|
+
|
|
3
|
+
A modern, isomorphic TypeScript SDK for the DeBros Network gateway. Works seamlessly in both Node.js and browser environments with support for database operations, pub/sub messaging, and network management.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Isomorphic**: Works in Node.js and browsers (uses fetch and isomorphic-ws)
|
|
8
|
+
- **Database ORM-like API**: QueryBuilder, Repository pattern, transactions
|
|
9
|
+
- **Pub/Sub Messaging**: WebSocket subscriptions with automatic reconnection
|
|
10
|
+
- **Authentication**: API key and JWT support with automatic token management
|
|
11
|
+
- **TypeScript First**: Full type safety and IntelliSense
|
|
12
|
+
- **Error Handling**: Unified SDKError with HTTP status and code
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @debros/network-ts-sdk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Initialize the Client
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { createClient } from "@debros/network-ts-sdk";
|
|
26
|
+
|
|
27
|
+
const client = createClient({
|
|
28
|
+
baseURL: "http://localhost:6001",
|
|
29
|
+
apiKey: "ak_your_api_key:namespace",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Or with JWT
|
|
33
|
+
const client = createClient({
|
|
34
|
+
baseURL: "http://localhost:6001",
|
|
35
|
+
jwt: "your_jwt_token",
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Database Operations
|
|
40
|
+
|
|
41
|
+
#### Create a Table
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
await client.db.createTable(
|
|
45
|
+
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### Insert Data
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const result = await client.db.exec(
|
|
53
|
+
"INSERT INTO users (name, email) VALUES (?, ?)",
|
|
54
|
+
["Alice", "alice@example.com"]
|
|
55
|
+
);
|
|
56
|
+
console.log(result.last_insert_id);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Query Data
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const users = await client.db.query("SELECT * FROM users WHERE email = ?", [
|
|
63
|
+
"alice@example.com",
|
|
64
|
+
]);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### Using QueryBuilder
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const activeUsers = await client.db
|
|
71
|
+
.createQueryBuilder("users")
|
|
72
|
+
.where("active = ?", [1])
|
|
73
|
+
.orderBy("name DESC")
|
|
74
|
+
.limit(10)
|
|
75
|
+
.getMany();
|
|
76
|
+
|
|
77
|
+
const firstUser = await client.db
|
|
78
|
+
.createQueryBuilder("users")
|
|
79
|
+
.where("id = ?", [1])
|
|
80
|
+
.getOne();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Using Repository Pattern
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface User {
|
|
87
|
+
id?: number;
|
|
88
|
+
name: string;
|
|
89
|
+
email: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const repo = client.db.repository<User>("users");
|
|
93
|
+
|
|
94
|
+
// Find
|
|
95
|
+
const users = await repo.find({ active: 1 });
|
|
96
|
+
const user = await repo.findOne({ email: "alice@example.com" });
|
|
97
|
+
|
|
98
|
+
// Save (INSERT or UPDATE)
|
|
99
|
+
const newUser: User = { name: "Bob", email: "bob@example.com" };
|
|
100
|
+
await repo.save(newUser);
|
|
101
|
+
|
|
102
|
+
// Remove
|
|
103
|
+
await repo.remove(newUser);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Transactions
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const results = await client.db.transaction([
|
|
110
|
+
{
|
|
111
|
+
kind: "exec",
|
|
112
|
+
sql: "INSERT INTO users (name, email) VALUES (?, ?)",
|
|
113
|
+
args: ["Charlie", "charlie@example.com"],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
kind: "query",
|
|
117
|
+
sql: "SELECT COUNT(*) as count FROM users",
|
|
118
|
+
args: [],
|
|
119
|
+
},
|
|
120
|
+
]);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Pub/Sub Messaging
|
|
124
|
+
|
|
125
|
+
The SDK provides a robust pub/sub client with:
|
|
126
|
+
|
|
127
|
+
- **Multi-subscriber support**: Multiple connections can subscribe to the same topic
|
|
128
|
+
- **Namespace isolation**: Topics are scoped to your authenticated namespace
|
|
129
|
+
- **Server timestamps**: Messages preserve server-side timestamps
|
|
130
|
+
- **Binary-safe**: Supports both string and binary (`Uint8Array`) payloads
|
|
131
|
+
- **Strict envelope validation**: Type-safe message parsing with error handling
|
|
132
|
+
|
|
133
|
+
#### Publish a Message
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Publish a string message
|
|
137
|
+
await client.pubsub.publish("notifications", "Hello, Network!");
|
|
138
|
+
|
|
139
|
+
// Publish binary data
|
|
140
|
+
const binaryData = new Uint8Array([1, 2, 3, 4]);
|
|
141
|
+
await client.pubsub.publish("binary-topic", binaryData);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Subscribe to Topics
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const subscription = await client.pubsub.subscribe("notifications", {
|
|
148
|
+
onMessage: (msg) => {
|
|
149
|
+
console.log("Topic:", msg.topic);
|
|
150
|
+
console.log("Data:", msg.data);
|
|
151
|
+
console.log("Server timestamp:", new Date(msg.timestamp));
|
|
152
|
+
},
|
|
153
|
+
onError: (err) => {
|
|
154
|
+
console.error("Subscription error:", err);
|
|
155
|
+
},
|
|
156
|
+
onClose: () => {
|
|
157
|
+
console.log("Subscription closed");
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Later, close the subscription
|
|
162
|
+
subscription.close();
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Message Interface:**
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
interface Message {
|
|
169
|
+
data: string; // Decoded message payload (string)
|
|
170
|
+
topic: string; // Topic name
|
|
171
|
+
timestamp: number; // Server timestamp in milliseconds
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### Debug Raw Envelopes
|
|
176
|
+
|
|
177
|
+
For debugging, you can inspect raw message envelopes before decoding:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const subscription = await client.pubsub.subscribe("notifications", {
|
|
181
|
+
onMessage: (msg) => {
|
|
182
|
+
console.log("Decoded message:", msg.data);
|
|
183
|
+
},
|
|
184
|
+
onRaw: (envelope) => {
|
|
185
|
+
console.log("Raw envelope:", envelope);
|
|
186
|
+
// { data: "base64...", timestamp: 1234567890, topic: "notifications" }
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### Multi-Subscriber Support
|
|
192
|
+
|
|
193
|
+
Multiple subscriptions to the same topic are supported. Each receives its own copy of messages:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// First subscriber
|
|
197
|
+
const sub1 = await client.pubsub.subscribe("events", {
|
|
198
|
+
onMessage: (msg) => console.log("Sub1:", msg.data),
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Second subscriber (both receive messages)
|
|
202
|
+
const sub2 = await client.pubsub.subscribe("events", {
|
|
203
|
+
onMessage: (msg) => console.log("Sub2:", msg.data),
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Unsubscribe independently
|
|
207
|
+
sub1.close(); // sub2 still active
|
|
208
|
+
sub2.close(); // fully unsubscribed
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### List Topics
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const topics = await client.pubsub.topics();
|
|
215
|
+
console.log("Active topics:", topics);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Presence Support
|
|
219
|
+
|
|
220
|
+
The SDK supports real-time presence tracking, allowing you to see who is currently subscribed to a topic.
|
|
221
|
+
|
|
222
|
+
#### Subscribe with Presence
|
|
223
|
+
|
|
224
|
+
Enable presence by providing `presence` options in `subscribe`:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const subscription = await client.pubsub.subscribe("room.123", {
|
|
228
|
+
onMessage: (msg) => console.log("Message:", msg.data),
|
|
229
|
+
presence: {
|
|
230
|
+
enabled: true,
|
|
231
|
+
memberId: "user-alice",
|
|
232
|
+
meta: { displayName: "Alice", avatar: "URL" },
|
|
233
|
+
onJoin: (member) => {
|
|
234
|
+
console.log(`${member.memberId} joined at ${new Date(member.joinedAt)}`);
|
|
235
|
+
console.log("Meta:", member.meta);
|
|
236
|
+
},
|
|
237
|
+
onLeave: (member) => {
|
|
238
|
+
console.log(`${member.memberId} left`);
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
#### Get Presence for a Topic
|
|
245
|
+
|
|
246
|
+
Query current members without subscribing:
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
const presence = await client.pubsub.getPresence("room.123");
|
|
250
|
+
console.log(`Total members: ${presence.count}`);
|
|
251
|
+
presence.members.forEach((member) => {
|
|
252
|
+
console.log(`- ${member.memberId} (joined: ${new Date(member.joinedAt)})`);
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### Subscription Helpers
|
|
257
|
+
|
|
258
|
+
Get presence information from an active subscription:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
if (subscription.hasPresence()) {
|
|
262
|
+
const members = await subscription.getPresence();
|
|
263
|
+
console.log("Current members:", members);
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Authentication
|
|
268
|
+
|
|
269
|
+
#### Switch API Key
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
client.auth.setApiKey("ak_new_key:namespace");
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
#### Switch JWT
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
client.auth.setJwt("new_jwt_token");
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### Get Current Token
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
const token = client.auth.getToken(); // Returns API key or JWT
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Get Authentication Info
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
const info = await client.auth.whoami();
|
|
291
|
+
console.log(info.authenticated, info.namespace);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
#### Logout
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
await client.auth.logout();
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Network Operations
|
|
301
|
+
|
|
302
|
+
#### Check Health
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
const healthy = await client.network.health();
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
#### Get Network Status
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
const status = await client.network.status();
|
|
312
|
+
console.log(status.healthy, status.peers);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### List Peers
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
const peers = await client.network.peers();
|
|
319
|
+
peers.forEach((peer) => {
|
|
320
|
+
console.log(peer.id, peer.addresses);
|
|
321
|
+
});
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
#### Proxy Requests Through Anyone Network
|
|
325
|
+
|
|
326
|
+
Make anonymous HTTP requests through the Anyone network:
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
// Simple GET request
|
|
330
|
+
const response = await client.network.proxyAnon({
|
|
331
|
+
url: "https://api.example.com/data",
|
|
332
|
+
method: "GET",
|
|
333
|
+
headers: {
|
|
334
|
+
Accept: "application/json",
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
console.log(response.status_code); // 200
|
|
339
|
+
console.log(response.body); // Response data as string
|
|
340
|
+
console.log(response.headers); // Response headers
|
|
341
|
+
|
|
342
|
+
// POST request with body
|
|
343
|
+
const postResponse = await client.network.proxyAnon({
|
|
344
|
+
url: "https://api.example.com/submit",
|
|
345
|
+
method: "POST",
|
|
346
|
+
headers: {
|
|
347
|
+
"Content-Type": "application/json",
|
|
348
|
+
},
|
|
349
|
+
body: JSON.stringify({ key: "value" }),
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// Parse JSON response
|
|
353
|
+
const data = JSON.parse(postResponse.body);
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Note:** The proxy endpoint requires authentication (API key or JWT) and only works when the Anyone relay is running on the gateway server.
|
|
357
|
+
|
|
358
|
+
## Configuration
|
|
359
|
+
|
|
360
|
+
### ClientConfig
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
interface ClientConfig {
|
|
364
|
+
baseURL: string; // Gateway URL
|
|
365
|
+
apiKey?: string; // API key (optional, if using JWT instead)
|
|
366
|
+
jwt?: string; // JWT token (optional, if using API key instead)
|
|
367
|
+
timeout?: number; // Request timeout in ms (default: 30000)
|
|
368
|
+
maxRetries?: number; // Max retry attempts (default: 3)
|
|
369
|
+
retryDelayMs?: number; // Delay between retries (default: 1000)
|
|
370
|
+
debug?: boolean; // Enable debug logging with full SQL queries (default: false)
|
|
371
|
+
storage?: StorageAdapter; // For persisting JWT/API key (default: MemoryStorage)
|
|
372
|
+
wsConfig?: Partial<WSClientConfig>; // WebSocket configuration
|
|
373
|
+
fetch?: typeof fetch; // Custom fetch implementation
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Storage Adapters
|
|
378
|
+
|
|
379
|
+
By default, credentials are stored in memory. For browser apps, use localStorage:
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
import { createClient, LocalStorageAdapter } from "@debros/network-ts-sdk";
|
|
383
|
+
|
|
384
|
+
const client = createClient({
|
|
385
|
+
baseURL: "http://localhost:6001",
|
|
386
|
+
storage: new LocalStorageAdapter(),
|
|
387
|
+
apiKey: "ak_your_key:namespace",
|
|
388
|
+
});
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Cache Operations
|
|
392
|
+
|
|
393
|
+
The SDK provides a distributed cache client backed by Olric. Data is organized into distributed maps (dmaps).
|
|
394
|
+
|
|
395
|
+
#### Put a Value
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// Put with optional TTL
|
|
399
|
+
await client.cache.put("sessions", "user:alice", { role: "admin" }, "1h");
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
#### Get a Value
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
// Returns null on cache miss (not an error)
|
|
406
|
+
const result = await client.cache.get("sessions", "user:alice");
|
|
407
|
+
if (result) {
|
|
408
|
+
console.log(result.value); // { role: "admin" }
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### Delete a Value
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
await client.cache.delete("sessions", "user:alice");
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### Multi-Get
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
const results = await client.cache.multiGet("sessions", [
|
|
422
|
+
"user:alice",
|
|
423
|
+
"user:bob",
|
|
424
|
+
]);
|
|
425
|
+
// Returns Map<string, any | null> — null for misses
|
|
426
|
+
results.forEach((value, key) => {
|
|
427
|
+
console.log(key, value);
|
|
428
|
+
});
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### Scan Keys
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// Scan all keys in a dmap, optionally matching a regex
|
|
435
|
+
const scan = await client.cache.scan("sessions", "user:.*");
|
|
436
|
+
console.log(scan.keys); // ["user:alice", "user:bob"]
|
|
437
|
+
console.log(scan.count); // 2
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
#### Health Check
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
const health = await client.cache.health();
|
|
444
|
+
console.log(health.status); // "ok"
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Storage (IPFS)
|
|
448
|
+
|
|
449
|
+
Upload, pin, and retrieve files from decentralized IPFS storage.
|
|
450
|
+
|
|
451
|
+
#### Upload a File
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
// Browser
|
|
455
|
+
const fileInput = document.querySelector('input[type="file"]');
|
|
456
|
+
const file = fileInput.files[0];
|
|
457
|
+
const result = await client.storage.upload(file, file.name);
|
|
458
|
+
console.log(result.cid); // "Qm..."
|
|
459
|
+
|
|
460
|
+
// Node.js
|
|
461
|
+
import { readFileSync } from "fs";
|
|
462
|
+
const buffer = readFileSync("image.jpg");
|
|
463
|
+
const result = await client.storage.upload(buffer, "image.jpg", { pin: true });
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
#### Retrieve Content
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Get as ReadableStream
|
|
470
|
+
const stream = await client.storage.get(cid);
|
|
471
|
+
const reader = stream.getReader();
|
|
472
|
+
while (true) {
|
|
473
|
+
const { done, value } = await reader.read();
|
|
474
|
+
if (done) break;
|
|
475
|
+
// Process chunk
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Get full Response (for headers like content-length)
|
|
479
|
+
const response = await client.storage.getBinary(cid);
|
|
480
|
+
const contentLength = response.headers.get("content-length");
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
#### Pin / Unpin / Status
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
// Pin an existing CID
|
|
487
|
+
await client.storage.pin("QmExampleCid", "my-file");
|
|
488
|
+
|
|
489
|
+
// Check pin status
|
|
490
|
+
const status = await client.storage.status("QmExampleCid");
|
|
491
|
+
console.log(status.status); // "pinned", "pinning", "queued", "unpinned", "error"
|
|
492
|
+
|
|
493
|
+
// Unpin
|
|
494
|
+
await client.storage.unpin("QmExampleCid");
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Serverless Functions (WASM)
|
|
498
|
+
|
|
499
|
+
Invoke WebAssembly serverless functions deployed on the network.
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
// Configure functions namespace
|
|
503
|
+
const client = createClient({
|
|
504
|
+
baseURL: "http://localhost:6001",
|
|
505
|
+
apiKey: "ak_your_key:namespace",
|
|
506
|
+
functionsConfig: {
|
|
507
|
+
namespace: "my-namespace",
|
|
508
|
+
},
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
// Invoke a function with typed input/output
|
|
512
|
+
interface PushInput {
|
|
513
|
+
token: string;
|
|
514
|
+
message: string;
|
|
515
|
+
}
|
|
516
|
+
interface PushOutput {
|
|
517
|
+
success: boolean;
|
|
518
|
+
messageId: string;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const result = await client.functions.invoke<PushInput, PushOutput>(
|
|
522
|
+
"send-push",
|
|
523
|
+
{ token: "device-token", message: "Hello!" }
|
|
524
|
+
);
|
|
525
|
+
console.log(result.messageId);
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Vault (Distributed Secrets)
|
|
529
|
+
|
|
530
|
+
The vault client provides Shamir-split secret storage across guardian nodes. Secrets are split into shares, distributed to guardians, and reconstructed only when enough shares are collected (quorum).
|
|
531
|
+
|
|
532
|
+
```typescript
|
|
533
|
+
const client = createClient({
|
|
534
|
+
baseURL: "http://localhost:6001",
|
|
535
|
+
apiKey: "ak_your_key:namespace",
|
|
536
|
+
vaultConfig: {
|
|
537
|
+
guardians: [
|
|
538
|
+
{ address: "10.0.0.1", port: 8443 },
|
|
539
|
+
{ address: "10.0.0.2", port: 8443 },
|
|
540
|
+
{ address: "10.0.0.3", port: 8443 },
|
|
541
|
+
],
|
|
542
|
+
identityHex: "your-identity-hex",
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
// Store a secret (Shamir-split across guardians)
|
|
547
|
+
const data = new TextEncoder().encode("my-secret-data");
|
|
548
|
+
const storeResult = await client.vault.store("api-key", data, 1);
|
|
549
|
+
console.log(storeResult.quorumMet); // true if enough guardians ACKed
|
|
550
|
+
|
|
551
|
+
// Retrieve and reconstruct a secret
|
|
552
|
+
const retrieved = await client.vault.retrieve("api-key");
|
|
553
|
+
console.log(new TextDecoder().decode(retrieved.data)); // "my-secret-data"
|
|
554
|
+
|
|
555
|
+
// List all secrets for this identity
|
|
556
|
+
const secrets = await client.vault.list();
|
|
557
|
+
console.log(secrets.secrets);
|
|
558
|
+
|
|
559
|
+
// Delete a secret from all guardians
|
|
560
|
+
await client.vault.delete("api-key");
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Wallet-Based Authentication
|
|
564
|
+
|
|
565
|
+
For wallet-based auth (challenge-response flow):
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
// 1. Request a challenge
|
|
569
|
+
const challenge = await client.auth.challenge();
|
|
570
|
+
|
|
571
|
+
// 2. Sign the challenge with your wallet (external)
|
|
572
|
+
const signature = await wallet.signMessage(challenge.message);
|
|
573
|
+
|
|
574
|
+
// 3. Verify signature and get JWT
|
|
575
|
+
const session = await client.auth.verify(challenge.id, signature);
|
|
576
|
+
console.log(session.token);
|
|
577
|
+
|
|
578
|
+
// 4. Get an API key for long-lived access
|
|
579
|
+
const apiKey = await client.auth.getApiKey();
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
## Error Handling
|
|
583
|
+
|
|
584
|
+
The SDK throws `SDKError` for all errors:
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
import { SDKError } from "@debros/network-ts-sdk";
|
|
588
|
+
|
|
589
|
+
try {
|
|
590
|
+
await client.db.query("SELECT * FROM nonexistent");
|
|
591
|
+
} catch (error) {
|
|
592
|
+
if (error instanceof SDKError) {
|
|
593
|
+
console.log(error.httpStatus); // e.g., 400
|
|
594
|
+
console.log(error.code); // e.g., "HTTP_400"
|
|
595
|
+
console.log(error.message); // Error message
|
|
596
|
+
console.log(error.details); // Full error response
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
## Browser Usage
|
|
602
|
+
|
|
603
|
+
The SDK works in browsers with minimal setup:
|
|
604
|
+
|
|
605
|
+
```typescript
|
|
606
|
+
// Browser example
|
|
607
|
+
import { createClient } from "@debros/network-ts-sdk";
|
|
608
|
+
|
|
609
|
+
const client = createClient({
|
|
610
|
+
baseURL: "https://gateway.example.com",
|
|
611
|
+
apiKey: "ak_browser_key:my-app",
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
// Use like any other API client
|
|
615
|
+
const data = await client.db.query("SELECT * FROM items");
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
**Note**: For WebSocket connections in browsers with authentication, ensure your gateway supports either header-based auth or query parameter auth.
|
|
619
|
+
|
|
620
|
+
## Testing
|
|
621
|
+
|
|
622
|
+
Run E2E tests against a running gateway:
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
# Set environment variables
|
|
626
|
+
export GATEWAY_BASE_URL=http://localhost:6001
|
|
627
|
+
export GATEWAY_API_KEY=ak_test_key:default
|
|
628
|
+
|
|
629
|
+
# Run tests
|
|
630
|
+
npm run test:e2e
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
## Examples
|
|
634
|
+
|
|
635
|
+
See the `tests/e2e/` directory for complete examples of:
|
|
636
|
+
|
|
637
|
+
- Authentication (`auth.test.ts`)
|
|
638
|
+
- Database operations (`db.test.ts`)
|
|
639
|
+
- Transactions (`tx.test.ts`)
|
|
640
|
+
- Pub/Sub messaging (`pubsub.test.ts`)
|
|
641
|
+
- Network operations (`network.test.ts`)
|
|
642
|
+
|
|
643
|
+
## Building
|
|
644
|
+
|
|
645
|
+
```bash
|
|
646
|
+
npm run build
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
Output goes to `dist/` with ESM and type declarations.
|
|
650
|
+
|
|
651
|
+
## Development
|
|
652
|
+
|
|
653
|
+
```bash
|
|
654
|
+
npm run dev # Watch mode
|
|
655
|
+
npm run typecheck # Type checking
|
|
656
|
+
npm run lint # Linting (if configured)
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
## License
|
|
660
|
+
|
|
661
|
+
MIT
|
|
662
|
+
|
|
663
|
+
## Support
|
|
664
|
+
|
|
665
|
+
For issues, questions, or contributions, please open an issue on GitHub or visit [DeBros Network Documentation](https://network.debros.io/docs/).
|