oddsockets-nodejs 1.0.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.
@@ -0,0 +1,729 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Node.js SDK Examples - OddSockets</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
11
+ <style>
12
+ :root {
13
+ --color-bg: #fafafa;
14
+ --color-surface: #ffffff;
15
+ --color-border: #e5e7eb;
16
+ --color-text-primary: #111827;
17
+ --color-text-secondary: #6b7280;
18
+ --color-text-muted: #9ca3af;
19
+ --color-accent: #3b82f6;
20
+ --color-accent-light: #dbeafe;
21
+ --color-success: #10b981;
22
+ --color-warning: #f59e0b;
23
+ --spacing-xs: 0.25rem;
24
+ --spacing-sm: 0.5rem;
25
+ --spacing-md: 1rem;
26
+ --spacing-lg: 1.5rem;
27
+ --spacing-xl: 2rem;
28
+ --spacing-2xl: 3rem;
29
+ --border-radius: 8px;
30
+ --font-mono: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;
31
+ }
32
+
33
+ * {
34
+ margin: 0;
35
+ padding: 0;
36
+ box-sizing: border-box;
37
+ }
38
+
39
+ body {
40
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
41
+ line-height: 1.6;
42
+ color: var(--color-text-primary);
43
+ background: var(--color-bg);
44
+ font-size: 16px;
45
+ overflow-x: hidden;
46
+ }
47
+
48
+ .container {
49
+ width: 100%;
50
+ max-width: 1200px;
51
+ margin: 0 auto;
52
+ padding: var(--spacing-xl) var(--spacing-md);
53
+ }
54
+
55
+
56
+ .topheader {
57
+ text-align: center;
58
+ margin-bottom: 0.15rem;
59
+ }
60
+
61
+ .topheader h1 {
62
+ font-size: 2.5rem;
63
+ font-weight: 700;
64
+ color: #1a202c;
65
+ margin-bottom: 0.15rem;
66
+ }
67
+
68
+ .topheader p {
69
+ font-size: 1.125rem;
70
+ color: #718096;
71
+ max-width: 600px;
72
+ margin: 0 auto;
73
+ }
74
+
75
+ .logo {
76
+ padding-top: 5px;
77
+ padding-left: 25px;
78
+ font-size: 1.375rem;
79
+ font-weight: 600;
80
+ margin-bottom: 0.1rem;
81
+ display: flex;
82
+ align-items: center;
83
+ gap: 0.5rem;
84
+ }
85
+
86
+ .logo i {
87
+ font-size: 1.75rem;
88
+ }
89
+
90
+
91
+ .footer {
92
+ text-align: center;
93
+ padding: 2rem 0;
94
+ border-top: 1px solid #e2e8f0;
95
+ color: #718096;
96
+ font-size: 0.875rem;
97
+ }
98
+ .back-link {
99
+ display: inline-flex;
100
+ align-items: center;
101
+ color: var(--color-accent);
102
+ text-decoration: none;
103
+ font-weight: 500;
104
+ padding-top: 10px;
105
+ margin-bottom: 0px;
106
+ transition: color 0.2s ease;
107
+ }
108
+
109
+ .back-link:hover {
110
+ color: #2563eb;
111
+ }
112
+
113
+ .back-link i {
114
+ margin-right: var(--spacing-sm);
115
+ }
116
+
117
+ .header {
118
+ text-align: center;
119
+ margin-bottom: var(--spacing-2xl);
120
+ }
121
+
122
+ .header h1 {
123
+ font-size: 2.5rem;
124
+ font-weight: 700;
125
+ color: var(--color-text-primary);
126
+ margin-bottom: var(--spacing-sm);
127
+ }
128
+
129
+ .header p {
130
+ font-size: 1.125rem;
131
+ color: var(--color-text-secondary);
132
+ max-width: 600px;
133
+ margin: 0 auto var(--spacing-lg);
134
+ }
135
+
136
+ .demo-button {
137
+ display: inline-flex;
138
+ align-items: center;
139
+ gap: var(--spacing-sm);
140
+ background: var(--color-accent);
141
+ color: white;
142
+ text-decoration: none;
143
+ padding: var(--spacing-md) var(--spacing-xl);
144
+ border-radius: var(--border-radius);
145
+ font-weight: 500;
146
+ font-size: 1rem;
147
+ transition: background-color 0.2s ease;
148
+ }
149
+
150
+ .demo-button:hover {
151
+ background: #2563eb;
152
+ }
153
+
154
+ /* BULLETPROOF FLEXBOX LAYOUT */
155
+ .examples-container {
156
+ display: flex;
157
+ flex-wrap: wrap;
158
+ gap: var(--spacing-xl);
159
+ margin-bottom: var(--spacing-2xl);
160
+ }
161
+
162
+ .example-card {
163
+ flex: 1 1 100%;
164
+ min-width: 0;
165
+ background: var(--color-surface);
166
+ border: 1px solid var(--color-border);
167
+ border-radius: var(--border-radius);
168
+ padding: var(--spacing-xl);
169
+ transition: all 0.2s ease;
170
+ display: flex;
171
+ flex-direction: column;
172
+ }
173
+
174
+ /* 2 columns on larger screens */
175
+ @media (min-width: 768px) {
176
+ .example-card {
177
+ flex: 1 1 calc(50% - var(--spacing-xl) / 2);
178
+ max-width: calc(50% - var(--spacing-xl) / 2);
179
+ }
180
+ }
181
+
182
+ /* Single column on mobile */
183
+ @media (max-width: 767px) {
184
+ .example-card {
185
+ flex: 1 1 100%;
186
+ max-width: 100%;
187
+ }
188
+ }
189
+
190
+ .example-card:hover {
191
+ transform: translateY(-2px);
192
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
193
+ }
194
+
195
+ .example-header {
196
+ display: flex;
197
+ align-items: center;
198
+ gap: var(--spacing-sm);
199
+ margin-bottom: var(--spacing-md);
200
+ flex-wrap: wrap;
201
+ }
202
+
203
+ .example-icon {
204
+ width: 24px;
205
+ height: 24px;
206
+ color: var(--color-accent);
207
+ flex-shrink: 0;
208
+ }
209
+
210
+ .example-title {
211
+ font-size: 1.25rem;
212
+ font-weight: 600;
213
+ color: var(--color-text-primary);
214
+ flex-grow: 1;
215
+ }
216
+
217
+ .example-status {
218
+ padding: var(--spacing-xs) var(--spacing-sm);
219
+ border-radius: 9999px;
220
+ font-size: 0.75rem;
221
+ font-weight: 500;
222
+ flex-shrink: 0;
223
+ }
224
+
225
+ .status-available {
226
+ background: #dcfce7;
227
+ color: #166534;
228
+ }
229
+
230
+ .status-coming-soon {
231
+ background: #fef3c7;
232
+ color: #92400e;
233
+ }
234
+
235
+ .example-description {
236
+ color: var(--color-text-secondary);
237
+ margin-bottom: var(--spacing-lg);
238
+ font-size: 0.875rem;
239
+ flex-grow: 1;
240
+ }
241
+
242
+ .code-block {
243
+ background: #1e293b;
244
+ color: #e2e8f0;
245
+ padding: var(--spacing-lg);
246
+ border-radius: var(--border-radius);
247
+ font-family: var(--font-mono);
248
+ font-size: 0.875rem;
249
+ line-height: 1.5;
250
+ overflow-x: auto;
251
+ margin-bottom: var(--spacing-lg);
252
+ border: 1px solid #334155;
253
+ width: 100%;
254
+ }
255
+
256
+ .code-block::-webkit-scrollbar {
257
+ height: 6px;
258
+ }
259
+
260
+ .code-block::-webkit-scrollbar-track {
261
+ background: #334155;
262
+ }
263
+
264
+ .code-block::-webkit-scrollbar-thumb {
265
+ background: #64748b;
266
+ border-radius: 3px;
267
+ }
268
+
269
+ .example-actions {
270
+ display: flex;
271
+ gap: var(--spacing-sm);
272
+ flex-wrap: wrap;
273
+ margin-top: auto;
274
+ }
275
+
276
+ .btn {
277
+ padding: var(--spacing-sm) var(--spacing-md);
278
+ border-radius: var(--border-radius);
279
+ text-decoration: none;
280
+ font-size: 0.875rem;
281
+ font-weight: 500;
282
+ transition: all 0.2s ease;
283
+ border: none;
284
+ cursor: pointer;
285
+ display: inline-flex;
286
+ align-items: center;
287
+ gap: var(--spacing-xs);
288
+ flex: 1;
289
+ justify-content: center;
290
+ min-width: 0;
291
+ }
292
+
293
+ .btn-primary {
294
+ background: var(--color-accent);
295
+ color: white;
296
+ }
297
+
298
+ .btn-primary:hover:not(:disabled) {
299
+ background: #2563eb;
300
+ }
301
+
302
+ .btn-secondary {
303
+ background: var(--color-surface);
304
+ color: var(--color-text-secondary);
305
+ border: 1px solid var(--color-border);
306
+ }
307
+
308
+ .btn-secondary:hover:not(:disabled) {
309
+ background: var(--color-bg);
310
+ color: var(--color-text-primary);
311
+ }
312
+
313
+ .btn:disabled {
314
+ opacity: 0.5;
315
+ cursor: not-allowed;
316
+ }
317
+
318
+ /* Mobile Responsive Design */
319
+ @media (max-width: 767px) {
320
+ .container {
321
+ padding: var(--spacing-lg) var(--spacing-sm);
322
+ }
323
+
324
+ .header h1 {
325
+ font-size: 2rem;
326
+ }
327
+
328
+ .header p {
329
+ font-size: 1rem;
330
+ }
331
+
332
+ .examples-container {
333
+ gap: var(--spacing-lg);
334
+ }
335
+
336
+ .example-card {
337
+ padding: var(--spacing-lg);
338
+ }
339
+
340
+ .example-header {
341
+ flex-direction: column;
342
+ align-items: flex-start;
343
+ gap: var(--spacing-sm);
344
+ }
345
+
346
+ .example-status {
347
+ align-self: flex-end;
348
+ }
349
+
350
+ .example-actions {
351
+ flex-direction: column;
352
+ }
353
+
354
+ .btn {
355
+ flex: none;
356
+ width: 100%;
357
+ }
358
+ }
359
+
360
+ /* Very small screens */
361
+ @media (max-width: 480px) {
362
+ .container {
363
+ padding: var(--spacing-md) var(--spacing-xs);
364
+ }
365
+
366
+ .header h1 {
367
+ font-size: 1.75rem;
368
+ }
369
+
370
+ .example-card {
371
+ padding: var(--spacing-md);
372
+ }
373
+
374
+ .code-block {
375
+ padding: var(--spacing-md);
376
+ font-size: 0.8125rem;
377
+ }
378
+
379
+ .demo-button {
380
+ padding: var(--spacing-sm) var(--spacing-lg);
381
+ font-size: 0.875rem;
382
+ }
383
+ }
384
+
385
+ /* Prism Theme Override */
386
+ pre[class*="language-"] {
387
+ background: #1e293b !important;
388
+ color: #e2e8f0 !important;
389
+ margin: 0;
390
+ border-radius: var(--border-radius);
391
+ overflow-x: auto;
392
+ }
393
+
394
+ .token.comment { color: #64748b !important; }
395
+ .token.string { color: #22d3ee !important; }
396
+ .token.keyword { color: #a78bfa !important; }
397
+ .token.function { color: #fb7185 !important; }
398
+ .token.number { color: #fbbf24 !important; }
399
+ .token.operator { color: #e2e8f0 !important; }
400
+
401
+ /* Ensure no horizontal overflow */
402
+ .example-card,
403
+ .code-block,
404
+ .example-actions,
405
+ .btn {
406
+ max-width: 100%;
407
+ word-wrap: break-word;
408
+ }
409
+ </style>
410
+ </head>
411
+ <body>
412
+ <div class="container">
413
+
414
+
415
+ <div class="topheader">
416
+
417
+ <div class="logo">
418
+ <a href="/">
419
+ <img src="https://prodmedia.tyga.host/public/tyga.cloud/landing/oddsockets.com/oddsockets-logo-words-white-256.png" alt="OddSockets" class="logo">
420
+ </a>
421
+ </div>
422
+ </div>
423
+
424
+ <a href="../docs/index.html" class="back-link">
425
+ <i class="fas fa-arrow-left"></i>
426
+ Back to Documentation
427
+ </a>
428
+
429
+ <div class="header">
430
+ <h1>Node.js SDK Examples</h1>
431
+ <p>Real-world examples showing how to use the OddSockets Node.js SDK in server-side applications</p>
432
+ <a href="basic-usage.js" class="demo-button">
433
+ <i class="fas fa-download"></i>
434
+ Download Example Code
435
+ </a>
436
+ </div>
437
+
438
+ <div class="examples-container">
439
+ <!-- Basic Usage Example -->
440
+ <div class="example-card">
441
+ <div class="example-header">
442
+ <i class="fas fa-rocket example-icon"></i>
443
+ <div class="example-title">Basic Usage</div>
444
+ <span class="example-status status-available">Available</span>
445
+ </div>
446
+ <div class="example-description">
447
+ Simple example showing how to connect, subscribe to a channel, and publish messages using the core SDK functionality in Node.js.
448
+ </div>
449
+ <div class="code-block">
450
+ <pre><code class="language-javascript">const OddSockets = require('@oddsocketsai/nodejs-sdk');
451
+
452
+ const client = new OddSockets({
453
+ apiKey: 'ak_live_1234567890abcdef',
454
+ userId: 'server-user-123'
455
+ });
456
+
457
+ const channel = client.channel('my-channel');
458
+
459
+ // Subscribe to messages
460
+ await channel.subscribe((message) => {
461
+ console.log('Received:', message);
462
+ });
463
+
464
+ // Publish a message
465
+ await channel.publish({
466
+ text: 'Hello from Node.js server!',
467
+ timestamp: new Date().toISOString()
468
+ });</code></pre>
469
+ </div>
470
+ <div class="example-actions">
471
+ <a href="basic-usage.js" class="btn btn-primary">
472
+ <i class="fas fa-download"></i>
473
+ Download Code
474
+ </a>
475
+ <a href="../docs/index.html#quick-start" class="btn btn-secondary">
476
+ <i class="fas fa-book"></i>
477
+ View Docs
478
+ </a>
479
+ </div>
480
+ </div>
481
+
482
+ <!-- PubNub Migration Example -->
483
+ <div class="example-card">
484
+ <div class="example-header">
485
+ <i class="fas fa-sync-alt example-icon"></i>
486
+ <div class="example-title">PubNub Migration</div>
487
+ <span class="example-status status-available">Available</span>
488
+ </div>
489
+ <div class="example-description">
490
+ Drop-in replacement example showing how to migrate from PubNub to OddSockets with minimal code changes in Node.js applications.
491
+ </div>
492
+ <div class="code-block">
493
+ <pre><code class="language-javascript">// Replace PubNub with OddSockets
494
+ const { PubNubCompat } = require('@oddsocketsai/nodejs-sdk');
495
+
496
+ const pubnub = new PubNubCompat({
497
+ publishKey: 'ak_live_1234567890abcdef',
498
+ subscribeKey: 'ak_live_1234567890abcdef',
499
+ userId: 'server123'
500
+ });
501
+
502
+ // Same API as PubNub!
503
+ pubnub.addListener({
504
+ message: function(messageEvent) {
505
+ console.log('Message:', messageEvent.message);
506
+ }
507
+ });
508
+
509
+ pubnub.subscribe({
510
+ channels: ['server-channel']
511
+ });</code></pre>
512
+ </div>
513
+ <div class="example-actions">
514
+ <a href="basic-usage.js" class="btn btn-primary">
515
+ <i class="fas fa-download"></i>
516
+ Download Code
517
+ </a>
518
+ <a href="../docs/index.html#quick-start" class="btn btn-secondary">
519
+ <i class="fas fa-book"></i>
520
+ View Docs
521
+ </a>
522
+ </div>
523
+ </div>
524
+
525
+ <!-- Express.js Integration Example -->
526
+ <div class="example-card">
527
+ <div class="example-header">
528
+ <i class="fas fa-server example-icon"></i>
529
+ <div class="example-title">Express.js Integration</div>
530
+ <span class="example-status status-available">Available</span>
531
+ </div>
532
+ <div class="example-description">
533
+ Complete example showing how to integrate OddSockets with Express.js for building real-time APIs and webhooks.
534
+ </div>
535
+ <div class="code-block">
536
+ <pre><code class="language-javascript">const express = require('express');
537
+ const OddSockets = require('@oddsocketsai/nodejs-sdk');
538
+
539
+ const app = express();
540
+ app.use(express.json());
541
+
542
+ // Initialize OddSockets
543
+ const client = new OddSockets({
544
+ apiKey: 'ak_live_1234567890abcdef'
545
+ });
546
+
547
+ // API endpoint to send messages
548
+ app.post('/api/send-message', async (req, res) => {
549
+ try {
550
+ const { channel, message } = req.body;
551
+ const oddSocketsChannel = client.channel(channel);
552
+
553
+ const result = await oddSocketsChannel.publish(message);
554
+ res.json({ success: true, result });
555
+ } catch (error) {
556
+ res.status(500).json({ error: error.message });
557
+ }
558
+ });
559
+
560
+ app.listen(3000);</code></pre>
561
+ </div>
562
+ <div class="example-actions">
563
+ <a href="basic-usage.js" class="btn btn-primary">
564
+ <i class="fas fa-download"></i>
565
+ Download Code
566
+ </a>
567
+ <a href="../docs/index.html#quick-start" class="btn btn-secondary">
568
+ <i class="fas fa-book"></i>
569
+ View Docs
570
+ </a>
571
+ </div>
572
+ </div>
573
+
574
+ <!-- Production Deployment Example -->
575
+ <div class="example-card">
576
+ <div class="example-header">
577
+ <i class="fas fa-cloud example-icon"></i>
578
+ <div class="example-title">Production Deployment</div>
579
+ <span class="example-status status-available">Available</span>
580
+ </div>
581
+ <div class="example-description">
582
+ Production-ready configuration with error handling, graceful shutdown, and environment variable management.
583
+ </div>
584
+ <div class="code-block">
585
+ <pre><code class="language-javascript">const OddSockets = require('@oddsocketsai/nodejs-sdk');
586
+
587
+ const client = new OddSockets({
588
+ apiKey: process.env.ODDSOCKETS_API_KEY,
589
+ userId: process.env.ODDSOCKETS_USER_ID || 'server-prod',
590
+ options: {
591
+ transports: ['websocket'], // WebSocket only
592
+ timeout: 10000, // 10 second timeout
593
+ reconnection: true, // Enable auto-reconnection
594
+ reconnectionAttempts: 10, // More attempts in production
595
+ maxReconnectionAttempts: 50 // Higher limit for production
596
+ }
597
+ });
598
+
599
+ // Production error handling
600
+ client.on('error', (error) => {
601
+ console.error('OddSockets error:', error);
602
+ });
603
+
604
+ // Graceful shutdown
605
+ process.on('SIGTERM', () => {
606
+ console.log('Shutting down gracefully...');
607
+ client.disconnect();
608
+ process.exit(0);
609
+ });</code></pre>
610
+ </div>
611
+ <div class="example-actions">
612
+ <a href="basic-usage.js" class="btn btn-primary">
613
+ <i class="fas fa-download"></i>
614
+ Download Code
615
+ </a>
616
+ <a href="../docs/index.html#deployment" class="btn btn-secondary">
617
+ <i class="fas fa-book"></i>
618
+ View Docs
619
+ </a>
620
+ </div>
621
+ </div>
622
+
623
+ <!-- Bulk Operations Example -->
624
+ <div class="example-card">
625
+ <div class="example-header">
626
+ <i class="fas fa-layer-group example-icon"></i>
627
+ <div class="example-title">Bulk Operations</div>
628
+ <span class="example-status status-available">Available</span>
629
+ </div>
630
+ <div class="example-description">
631
+ Efficient bulk message publishing for high-throughput applications and batch processing scenarios.
632
+ </div>
633
+ <div class="code-block">
634
+ <pre><code class="language-javascript">const OddSockets = require('@oddsocketsai/nodejs-sdk');
635
+
636
+ const client = new OddSockets({
637
+ apiKey: 'ak_live_1234567890abcdef'
638
+ });
639
+
640
+ // Publish multiple messages at once
641
+ const results = await client.publishBulk([
642
+ { channel: 'notifications', message: 'User logged in' },
643
+ { channel: 'analytics', message: { event: 'page_view' } },
644
+ { channel: 'alerts', message: 'System status: OK' }
645
+ ]);
646
+
647
+ results.forEach((result, index) => {
648
+ if (result.success) {
649
+ console.log(`Message ${index + 1} published successfully`);
650
+ } else {
651
+ console.error(`Message ${index + 1} failed:`, result.error);
652
+ }
653
+ });</code></pre>
654
+ </div>
655
+ <div class="example-actions">
656
+ <a href="basic-usage.js" class="btn btn-primary">
657
+ <i class="fas fa-download"></i>
658
+ Download Code
659
+ </a>
660
+ <a href="../docs/index.html#quick-start" class="btn btn-secondary">
661
+ <i class="fas fa-book"></i>
662
+ View Docs
663
+ </a>
664
+ </div>
665
+ </div>
666
+
667
+ <!-- Docker Deployment Example -->
668
+ <div class="example-card">
669
+ <div class="example-header">
670
+ <i class="fab fa-docker example-icon"></i>
671
+ <div class="example-title">Docker Deployment</div>
672
+ <span class="example-status status-available">Available</span>
673
+ </div>
674
+ <div class="example-description">
675
+ Complete Docker setup with multi-stage builds, health checks, and container orchestration for scalable deployments.
676
+ </div>
677
+ <div class="code-block">
678
+ <pre><code class="language-dockerfile">FROM node:18-alpine
679
+
680
+ WORKDIR /app
681
+
682
+ # Copy package files
683
+ COPY package*.json ./
684
+
685
+ # Install dependencies
686
+ RUN npm ci --only=production
687
+
688
+ # Copy application code
689
+ COPY . .
690
+
691
+ # Health check
692
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
693
+ CMD node healthcheck.js || exit 1
694
+
695
+ # Expose port
696
+ EXPOSE 3000
697
+
698
+ # Start application
699
+ CMD ["node", "server.js"]</code></pre>
700
+ </div>
701
+ <div class="example-actions">
702
+ <a href="basic-usage.js" class="btn btn-primary">
703
+ <i class="fas fa-download"></i>
704
+ Download Code
705
+ </a>
706
+ <a href="../docs/index.html#deployment" class="btn btn-secondary">
707
+ <i class="fas fa-book"></i>
708
+ View Docs
709
+ </a>
710
+ </div>
711
+ </div>
712
+
713
+ </div>
714
+ </div>
715
+
716
+ <div class="footer">
717
+ <p>&copy; 2025 Tyga.Cloud Ltd. oddsockets.com is a division of Tyga.Cloud Ltd. All rights reserved.</p>
718
+ </div>
719
+
720
+ <script>
721
+ // Initialize Prism.js
722
+ document.addEventListener('DOMContentLoaded', function() {
723
+ if (typeof Prism !== 'undefined') {
724
+ Prism.highlightAll();
725
+ }
726
+ });
727
+ </script>
728
+ </body>
729
+ </html>