dolphin-server-modules 1.5.6 → 1.6.0

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.
@@ -1,60 +1,84 @@
1
- # Dolphin Framework: Absolute Master Guide (100+ Pages Equivalent) 🐬🇳🇵
2
-
3
- > **Latest Version:** v1.4.7+ | **Updated:** 2026-04-03 | **License:** MIT
1
+ Dolphin Framework: Absolute Master Guide (100+ Pages Equivalent) 🐬🇳🇵
2
+ Latest Version: v2.0 | Updated: 2026-04-05 | License: MIT
4
3
 
5
4
  यो डकुमेन्ट Dolphin Framework को आधिकारिक र विस्तृत गाइड हो। यसले तपाईँलाई एउटा साधारण कोड लेख्ने डेभलपरबाट "Framework Master" बनाउन मद्दत गर्नेछ।
6
5
 
7
- ---
8
-
9
- ## विषय सूची (Table of Contents)
10
-
11
- - [०. परिचय र दर्शन](#०-परिचय-र-दर्शन)
12
- - [१. सेटअप र वातावरण](#१-सेटअप-र-वातावरण)
13
- - [२. कोर सर्भर इन्जिन](#२-कोर-सर्भर-इन्जिन)
14
- - [३. Unified Context (ctx) Deep Dive](#३-unified-context-ctx-deep-dive)
15
- - [४. एडभान्स्ड राउटिङ](#४-एडभान्स्ड-राउटिङ)
16
- - [५. मिडलवेयर आर्किटेक्चर](#५-मिडलवेयर-आर्किटेक्चर)
17
- - [६. डेटाबेस एड्याप्टर](#६-डेटाबेस-एड्याप्टर)
18
- - [७. Auth मोड्युल मास्टरक्लास](#७-auth-मोड्युल-मास्टरक्लास)
19
- - [८. अटोमेटेड CRUD इन्जिन](#८-अटोमेटेड-crud-इन्जिन)
20
- - [९. Zod भ्यालिडेसन र सुरक्षा](#९-zod-भ्यालिडेसन-र-सुरक्षा)
21
- - [१०. रियल-वर्ल्ड प्रोजेक्ट: DolphinStore API](#१०-रियल-वर्ल्ड-प्रोजेक्ट-dolphinstore-api)
22
- - [११. स्केलिङ र पर्फर्मेन्स](#११-स्केलिङ-र-पर्फर्मेन्स)
23
- - [१२. टेस्टिङ र डेभप्स](#१२-टेस्टिङ-र-डेभप्स)
24
- - [१३. RealtimeCore: रियलटाइम पब/सब मास्टरक्लास](#१३-realtimecore-रियलटाइम-पबसब-मास्टरक्लास)
25
- - [१४. इन्डिपेन्डेन्ट राउटिङ](#१४-इन्डिपेन्डेन्ट-राउटिङ)
26
- - [१५. स्वतन्त्र अटो-स्वैगर जेनेरेसन](#१५-स्वतन्त्र-अटो-स्वैगर-जेनेरेसन)
27
- - [१६. API रेफरेन्स](#१६-api-रेफरेन्स)
28
-
29
- ---
30
-
31
- ## ०. परिचय र दर्शन (Introduction & Philosophy)
32
-
33
- ### Dolphin किन जन्मियो?
34
- ब्याकइन्ड डेभलपमेन्टको दुनियाँमा एक्सप्रेस (Express) सबैभन्दा लोकप्रिय छ। तर एक्सप्रेस पूरानो भइसक्यो। यसमा धेरै अनावश्यक वजन (Bloat) छ र यो मोडर्न एउटा (Modern) `async/await` सँग सधैँ राम्रोसँग काम गर्दैन।
35
-
36
- **Dolphin को जन्म तीनवटा मुख्य कारणले भएको हो:**
37
- 1. **Native Speed**: कुनै पनि बाहिरी लाइब्रेरी बिना नेटिभ `http` मा चल्ने।
38
- 2. **Context-First**: `req` `res` लाई एउटै 'Context' (ctx) मा मिलाएर कोडलाई सफा राख्ने।
39
- 3. **Total Modularity**: तपाईँले Auth चाहनुहुन्छ? Auth मोड्युल मात्र लोड गर्नुहोस्।
40
-
41
- ### पर्फर्मेन्स बेन्चमार्क
42
- | Framework | Requests Per Second (RPS) | Latency (avg) |
43
- | :--- | :--- | :--- |
44
- | Express.js | ~15,000 | 10ms |
45
- | Fastify | ~35,000 | 2ms |
46
- | **Dolphin (v1.4.7+)** | **~45,000+** | **1.5ms** |
47
-
48
- ---
49
-
50
- ## १. सेटअप वातावरण (Setup & Environment)
51
-
52
- ### १.१ आवश्यक चिजहरू (Prerequisites)
53
- - **Node.js**: v18.x वा सोभन्दा माथि
54
- - **TypeScript**: Dolphin टाइप-सेफ छ, त्यसैले TS सिफारिस गरिन्छ।
55
-
56
- ### १.२ प्रोजेक्ट सुरु गर्ने
57
- ```bash
6
+ विषय सूची (Table of Contents)
7
+ ०. परिचय र दर्शन
8
+
9
+ १. सेटअप र वातावरण
10
+
11
+ २. कोर सर्भर इन्जिन
12
+
13
+ ३. Unified Context (ctx) Deep Dive
14
+
15
+ ४. एडभान्स्ड राउटिङ
16
+
17
+ ५. मिडलवेयर आर्किटेक्चर
18
+
19
+ ६. डेटाबेस एड्याप्टर
20
+
21
+ ७. Auth मोड्युल मास्टरक्लास
22
+
23
+ ८. अटोमेटेड CRUD इन्जिन
24
+
25
+ ९. Zod भ्यालिडेसन सुरक्षा
26
+
27
+ १०. रियल-वर्ल्ड प्रोजेक्ट: DolphinStore API
28
+
29
+ ११. स्केलिङ र पर्फर्मेन्स
30
+
31
+ १२. टेस्टिङ र डेभप्स
32
+
33
+ १३. RealtimeCore v2.0: रियलटाइम पब/सब मास्टरक्लास (पूर्ण अपडेटेड)
34
+
35
+ १३.१ v2.0 का नयाँ फिचरहरू
36
+
37
+ १३.२ Device Management (डिभाइस व्यवस्थापन)
38
+
39
+ १३.३ High-Frequency Messaging (pubPush/subPull)
40
+
41
+ १३.४ File Transfer with Resume (pubFile/subFile)
42
+
43
+ १३.५ P2P Streaming
44
+
45
+ १३.६ Private Messaging
46
+
47
+ १३.७ Basic Pub/Sub (Retro-compatible)
48
+
49
+ १३.८ पूर्ण उदाहरण: हस्पिटल मोनिटरिङ सिस्टम
50
+
51
+ १४. इन्डिपेन्डेन्ट राउटिङ
52
+
53
+ १५. स्वतन्त्र अटो-स्वैगर जेनेरेसन
54
+
55
+ १६. API रेफरेन्स
56
+
57
+ ०. परिचय र दर्शन (Introduction & Philosophy)
58
+ Dolphin किन जन्मियो?
59
+ ब्याकइन्ड डेभलपमेन्टको दुनियाँमा एक्सप्रेस (Express) सबैभन्दा लोकप्रिय छ। तर एक्सप्रेस पूरानो भइसक्यो। यसमा धेरै अनावश्यक वजन (Bloat) छ र यो मोडर्न एउटा (Modern) async/await सँग सधैँ राम्रोसँग काम गर्दैन।
60
+
61
+ Dolphin को जन्म तीनवटा मुख्य कारणले भएको हो:
62
+
63
+ Native Speed: कुनै पनि बाहिरी लाइब्रेरी बिना नेटिभ http मा चल्ने।
64
+
65
+ Context-First: req र res लाई एउटै 'Context' (ctx) मा मिलाएर कोडलाई सफा राख्ने।
66
+
67
+ Total Modularity: तपाईँले Auth चाहनुहुन्छ? Auth मोड्युल मात्र लोड गर्नुहोस्।
68
+
69
+ पर्फर्मेन्स बेन्चमार्क
70
+ Framework Requests Per Second (RPS) Latency (avg)
71
+ Express.js ~15,000 10ms
72
+ Fastify ~35,000 2ms
73
+ Dolphin (v2.0) ~45,000+ 1.5ms
74
+ १. सेटअप र वातावरण (Setup & Environment)
75
+ १.१ आवश्यक चिजहरू (Prerequisites)
76
+ Node.js: v18.x वा सोभन्दा माथि
77
+
78
+ TypeScript: Dolphin टाइप-सेफ छ, त्यसैले TS सिफारिस गरिन्छ।
79
+
80
+ १.२ प्रोजेक्ट सुरु गर्ने
81
+ bash
58
82
  mkdir dolphin-master-app && cd dolphin-master-app
59
83
  npm init -y
60
84
  npm install dolphin-server-modules mongoose zod ioredis
@@ -107,7 +131,7 @@ ctx.status(code): HTTP स्टेटस कोड
107
131
 
108
132
  ctx.header(key, value): रेस्पोन्स हेडर
109
133
 
110
- ३.२ अटो-JSON रेस्पोन्स [v1.4.7]
134
+ ३.२ अटो-JSON रेस्पोन्स [v1.4.7+]
111
135
  typescript
112
136
  // पुरानो:
113
137
  app.get('/old', (ctx) => { ctx.json({ ok: true }); });
@@ -253,76 +277,49 @@ test('GET /test', async () => {
253
277
  const res = await request(app.server).get('/test');
254
278
  expect(res.body.ok).toBe(true);
255
279
  });
256
- १३. RealtimeCore: रियलटाइम पब/सब मास्टरक्लास (RealtimeCore)
280
+ १३. RealtimeCore v2.0: रियलटाइम पब/सब मास्टरक्लास (पूर्ण अपडेटेड)
281
+ ⚠️ महत्त्वपूर्ण: यो सेक्सन Dolphin Framework v2.0 को पूर्ण RealtimeCore अनुसार अपडेट गरिएको छ। तपाईंको Core मा pubPush, subPull, pubFile, subFile, Resume, P2P, Device Management जस्ता एडभान्स्ड फिचरहरू समावेश छन्।
282
+
257
283
  RealtimeCore Dolphin को उच्च-प्रदर्शन युनिफाइड पब/सब बस हो। यो IoT डिभाइसहरू, वेबसकेटहरू, र माइक्रोसर्भिसहरू बीच रियलटाइम डाटा संचारको लागि डिजाइन गरिएको छ।
258
284
 
259
- १३.१ RealtimeCore को मुख्य विशेषताहरू
260
- Feature Description
261
- TopicTrie O(L) समयमा टपिक म्याचिङ (वाइल्डकार्ड + स्ट्याटिक)
262
- Retained Messages अन्तिम मेसेज सम्झने क्षमता (MQTT जस्तै)
263
- Redis Bridge मल्टिपल सर्भरहरू बीच स्केलिङ
264
- DJSON Integration बाइनरी, हेक्स, बेस६४ डाटा अटो-डिकोड
265
- JSON Cache दोहोरिने पेलोडहरूको क्यासिङ (५ सेकेण्ड TTL)
266
- ACL Support डिभाइस-लेभल पब्लिस/सब्सक्राइब अनुमति
267
- Plugins System HL7, Modbus, MQTT जस्ता प्रोटोकलहरू थप्न
285
+ १३.१ v2.0 का नयाँ फिचरहरू
286
+ फिचर विवरण
287
+ pubPush / subPull अति उच्च गतिको डाटाको लागि (IoT Sensors, Live Graphs) - No JSON.stringify, No Redis
288
+ pubFile / subFile ठूला फाइलहरू टुक्रा-टुक्रा (64KB chunks) मा पठाउने - Resume Support सहित
289
+ resumeFile पहिले रोकिएको ठाउँबाट फाइल डाउनलोड पुनः सुरु गर्ने
290
+ Device Management isOnline(), isReady(), sendTo(), kick(), broadcastToGroup()
291
+ Private Messaging privateSub(), privatePub() - सुरक्षित संचार
292
+ P2P Streaming पीयर-टु-पीयर डाटा सेयरिङ
293
+ Auto Cleanup ६० सेकेन्ड इन्याक्टिभ डिभाइस आफै हट्छ
294
+ High-Freq Buffers प्रति टपिक १०० वटा मात्र बफर (Memory efficient)
268
295
  १३.२ स्थापना (Installation)
269
296
  bash
270
297
  npm install dolphin-server-modules ioredis
271
- १३.३ आधारभूत प्रयोग (Basic Usage)
298
+ १३.३ Device Management (डिभाइस व्यवस्थापन)
299
+ RealtimeCore v2.0 ले पूर्ण डिभाइस व्यवस्थापन क्षमता प्रदान गर्दछ:
300
+
272
301
  typescript
273
302
  import { RealtimeCore } from 'dolphin-server-modules/realtime';
274
303
 
275
- // RealtimeCore को इन्स्ट्यान्स बनाउने
276
304
  const rt = new RealtimeCore({
277
- maxMessageSize: 512 * 1024, // 512KB म्याक्स
278
- enableJSONCache: true, // JSON क्यास सक्षम
279
- debug: true, // डिबग लग
280
- useBinaryProtocol: false // बाइनरी प्रोटोकल प्रयोग
281
- });
282
-
283
- // टपिक सब्सक्राइब गर्ने (वाइल्डकार्ड + सपोर्ट)
284
- rt.subscribe('sensors/temperature/+', (payload) => {
285
- console.log(`तापक्रम डाटा: ${payload.value}°C`);
305
+ debug: true,
306
+ enableJSONCache: true
286
307
  });
287
308
 
288
- // टपिकमा पब्लिस गर्ने
289
- rt.publish('sensors/temperature/room1', { value: 23.5, unit: 'celsius' });
290
-
291
- // रिटेन्ड मेसेज (नयाँ सब्सक्राइबरले पाउने)
292
- rt.publish('config/system', { mode: 'active' }, { retain: true, ttl: 3600000 });
293
- १३.४ वाइल्डकार्ड म्याचिङ (Wildcard Matching)
294
- RealtimeCore ले MQTT-शैली वाइल्डकार्डहरू सपोर्ट गर्छ:
295
-
296
- typescript
297
- // + (सिङ्गल लेभल) - एउटा सेग्मेन्ट मात्र
298
- rt.subscribe('sensors/+/temperature', (data) => {
299
- // म्याच: sensors/room1/temperature, sensors/room2/temperature
300
- // म्याच गर्दैन: sensors/room1/floor2/temperature
301
- });
302
-
303
- // # (मल्टी लेभल) - सबै सेग्मेन्टहरू
304
- rt.subscribe('sensors/#', (data) => {
305
- // म्याच: sensors/temp, sensors/room1/humidity, sensors/building/floor/room/temp
306
- });
307
-
308
- // स्ट्याटिक टपिक (पूर्ण म्याच)
309
- rt.subscribe('device/online', (data) => {
310
- // केवल device/online मात्र
311
- });
312
- १३.५ डिभाइस रजिस्ट्रेसन र सकेट ह्यान्डलिङ (Device Registration)
313
- typescript
314
- // WebSocket कनेक्सन ह्यान्डल गर्ने (उदाहरण: ws लाइब्रेरीसँग)
309
+ // WebSocket सर्भरसँग integrate गर्ने
315
310
  import WebSocket from 'ws';
316
-
317
- const wss = new WebSocket.Server({ port: 8081 });
311
+ const wss = new WebSocket.Server({ port: 8080 });
318
312
 
319
313
  wss.on('connection', (ws, req) => {
320
314
  const deviceId = req.headers['device-id'] as string || `device-${Date.now()}`;
321
315
 
322
- // डिभाइस रजिस्टर गर्ने
323
- rt.register(deviceId, ws, { type: 'sensor', location: 'kathmandu' });
316
+ // डिभाइस रजिस्टर गर्ने (metadata सहित)
317
+ rt.register(deviceId, ws, {
318
+ type: 'sensor',
319
+ location: 'kathmandu',
320
+ group: 'temperature-sensors'
321
+ });
324
322
 
325
- // मेसेज ह्यान्डल गर्ने
326
323
  ws.on('message', async (data: Buffer) => {
327
324
  await rt.handle(data, ws, deviceId);
328
325
  });
@@ -332,33 +329,124 @@ wss.on('connection', (ws, req) => {
332
329
  });
333
330
  });
334
331
 
335
- // सिग्नलिङ टपिकहरू अटोम्याटिक रूपमा बन्छन्:
336
- // - phone/signaling/{deviceId} → डिभाइस-स्पेसिफिक
337
- // - phone/signaling/all सबै डिभाइसहरूमा ब्रोडकास्ट
338
- १३.६ DJSON डाटा ह्यान्डलिङ (DJSON Data Handling)
339
- RealtimeCore ले djson मार्फत बाइनरी, हेक्स, र बेस६४ डाटा अटो-डिकोड गर्छ:
332
+ // डिभाइस अनलाइन कि छैन चेक गर्ने
333
+ console.log(rt.isOnline('device-123')); // true/false
334
+ console.log(rt.isReady('device-123')); // socket ready कि छैन
335
+
336
+ // डिभाइसलाई सिधै मेसेज पठाउने (बिना Pub/Sub)
337
+ rt.sendTo('device-123', { type: 'PING', message: 'Are you alive?' });
338
+
339
+ // खराब डिभाइसलाई किक गर्ने
340
+ rt.kick('bad-device', 'Unauthorized access detected');
341
+
342
+ // सबै अनलाइन डिभाइसको लिस्ट
343
+ const devices = rt.getOnlineDevices();
344
+ // Output: [{ id: 'device-123', lastSeen: 123456, group: 'temperature-sensors' }]
345
+
346
+ // कुनै विशेष ग्रुपलाई मात्र ब्रोडकास्ट
347
+ rt.broadcastToGroup('temperature-sensors', { command: 'read_temperature' });
348
+
349
+ // डिभाइसलाई पिंग गर्ने
350
+ rt.ping('device-123');
351
+ १३.४ High-Frequency Messaging (pubPush/subPull)
352
+ IoT Sensors, Live Graphs, Real-time Stock Data को लागि अति छिटो messaging:
353
+
354
+ typescript
355
+ // सेन्सरबाट हाई-फ्रिक्वेन्सी डाटा पठाउने (pubPush)
356
+ // यो method ले JSON.stringify, ACL, Redis सबै बाइपास गर्छ
357
+ rt.pubPush('sensors/temperature/room1', Buffer.from([0x1A, 0x2B, 0x3C, 0x4D]));
358
+ rt.pubPush('sensors/humidity/room1', { value: 65.5, unit: '%' }); // Auto JSON
359
+
360
+ // क्लाइन्टले डाटा मागेपछि मात्र पाउने (subPull) - Data Saving
361
+ // क्लाइन्टले माग्दा पछिल्लो 10 वटा डाटा पाउँछ
362
+ rt.subPull('device-123', 'sensors/temperature/room1', 10);
363
+
364
+ // pubPush डाटा अटोम्याटिक बफरमा सेभ हुन्छ
365
+ // subPull ले बफरबाट पछिल्लो डाटा निकाल्छ
366
+ १३.५ File Transfer with Resume (pubFile/subFile)
367
+ ठूला फाइलहरू टुक्रा-टुक्रा गरेर पठाउने। रिज्युम सपोर्ट सहित:
368
+
369
+ typescript
370
+ // सर्भरले फाइल पब्लिस गर्ने तयारी (pubFile)
371
+ const fileId = 'patient-report-123';
372
+ const metadata = rt.pubFile(fileId, '/path/to/patient-report.pdf', 64 * 1024); // 64KB chunks
373
+
374
+ if (metadata) {
375
+ console.log(`File registered: ${metadata.name}, Total chunks: ${metadata.totalChunks}`);
376
+ }
377
+
378
+ // क्लाइन्टले फाइल डाउनलोड गर्ने (subFile)
379
+ // startChunk = 0 भनेको सुरुदेखि नै डाउनलोड गर्ने
380
+ await rt.subFile('device-123', fileId, 0);
381
+
382
+ // Resume: पहिले रोकिएको ठाउँबाट पुनः सुरु गर्ने
383
+ const lastChunk = rt.getFileProgress('device-123', fileId);
384
+ if (lastChunk >= 0) {
385
+ console.log(`Resuming from chunk ${lastChunk + 1}`);
386
+ await rt.resumeFile('device-123', fileId);
387
+ }
388
+
389
+ // फाइलको जानकारी लिने
390
+ const fileInfo = rt.getFileInfo(fileId);
391
+ console.log(`File: ${fileInfo?.name}, Size: ${fileInfo?.size} bytes`);
392
+
393
+ // सबै उपलब्ध फाइलहरूको सूची
394
+ const files = rt.listFiles();
395
+ १३.६ P2P Streaming
396
+ सर्भर मार्फत पीयरहरू बीच सिधै डाटा सेयरिङ:
397
+
398
+ typescript
399
+ // फाइलको उपलब्धता सबै पीयरलाई जानकारी दिने
400
+ rt.announceToPeers('file-123', 'device-A');
401
+
402
+ // फाइल कुन-कुन पीयरसँग छ हेर्ने
403
+ const peers = rt.getPeersForFile('file-123');
404
+ console.log(`File available at: ${peers}`);
405
+
406
+ // पीयरबाट सिधै डाटा माग गर्ने
407
+ rt.requestFromPeer('device-B', 'device-A', 'file-123', 5); // chunk 5
408
+
409
+ // पीयरलाई सिधै डाटा पठाउने (Server Pass-through)
410
+ rt.sendToPeer('device-A', 'device-B', { chunk: 5, data: buffer });
411
+ १३.७ Private Messaging
412
+ सुरक्षित निजी संचारको लागि:
413
+
414
+ typescript
415
+ // क्लाइन्टले आफ्नो प्राइभेट च्यानल सुन्ने
416
+ rt.privateSub('device-123', (msg) => {
417
+ console.log('Private message received:', msg);
418
+ });
419
+
420
+ // कसैलाई प्राइभेट मेसेज पठाउने
421
+ rt.privatePub('device-456', { secret: 'data', action: 'alert' });
422
+
423
+ // नोट: privatePub ले `phone/signaling/{targetId}` टपिकमा publish गर्छ
424
+ १३.८ Basic Pub/Sub (Retro-compatible)
425
+ पुरानो MQTT-शैली pub/sub पनि काम गर्छ:
340
426
 
341
427
  typescript
342
- // क्लाइन्टबाट पठाइएको डाटा (विभिन्न फर्म्याटमा)
343
- // १. सामान्य JSON
344
- rt.handle(Buffer.from(JSON.stringify({
345
- topic: 'sensor/data',
346
- payload: { value: 42 }
347
- })));
348
-
349
- // २. बेस६४-इन्कोडेड JSON
350
- rt.handle(Buffer.from(JSON.stringify({
351
- raw: Buffer.from(JSON.stringify({ topic: 'test', payload: { x: 1 } })).toString('base64')
352
- })));
353
-
354
- // ३. हेक्स-इन्कोडेड डाटा
355
- rt.handle(Buffer.from(JSON.stringify({
356
- _type: 'hex',
357
- raw: '7b22746f706963223a2274657374222c227061796c6f6164223a7b7d7d'
358
- })));
359
-
360
- // सबै केसहरूमा RealtimeCore ले आफै डिकोड गरेर publish गर्छ
361
- १३.७ रेडिस स्केलिङ (Redis Scaling)
428
+ // टपिक सब्सक्राइब गर्ने (वाइल्डकार्ड सपोर्ट)
429
+ rt.subscribe('sensors/temperature/+', (payload, topic) => {
430
+ console.log(`Temperature data: ${payload.value}°C from ${topic}`);
431
+ });
432
+
433
+ // टपिकमा पब्लिस गर्ने
434
+ rt.publish('sensors/temperature/room1', { value: 23.5, unit: 'celsius' });
435
+
436
+ // रिटेन्ड मेसेज (नयाँ सब्सक्राइबरले पाउने)
437
+ rt.publish('config/system', { mode: 'active' }, { retain: true, ttl: 3600000 });
438
+
439
+ // वाइल्डकार्ड म्याचिङ
440
+ // + (सिङ्गल लेभल) - एउटा सेग्मेन्ट मात्र
441
+ rt.subscribe('sensors/+/temperature', (data) => {
442
+ // म्याच: sensors/room1/temperature, sensors/room2/temperature
443
+ });
444
+
445
+ // # (मल्टी लेभल) - सबै सेग्मेन्टहरू
446
+ rt.subscribe('sensors/#', (data) => {
447
+ // म्याच: sensors/temp, sensors/room1/humidity, sensors/building/floor/room/temp
448
+ });
449
+ १३.९ Redis Scaling
362
450
  एकाधिक सर्भरहरू बीच मेसेज सिंक गर्न:
363
451
 
364
452
  typescript
@@ -370,7 +458,7 @@ const rt2 = new RealtimeCore({ redisUrl: 'redis://localhost:6379' });
370
458
 
371
459
  // rt1 मा पब्लिस गरेको मेसेज rt2 मा पुग्छ
372
460
  rt1.publish('global/event', { message: 'Hello from Server 1' });
373
- १३.८ एसीएल (Access Control List)
461
+ १३.१० ACL (Access Control List)
374
462
  typescript
375
463
  const rt = new RealtimeCore({
376
464
  acl: {
@@ -385,7 +473,7 @@ const rt = new RealtimeCore({
385
473
  }
386
474
  }
387
475
  });
388
- १३.९ प्लगिन सिस्टम (Plugin System)
476
+ १३.११ प्लगिन सिस्टम (Plugin System)
389
477
  typescript
390
478
  import { RealtimePlugin, RealtimeContext } from 'dolphin-server-modules/plugins';
391
479
 
@@ -403,81 +491,279 @@ const mqttPlugin: RealtimePlugin = {
403
491
  };
404
492
 
405
493
  rt.use(mqttPlugin);
406
- १३.१० एपिआई रेफरेन्स (API Reference)
407
- Constructor Options
408
- typescript
409
- interface RealtimeCoreConfig {
410
- maxMessageSize?: number; // डिफल्ट: 256KB
411
- redisUrl?: string; // Redis URL (ऐच्छिक)
412
- acl?: { // Access Control
413
- canSubscribe: (deviceId, topic) => boolean;
414
- canPublish: (deviceId, topic) => boolean;
415
- };
416
- enableJSONCache?: boolean; // JSON क्यास सक्षम
417
- useBinaryProtocol?: boolean; // बाइनरी प्रोटोकल
418
- debug?: boolean; // डिबग मोड
419
- }
420
- Methods
421
- Method Description
422
- subscribe(topic, fn, deviceId?) टपिकमा सब्सक्राइब
423
- publish(topic, payload, opts?, deviceId?) टपिकमा पब्लिस
424
- handle(raw, socket?, deviceId?) कच्चा डाटा प्रोसेस
425
- broadcast(topic, payload, opts?) सबै डिभाइसमा पठाउने
426
- register(deviceId, socket?, metadata?) डिभाइस रजिस्टर
427
- unregister(deviceId) डिभाइस हटाउने
428
- use(plugin) प्लगिन थप्ने
429
- getStats() स्ट्याटिस्टिक्स
430
- destroy() सबै रिसोर्स क्लिनअप
431
- १३.११ पूर्ण उदाहरण: IoT Sensor Platform
494
+ १३.१२ पूर्ण उदाहरण: हस्पिटल मोनिटरिङ सिस्टम
495
+ यो उदाहरणले हस्पिटलमा Telephone System र Equipment Monitoring को लागि पूर्ण real-time solution देखाउँछ:
496
+
432
497
  typescript
433
- // iot-server.ts
498
+ // hospital-realtime.ts
434
499
  import { RealtimeCore } from 'dolphin-server-modules/realtime';
435
500
  import WebSocket from 'ws';
501
+ import mongoose from 'mongoose';
436
502
 
503
+ // MongoDB Schema
504
+ const TelephoneSchema = new mongoose.Schema({
505
+ deviceId: String, ip: String, extension: String,
506
+ status: { type: String, enum: ['idle', 'busy', 'offline', 'ringing'] },
507
+ busy: { isBusy: Boolean, occupiedBy: String, since: Date },
508
+ lastSeen: Date
509
+ });
510
+
511
+ const EquipmentSchema = new mongoose.Schema({
512
+ equipmentId: String, name: String, type: String,
513
+ status: { type: String, enum: ['online', 'offline', 'in_use', 'maintenance'] },
514
+ busy: { isBusy: Boolean, occupiedBy: String, since: Date },
515
+ patientInfo: { patientId: String, roomNo: String, bedNo: String },
516
+ lastSeen: Date
517
+ });
518
+
519
+ const Telephone = mongoose.model('Telephone', TelephoneSchema);
520
+ const Equipment = mongoose.model('Equipment', EquipmentSchema);
521
+
522
+ // RealtimeCore Setup
437
523
  const rt = new RealtimeCore({
438
524
  maxMessageSize: 1024 * 1024,
439
525
  enableJSONCache: true,
440
- debug: process.env.NODE_ENV === 'development'
526
+ debug: true
441
527
  });
442
528
 
443
- // तापक्रम डाटा प्रोसेसिङ
444
- rt.subscribe('sensors/+/temperature', (data) => {
445
- if (data.value > 40) {
446
- console.warn(`उच्च तापक्रम अलर्ट! ${data.value}°C`);
447
- rt.publish('alerts/high-temp', { value: data.value, timestamp: Date.now() });
529
+ // 1. Device Registration Handler
530
+ async function handleDeviceConnection(ws: WebSocket, deviceId: string, deviceType: string) {
531
+ rt.register(deviceId, ws, { type: deviceType, registeredAt: Date.now() });
532
+
533
+ // Send current status immediately
534
+ const status = await getCurrentStatus(deviceId, deviceType);
535
+ rt.sendTo(deviceId, { type: 'INIT_STATUS', data: status });
536
+
537
+ ws.on('message', async (data) => {
538
+ await rt.handle(data as Buffer, ws, deviceId);
539
+ await updateHeartbeat(deviceId, deviceType);
540
+ });
541
+
542
+ ws.on('close', () => {
543
+ rt.unregister(deviceId);
544
+ markDeviceOffline(deviceId, deviceType);
545
+ });
546
+ }
547
+
548
+ // 2. Telephone Status Update (Real-time)
549
+ rt.subscribe('telephone/+/status', async (data, topic) => {
550
+ const deviceId = topic.split('/')[1];
551
+ await Telephone.findOneAndUpdate(
552
+ { deviceId },
553
+ { status: data.status, lastSeen: new Date() }
554
+ );
555
+
556
+ // Broadcast to all monitoring clients
557
+ rt.broadcast('monitor/telephone/update', { deviceId, status: data.status });
558
+
559
+ // Special alert for busy
560
+ if (data.status === 'busy') {
561
+ rt.publish('alert/telephone/busy', { deviceId, callWith: data.callWith });
562
+ }
563
+ });
564
+
565
+ // 3. Equipment Reservation with Resume Support
566
+ rt.subscribe('equipment/reserve', async (data) => {
567
+ const { equipmentId, patientId, roomNo } = data;
568
+
569
+ const equipment = await Equipment.findOne({ equipmentId });
570
+ if (equipment?.busy?.isBusy) {
571
+ rt.sendTo(data.deviceId, {
572
+ type: 'RESERVE_FAILED',
573
+ reason: `Equipment busy with ${equipment.busy.occupiedBy}`
574
+ });
575
+ return;
448
576
  }
577
+
578
+ await Equipment.findOneAndUpdate(
579
+ { equipmentId },
580
+ {
581
+ 'busy.isBusy': true,
582
+ 'busy.occupiedBy': patientId,
583
+ 'busy.since': new Date(),
584
+ patientInfo: { patientId, roomNo },
585
+ status: 'in_use'
586
+ }
587
+ );
588
+
589
+ rt.publish(`equipment/${equipmentId}/reserved`, { patientId, roomNo });
590
+ rt.sendTo(data.deviceId, { type: 'RESERVE_SUCCESS', equipmentId });
449
591
  });
450
592
 
451
- // सबै सेन्सर डाटा लग गर्ने
452
- rt.subscribe('sensors/#', (data, topic) => {
453
- console.log(`[${new Date().toISOString()}] ${topic}:`, data);
593
+ // 4. File Transfer for Medical Reports
594
+ rt.subscribe('report/request', async (data) => {
595
+ const { patientId, reportType, deviceId } = data;
596
+ const reportPath = `/reports/${patientId}/${reportType}.pdf`;
597
+ const fileId = `report-${patientId}-${Date.now()}`;
598
+
599
+ const metadata = rt.pubFile(fileId, reportPath);
600
+ if (metadata) {
601
+ rt.sendTo(deviceId, {
602
+ type: 'REPORT_READY',
603
+ fileId,
604
+ name: metadata.name,
605
+ size: metadata.size,
606
+ totalChunks: metadata.totalChunks
607
+ });
608
+ }
454
609
  });
455
610
 
456
- // WebSocket सर्भर
457
- const wss = new WebSocket.Server({ port: 8080 });
611
+ // 5. Resume interrupted file download
612
+ rt.subscribe('report/resume', async (data) => {
613
+ const { fileId, deviceId } = data;
614
+ const lastChunk = rt.getFileProgress(deviceId, fileId);
615
+
616
+ if (lastChunk >= 0) {
617
+ await rt.resumeFile(deviceId, fileId);
618
+ rt.sendTo(deviceId, { type: 'RESUME_STARTED', fromChunk: lastChunk + 1 });
619
+ }
620
+ });
458
621
 
459
- wss.on('connection', (ws, req) => {
460
- const deviceId = new URL(req.url!, `http://${req.headers.host}`).searchParams.get('id')
461
- || `device-${Date.now()}`;
622
+ // 6. Heartbeat Monitor (Auto offline detection)
623
+ setInterval(async () => {
624
+ const timeout = new Date(Date.now() - 10000); // 10 seconds
625
+
626
+ const offlineTelephones = await Telephone.updateMany(
627
+ { lastSeen: { $lt: timeout }, status: { $ne: 'offline' } },
628
+ { status: 'offline' }
629
+ );
462
630
 
463
- rt.register(deviceId, ws, { ip: req.socket.remoteAddress });
631
+ const offlineEquipment = await Equipment.updateMany(
632
+ { lastSeen: { $lt: timeout }, status: { $ne: 'offline' } },
633
+ { status: 'offline' }
634
+ );
464
635
 
465
- ws.on('message', (data) => rt.handle(data as Buffer, ws, deviceId));
466
- ws.on('close', () => rt.unregister(deviceId));
636
+ if (offlineTelephones.modifiedCount > 0 || offlineEquipment.modifiedCount > 0) {
637
+ rt.publish('alert/offline', {
638
+ telephones: offlineTelephones.modifiedCount,
639
+ equipment: offlineEquipment.modifiedCount,
640
+ timestamp: Date.now()
641
+ });
642
+ }
643
+ }, 5000);
644
+
645
+ // 7. Dashboard Stats (Real-time)
646
+ rt.subscribe('dashboard/stats', async (data, deviceId) => {
647
+ const [telephones, equipment] = await Promise.all([
648
+ Telephone.find(),
649
+ Equipment.find()
650
+ ]);
651
+
652
+ rt.sendTo(deviceId, {
653
+ type: 'DASHBOARD_STATS',
654
+ data: {
655
+ telephones: {
656
+ total: telephones.length,
657
+ busy: telephones.filter(t => t.status === 'busy').length,
658
+ offline: telephones.filter(t => t.status === 'offline').length
659
+ },
660
+ equipment: {
661
+ total: equipment.length,
662
+ inUse: equipment.filter(e => e.busy?.isBusy).length,
663
+ offline: equipment.filter(e => e.status === 'offline').length
664
+ },
665
+ timestamp: Date.now()
666
+ }
667
+ });
668
+ });
669
+
670
+ // Helper functions
671
+ async function updateHeartbeat(deviceId: string, type: string) {
672
+ const Model = type === 'telephone' ? Telephone : Equipment;
673
+ const idField = type === 'telephone' ? 'deviceId' : 'equipmentId';
674
+ await Model.findOneAndUpdate(
675
+ { [idField]: deviceId },
676
+ { lastSeen: new Date(), status: 'online' }
677
+ );
678
+ }
679
+
680
+ async function markDeviceOffline(deviceId: string, type: string) {
681
+ const Model = type === 'telephone' ? Telephone : Equipment;
682
+ const idField = type === 'telephone' ? 'deviceId' : 'equipmentId';
683
+ await Model.findOneAndUpdate(
684
+ { [idField]: deviceId },
685
+ { status: 'offline' }
686
+ );
687
+ }
688
+
689
+ async function getCurrentStatus(deviceId: string, type: string) {
690
+ const Model = type === 'telephone' ? Telephone : Equipment;
691
+ const idField = type === 'telephone' ? 'deviceId' : 'equipmentId';
692
+ return await Model.findOne({ [idField]: deviceId });
693
+ }
694
+
695
+ // Start WebSocket Server
696
+ const wss = new WebSocket.Server({ port: 8080 });
697
+ wss.on('connection', (ws, req) => {
698
+ const url = new URL(req.url!, `http://${req.headers.host}`);
699
+ const deviceId = url.searchParams.get('id')!;
700
+ const deviceType = url.searchParams.get('type')!; // 'telephone' or 'equipment'
701
+
702
+ handleDeviceConnection(ws, deviceId, deviceType);
467
703
  });
468
704
 
469
- // हेल्थ चेक एन्डपोइन्ट
470
- setInterval(() => {
471
- const stats = rt.getStats();
472
- console.log(`Realtime Stats: ${stats.devices} devices, ${stats.retained} retained`);
473
- }, 30000);
705
+ // Start HTTP Server with Dolphin
706
+ import { createDolphinServer } from 'dolphin-server-modules/server';
707
+ const app = createDolphinServer();
474
708
 
475
- process.on('SIGTERM', async () => {
476
- await rt.destroy();
477
- process.exit(0);
709
+ app.get('/stats', (ctx) => {
710
+ return rt.getStats();
478
711
  });
479
712
 
480
- console.log('IoT Platform running on ws://localhost:8080');
713
+ app.listen(3000, () => {
714
+ console.log('🏥 Hospital Realtime System Running');
715
+ console.log('📊 Stats:', rt.getStats());
716
+ });
717
+
718
+ console.log('Hospital Monitoring System Active! 🏥');
719
+ १३.१३ API रेफरेन्स (RealtimeCore v2.0)
720
+ Constructor Options:
721
+
722
+ typescript
723
+ interface RealtimeCoreConfig {
724
+ maxMessageSize?: number; // डिफल्ट: 256KB
725
+ redisUrl?: string; // Redis URL (ऐच्छिक)
726
+ acl?: { // Access Control
727
+ canSubscribe: (deviceId, topic) => boolean;
728
+ canPublish: (deviceId, topic) => boolean;
729
+ };
730
+ enableJSONCache?: boolean; // JSON क्यास सक्षम
731
+ useBinaryProtocol?: boolean; // बाइनरी प्रोटोकल
732
+ debug?: boolean; // डिबग मोड
733
+ maxBufferPerTopic?: number; // pubPush बफर साइज (डिफल्ट: 100)
734
+ defaultChunkSize?: number; // File chunk size (डिफल्ट: 64KB)
735
+ enableP2P?: boolean; // P2P सक्षम
736
+ }
737
+ Methods:
738
+
739
+ Method Description
740
+ subscribe(topic, fn, deviceId?) टपिकमा सब्सक्राइब
741
+ publish(topic, payload, opts?, deviceId?) टपिकमा पब्लिस
742
+ pubPush(topic, payload) हाई-फ्रिक्वेन्सी पब्लिस (No JSON)
743
+ subPull(deviceId, topic, count?) बफरबाट डाटा तान्ने
744
+ pubFile(fileId, filePath, chunkSize?) फाइल ट्रान्सफर तयारी
745
+ subFile(deviceId, fileId, startChunk?) फाइल डाउनलोड
746
+ resumeFile(deviceId, fileId) रोकिएको डाउनलोड पुनः सुरु
747
+ getFileProgress(deviceId, fileId) डाउनलोड प्रगति हेर्ने
748
+ listFiles() सबै उपलब्ध फाइलहरू
749
+ register(deviceId, socket?, metadata?) डिभाइस रजिस्टर
750
+ unregister(deviceId) डिभाइस हटाउने
751
+ isOnline(deviceId) डिभाइस अनलाइन छ कि छैन
752
+ isReady(deviceId) सकेट तयार छ कि छैन
753
+ sendTo(deviceId, payload) डिभाइसमा सिधै पठाउने
754
+ kick(deviceId, reason?) डिभाइस हटाउने
755
+ broadcastToGroup(groupName, payload) ग्रुपमा ब्रोडकास्ट
756
+ getOnlineDevices() सबै अनलाइन डिभाइस
757
+ ping(deviceId) डिभाइस पिंग गर्ने
758
+ privateSub(deviceId, fn) प्राइभेट च्यानल सुन्ने
759
+ privatePub(targetId, payload, opts?) प्राइभेट मेसेज पठाउने
760
+ announceToPeers(fileId, deviceId) P2P घोषणा
761
+ getPeersForFile(fileId) पीयर सूची
762
+ handle(raw, socket?, deviceId?) कच्चा डाटा प्रोसेस
763
+ broadcast(topic, payload, opts?) सबै डिभाइसमा पठाउने
764
+ use(plugin) प्लगिन थप्ने
765
+ getStats() स्ट्याटिस्टिक्स
766
+ destroy() सबै रिसोर्स क्लिनअप
481
767
  १४. इन्डिपेन्डेन्ट राउटिङ (Independent Routing)
482
768
  typescript
483
769
  // userRoutes.ts
@@ -532,40 +818,51 @@ app.listen(port, cb) सर्भर सुरु गर्ने
532
818
  app.get/patch/post/put/delete(path, ...handlers) HTTP मेथड
533
819
  app.use(path?, middleware/router) मिडलवेयर वा राउटर
534
820
  app.group(prefix, callback) रूट ग्रुपिङ
535
- RealtimeCore
821
+ RealtimeCore v2.0
536
822
  Method Description
537
823
  rt.subscribe(topic, fn, deviceId?) सब्सक्राइब
538
824
  rt.publish(topic, payload, opts?, deviceId?) पब्लिस
539
- rt.handle(raw, socket?, deviceId?) डाटा ह्यान्डल
825
+ rt.pubPush(topic, payload) हाई-फ्रिक्वेन्सी पब्लिस
826
+ rt.subPull(deviceId, topic, count?) बफरबाट तान्ने
827
+ rt.pubFile(fileId, filePath, chunkSize?) फाइल तयारी
828
+ rt.subFile(deviceId, fileId, startChunk?) फाइल डाउनलोड
829
+ rt.resumeFile(deviceId, fileId) डाउनलोड पुनः सुरु
540
830
  rt.register(deviceId, socket?, metadata?) डिभाइस रजिस्टर
831
+ rt.sendTo(deviceId, payload) सिधै पठाउने
832
+ rt.kick(deviceId, reason?) डिभाइस हटाउने
833
+ rt.privateSub(deviceId, fn) प्राइभेट सब्सक्राइब
834
+ rt.privatePub(targetId, payload, opts?) प्राइभेट पब्लिस
835
+ rt.getStats() स्ट्याटिस्टिक्स
541
836
  rt.destroy() क्लिनअप
542
- निष्कर्ष (Conclusion)
543
- बधाई छ! तपाईँले Dolphin Framework को Master Guide पूरा गर्नुभयो। अब तपाईँ:
837
+ १७. Universal Signaling (WebRTC & IoT)
838
+ Dolphin v1.6.0 बाट शून्य डिपेन्डेन्सी सहितको Universal Signaling Module आएको छ, जसले WebRTC र IoT Control लाई एउटै API मा ह्यान्डल गर्छ।
544
839
 
545
- ✅ हाई-पर्फर्मेन्स API सर्भर बनाउन
840
+ typescript
841
+ import { createSignaling } from 'dolphin-server-modules/signaling';
842
+ import { RealtimeCore } from 'dolphin-server-modules/realtime';
546
843
 
547
- अटोमेटेड CRUD भ्यालिडेसन प्रयोग गर्न
844
+ const rt = new RealtimeCore();
845
+ const signaling = createSignaling(rt);
548
846
 
549
- RealtimeCore सँग IoT रियलटाइम एप्लिकेसन बनाउन
847
+ // 1. WebRTC Call (For Phones/Apps)
848
+ await signaling.invite('user1', 'user2', { sdp: 'offer_data' });
550
849
 
551
- Redis सँग मल्टिपल सर्भर स्केल गर्न
850
+ // 2. IoT / Medical Command
851
+ await signaling.sendCommand('DoctorApp', 'Machine_01', { action: 'START' });
552
852
 
853
+ निष्कर्ष (Conclusion)
854
+ बधाई छ! तपाईँले Dolphin Framework v2.0 को Master Guide पूरा गर्नुभयो। अब तपाईँ:
855
+
856
+ ✅ हाई-पर्फर्मेन्स API सर्भर बनाउन
857
+ ✅ अटोमेटेड CRUD र भ्यालिडेसन प्रयोग गर्न
858
+ ✅ RealtimeCore v2.0 सँग पूर्ण रियलटाइम एप्लिकेसन बनाउन
859
+ ✅ pubPush/subPull सँग हाई-फ्रिक्वेन्सी डाटा ह्यान्डल गर्न
860
+ ✅ pubFile/subFile सँग ठूला फाइलहरू रिज्युम सपोर्ट सहित ट्रान्सफर गर्न
861
+ ✅ Device Management सँग डिभाइसहरू ट्र्याक गर्न
862
+ ✅ Redis सँग मल्टिपल सर्भर स्केल गर्न
553
863
  ✅ अटो-जेनेरेटेड Swagger डकुमेन्टेसन बनाउन
554
864
 
555
865
  सक्नुहुन्छ।
556
866
 
557
867
  Happy Coding! 🐬🇳🇵
558
- नेपालबाट विश्वस्तरको सफ्टवेयर बनाऔँ!
559
-
560
- text
561
-
562
- ## 📄 PDF कसरी बनाउने?
563
-
564
- ### विधि १: VS Code (सजिलो)
565
- 1. माथिको कोडलाई `dolphin-master-guide.md` मा सेभ गर्नुहोस्
566
- 2. VS Code मा `Markdown PDF` एक्सटेन्सन इन्स्टल गर्नुहोस्
567
- 3. फाइलमा राइट क्लिक → `Markdown PDF: Export (pdf)`
568
-
569
- ### विधि २: कमान्ड लाइन (Pandoc)
570
- ```bash
571
- pandoc dolphin-master-guide.md -o dolphin-framework-guide.pdf --pdf-engine=xelatex -V geometry:margin=1in
868
+ नेपालबाट विश्वस्तरको सफ्टवेयर बनाऔँ!