@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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +665 -0
  3. package/dist/index.d.ts +1334 -0
  4. package/dist/index.js +2553 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +82 -0
  7. package/src/auth/client.ts +276 -0
  8. package/src/auth/index.ts +3 -0
  9. package/src/auth/types.ts +62 -0
  10. package/src/cache/client.ts +203 -0
  11. package/src/cache/index.ts +14 -0
  12. package/src/core/http.ts +541 -0
  13. package/src/core/index.ts +10 -0
  14. package/src/core/interfaces/IAuthStrategy.ts +28 -0
  15. package/src/core/interfaces/IHttpTransport.ts +73 -0
  16. package/src/core/interfaces/IRetryPolicy.ts +20 -0
  17. package/src/core/interfaces/IWebSocketClient.ts +60 -0
  18. package/src/core/interfaces/index.ts +4 -0
  19. package/src/core/transport/AuthHeaderStrategy.ts +108 -0
  20. package/src/core/transport/RequestLogger.ts +116 -0
  21. package/src/core/transport/RequestRetryPolicy.ts +53 -0
  22. package/src/core/transport/TLSConfiguration.ts +53 -0
  23. package/src/core/transport/index.ts +4 -0
  24. package/src/core/ws.ts +246 -0
  25. package/src/db/client.ts +126 -0
  26. package/src/db/index.ts +13 -0
  27. package/src/db/qb.ts +111 -0
  28. package/src/db/repository.ts +128 -0
  29. package/src/db/types.ts +67 -0
  30. package/src/errors.ts +38 -0
  31. package/src/functions/client.ts +62 -0
  32. package/src/functions/index.ts +2 -0
  33. package/src/functions/types.ts +21 -0
  34. package/src/index.ts +201 -0
  35. package/src/network/client.ts +119 -0
  36. package/src/network/index.ts +7 -0
  37. package/src/pubsub/client.ts +361 -0
  38. package/src/pubsub/index.ts +12 -0
  39. package/src/pubsub/types.ts +46 -0
  40. package/src/storage/client.ts +272 -0
  41. package/src/storage/index.ts +7 -0
  42. package/src/utils/codec.ts +68 -0
  43. package/src/utils/index.ts +3 -0
  44. package/src/utils/platform.ts +44 -0
  45. package/src/utils/retry.ts +58 -0
  46. package/src/vault/auth.ts +98 -0
  47. package/src/vault/client.ts +197 -0
  48. package/src/vault/crypto/aes.ts +271 -0
  49. package/src/vault/crypto/hkdf.ts +42 -0
  50. package/src/vault/crypto/index.ts +27 -0
  51. package/src/vault/crypto/shamir.ts +173 -0
  52. package/src/vault/index.ts +65 -0
  53. package/src/vault/quorum.ts +16 -0
  54. package/src/vault/transport/fanout.ts +94 -0
  55. package/src/vault/transport/guardian.ts +285 -0
  56. package/src/vault/transport/index.ts +19 -0
  57. package/src/vault/transport/types.ts +101 -0
  58. 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/).