@kangwifi-pro/waliwa 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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +600 -0
  3. package/dist/advanced/features.d.ts +211 -0
  4. package/dist/advanced/features.d.ts.map +1 -0
  5. package/dist/advanced/features.js +671 -0
  6. package/dist/advanced/features.js.map +1 -0
  7. package/dist/auth/auth-state.d.ts +89 -0
  8. package/dist/auth/auth-state.d.ts.map +1 -0
  9. package/dist/auth/auth-state.js +330 -0
  10. package/dist/auth/auth-state.js.map +1 -0
  11. package/dist/auth/pairing-code.d.ts +78 -0
  12. package/dist/auth/pairing-code.d.ts.map +1 -0
  13. package/dist/auth/pairing-code.js +191 -0
  14. package/dist/auth/pairing-code.js.map +1 -0
  15. package/dist/auth/qr-code.d.ts +60 -0
  16. package/dist/auth/qr-code.d.ts.map +1 -0
  17. package/dist/auth/qr-code.js +151 -0
  18. package/dist/auth/qr-code.js.map +1 -0
  19. package/dist/calls/handler.d.ts +61 -0
  20. package/dist/calls/handler.d.ts.map +1 -0
  21. package/dist/calls/handler.js +117 -0
  22. package/dist/calls/handler.js.map +1 -0
  23. package/dist/core/binary.d.ts +74 -0
  24. package/dist/core/binary.d.ts.map +1 -0
  25. package/dist/core/binary.js +448 -0
  26. package/dist/core/binary.js.map +1 -0
  27. package/dist/core/crypto.d.ts +60 -0
  28. package/dist/core/crypto.d.ts.map +1 -0
  29. package/dist/core/crypto.js +170 -0
  30. package/dist/core/crypto.js.map +1 -0
  31. package/dist/core/noise.d.ts +106 -0
  32. package/dist/core/noise.d.ts.map +1 -0
  33. package/dist/core/noise.js +307 -0
  34. package/dist/core/noise.js.map +1 -0
  35. package/dist/events/emitter.d.ts +44 -0
  36. package/dist/events/emitter.d.ts.map +1 -0
  37. package/dist/events/emitter.js +79 -0
  38. package/dist/events/emitter.js.map +1 -0
  39. package/dist/features/index.d.ts +342 -0
  40. package/dist/features/index.d.ts.map +1 -0
  41. package/dist/features/index.js +755 -0
  42. package/dist/features/index.js.map +1 -0
  43. package/dist/fixes/index.d.ts +333 -0
  44. package/dist/fixes/index.d.ts.map +1 -0
  45. package/dist/fixes/index.js +762 -0
  46. package/dist/fixes/index.js.map +1 -0
  47. package/dist/groups/management.d.ts +86 -0
  48. package/dist/groups/management.d.ts.map +1 -0
  49. package/dist/groups/management.js +443 -0
  50. package/dist/groups/management.js.map +1 -0
  51. package/dist/index.d.ts +65 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +236 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/messages/media.d.ts +93 -0
  56. package/dist/messages/media.d.ts.map +1 -0
  57. package/dist/messages/media.js +252 -0
  58. package/dist/messages/media.js.map +1 -0
  59. package/dist/messages/message-encoder.d.ts +70 -0
  60. package/dist/messages/message-encoder.d.ts.map +1 -0
  61. package/dist/messages/message-encoder.js +453 -0
  62. package/dist/messages/message-encoder.js.map +1 -0
  63. package/dist/messages/send.d.ts +101 -0
  64. package/dist/messages/send.d.ts.map +1 -0
  65. package/dist/messages/send.js +409 -0
  66. package/dist/messages/send.js.map +1 -0
  67. package/dist/recovery/index.d.ts +125 -0
  68. package/dist/recovery/index.d.ts.map +1 -0
  69. package/dist/recovery/index.js +584 -0
  70. package/dist/recovery/index.js.map +1 -0
  71. package/dist/skdm/index.d.ts +220 -0
  72. package/dist/skdm/index.d.ts.map +1 -0
  73. package/dist/skdm/index.js +600 -0
  74. package/dist/skdm/index.js.map +1 -0
  75. package/dist/socket/hybrid.d.ts +118 -0
  76. package/dist/socket/hybrid.d.ts.map +1 -0
  77. package/dist/socket/hybrid.js +352 -0
  78. package/dist/socket/hybrid.js.map +1 -0
  79. package/dist/socket/wa-socket.d.ts +300 -0
  80. package/dist/socket/wa-socket.d.ts.map +1 -0
  81. package/dist/socket/wa-socket.js +1094 -0
  82. package/dist/socket/wa-socket.js.map +1 -0
  83. package/dist/socket/ws-socket.d.ts +96 -0
  84. package/dist/socket/ws-socket.d.ts.map +1 -0
  85. package/dist/socket/ws-socket.js +302 -0
  86. package/dist/socket/ws-socket.js.map +1 -0
  87. package/dist/types/index.d.ts +444 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/index.js +7 -0
  90. package/dist/types/index.js.map +1 -0
  91. package/dist/utils/jid.d.ts +46 -0
  92. package/dist/utils/jid.d.ts.map +1 -0
  93. package/dist/utils/jid.js +152 -0
  94. package/dist/utils/jid.js.map +1 -0
  95. package/dist/utils/logger.d.ts +45 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +79 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/retry.d.ts +43 -0
  100. package/dist/utils/retry.d.ts.map +1 -0
  101. package/dist/utils/retry.js +175 -0
  102. package/dist/utils/retry.js.map +1 -0
  103. package/docs/API.md +745 -0
  104. package/docs/ARCHITECTURE.md +307 -0
  105. package/docs/BAILEYS_FIXES.md +360 -0
  106. package/docs/FEATURES.md +532 -0
  107. package/docs/PROTOCOL.md +489 -0
  108. package/docs/RECOVERY.md +409 -0
  109. package/docs/SKDM.md +233 -0
  110. package/examples/ai-bot/index.ts +479 -0
  111. package/examples/ai-bot/package.json +17 -0
  112. package/examples/echo-bot/index.ts +171 -0
  113. package/examples/echo-bot/package.json +18 -0
  114. package/examples/group-bot/index.ts +557 -0
  115. package/examples/group-bot/package.json +17 -0
  116. package/examples/rest-gateway/index.ts +499 -0
  117. package/examples/rest-gateway/package.json +19 -0
  118. package/package.json +75 -0
  119. package/src/advanced/features.ts +817 -0
  120. package/src/auth/auth-state.ts +342 -0
  121. package/src/auth/pairing-code.ts +246 -0
  122. package/src/auth/qr-code.ts +191 -0
  123. package/src/calls/handler.ts +153 -0
  124. package/src/core/binary.ts +464 -0
  125. package/src/core/crypto.ts +189 -0
  126. package/src/core/noise.ts +406 -0
  127. package/src/events/emitter.ts +88 -0
  128. package/src/features/index.ts +921 -0
  129. package/src/fixes/index.ts +882 -0
  130. package/src/groups/management.ts +497 -0
  131. package/src/index.ts +274 -0
  132. package/src/messages/media.ts +372 -0
  133. package/src/messages/message-encoder.ts +520 -0
  134. package/src/messages/send.ts +521 -0
  135. package/src/recovery/index.ts +704 -0
  136. package/src/skdm/index.ts +693 -0
  137. package/src/socket/hybrid.ts +414 -0
  138. package/src/socket/wa-socket.ts +1347 -0
  139. package/src/socket/ws-socket.ts +355 -0
  140. package/src/types/index.ts +457 -0
  141. package/src/utils/jid.ts +156 -0
  142. package/src/utils/logger.ts +84 -0
  143. package/src/utils/retry.ts +205 -0
  144. package/tsconfig.json +30 -0
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Waliwa - Retry & throttle utilities
3
+ * Implementasi efficient untuk retry exponential backoff dan rate limiting
4
+ */
5
+
6
+ import { getRandomBytes } from '../core/crypto.js';
7
+
8
+ // ============== Retry ==============
9
+
10
+ export interface RetryOptions {
11
+ retries?: number;
12
+ minTimeout?: number;
13
+ maxTimeout?: number;
14
+ factor?: number;
15
+ randomize?: boolean;
16
+ onFailedAttempt?: (error: Error, attempt: number) => void;
17
+ }
18
+
19
+ /**
20
+ * Exponential backoff retry dengan jitter
21
+ */
22
+ export async function retry<T>(
23
+ fn: () => Promise<T>,
24
+ options: RetryOptions = {}
25
+ ): Promise<T> {
26
+ const {
27
+ retries = 5,
28
+ minTimeout = 500,
29
+ maxTimeout = 30000,
30
+ factor = 2,
31
+ randomize = true,
32
+ onFailedAttempt
33
+ } = options;
34
+
35
+ let attempt = 0;
36
+ let lastError: Error;
37
+
38
+ while (attempt <= retries) {
39
+ try {
40
+ return await fn();
41
+ } catch (err) {
42
+ lastError = err as Error;
43
+ attempt++;
44
+ if (attempt > retries) {
45
+ throw lastError;
46
+ }
47
+ if (onFailedAttempt) {
48
+ onFailedAttempt(lastError, attempt);
49
+ }
50
+ // Exponential backoff dengan jitter
51
+ let delay = minTimeout * Math.pow(factor, attempt - 1);
52
+ if (randomize) {
53
+ const jitter = (getRandomBytes(1)[0] / 255) * 0.3;
54
+ delay = delay * (1 + jitter);
55
+ }
56
+ delay = Math.min(delay, maxTimeout);
57
+ await sleep(delay);
58
+ }
59
+ }
60
+ throw lastError!;
61
+ }
62
+
63
+ export function sleep(ms: number): Promise<void> {
64
+ return new Promise(resolve => setTimeout(resolve, ms));
65
+ }
66
+
67
+ // ============== Throttle / Rate Limiter ==============
68
+
69
+ /**
70
+ * Token bucket rate limiter - RAM-efficient (single object per limiter)
71
+ */
72
+ export class RateLimiter {
73
+ private tokens: number;
74
+ private lastRefill: number;
75
+ private readonly maxTokens: number;
76
+ private readonly refillRate: number; // tokens per ms
77
+ private readonly queue: Array<{ resolve: () => void; reject: (err: Error) => void }> = [];
78
+ private processing: boolean = false;
79
+
80
+ constructor(maxTokensPerSecond: number) {
81
+ this.maxTokens = maxTokensPerSecond;
82
+ this.tokens = maxTokensPerSecond;
83
+ this.refillRate = maxTokensPerSecond / 1000;
84
+ this.lastRefill = Date.now();
85
+ }
86
+
87
+ private refill(): void {
88
+ const now = Date.now();
89
+ const elapsed = now - this.lastRefill;
90
+ this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate);
91
+ this.lastRefill = now;
92
+ }
93
+
94
+ async acquire(): Promise<void> {
95
+ this.refill();
96
+ if (this.tokens >= 1) {
97
+ this.tokens -= 1;
98
+ return;
99
+ }
100
+ // Queue
101
+ return new Promise((resolve, reject) => {
102
+ this.queue.push({ resolve, reject });
103
+ this.processQueue();
104
+ });
105
+ }
106
+
107
+ private processQueue(): void {
108
+ if (this.processing) return;
109
+ this.processing = true;
110
+ const tick = () => {
111
+ this.refill();
112
+ while (this.queue.length > 0 && this.tokens >= 1) {
113
+ this.tokens -= 1;
114
+ const item = this.queue.shift()!;
115
+ item.resolve();
116
+ }
117
+ if (this.queue.length > 0) {
118
+ setTimeout(tick, 50);
119
+ } else {
120
+ this.processing = false;
121
+ }
122
+ };
123
+ tick();
124
+ }
125
+
126
+ /** Destroy limiter dan reject semua queued requests */
127
+ destroy(): void {
128
+ while (this.queue.length > 0) {
129
+ const item = this.queue.shift()!;
130
+ item.reject(new Error('Rate limiter destroyed'));
131
+ }
132
+ }
133
+ }
134
+
135
+ // ============== Debounce ==============
136
+
137
+ export function debounce<T extends (...args: any[]) => void>(
138
+ fn: T,
139
+ wait: number
140
+ ): (...args: Parameters<T>) => void {
141
+ let timeout: NodeJS.Timeout | null = null;
142
+ return (...args: Parameters<T>) => {
143
+ if (timeout) clearTimeout(timeout);
144
+ timeout = setTimeout(() => fn(...args), wait);
145
+ };
146
+ }
147
+
148
+ // ============== Throttle (leading edge) ==============
149
+
150
+ export function throttle<T extends (...args: any[]) => void>(
151
+ fn: T,
152
+ wait: number
153
+ ): (...args: Parameters<T>) => void {
154
+ let lastCall = 0;
155
+ let timeout: NodeJS.Timeout | null = null;
156
+ return (...args: Parameters<T>) => {
157
+ const now = Date.now();
158
+ const remaining = wait - (now - lastCall);
159
+ if (remaining <= 0) {
160
+ if (timeout) {
161
+ clearTimeout(timeout);
162
+ timeout = null;
163
+ }
164
+ lastCall = now;
165
+ fn(...args);
166
+ } else if (!timeout) {
167
+ timeout = setTimeout(() => {
168
+ lastCall = Date.now();
169
+ timeout = null;
170
+ fn(...args);
171
+ }, remaining);
172
+ }
173
+ };
174
+ }
175
+
176
+ // ============== Promise Queue (sequential execution) ==============
177
+
178
+ export class PromiseQueue {
179
+ private queue: Array<() => Promise<void>> = [];
180
+ private running: boolean = false;
181
+
182
+ async add<T>(fn: () => Promise<T>): Promise<T> {
183
+ return new Promise<T>((resolve, reject) => {
184
+ this.queue.push(async () => {
185
+ try {
186
+ const result = await fn();
187
+ resolve(result);
188
+ } catch (err) {
189
+ reject(err);
190
+ }
191
+ });
192
+ this.process();
193
+ });
194
+ }
195
+
196
+ private async process(): Promise<void> {
197
+ if (this.running) return;
198
+ this.running = true;
199
+ while (this.queue.length > 0) {
200
+ const task = this.queue.shift()!;
201
+ await task();
202
+ }
203
+ this.running = false;
204
+ }
205
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022"],
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "sourceMap": true,
12
+ "strict": true,
13
+ "noImplicitAny": true,
14
+ "strictNullChecks": true,
15
+ "strictFunctionTypes": true,
16
+ "noUnusedLocals": false,
17
+ "noUnusedParameters": false,
18
+ "noImplicitReturns": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "esModuleInterop": true,
21
+ "allowSyntheticDefaultImports": true,
22
+ "forceConsistentCasingInFileNames": true,
23
+ "skipLibCheck": true,
24
+ "resolveJsonModule": true,
25
+ "experimentalDecorators": true,
26
+ "emitDecoratorMetadata": true
27
+ },
28
+ "include": ["src/**/*.ts"],
29
+ "exclude": ["node_modules", "dist", "examples", "**/*.test.ts"]
30
+ }