@meshwhisper/node 0.1.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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,547 @@
1
+ #!/usr/bin/env node
2
+ // ============================================================
3
+ // MeshWhisper Node
4
+ // Bundles four functions into one process on one port:
5
+ // 1. Relay — WebSocket relay + store-and-forward
6
+ // 2. Directory — Prekey bundle lookup (X3DH cold-start)
7
+ // 3. Push — APNs/FCM wake signals via webhook
8
+ // 4. Media — Encrypted blob storage (TTL-based, opaque)
9
+ //
10
+ // Usage:
11
+ // PORT=443 node dist/index.js
12
+ // PORT=8080 node dist/index.js (dev)
13
+ //
14
+ // Push webhook:
15
+ // PUSH_WEBHOOK_URL=https://your-push-server/notify
16
+ //
17
+ // When a blob arrives for an offline recipient that has a registered push
18
+ // token, the Node POSTs JSON to PUSH_WEBHOOK_URL:
19
+ // { token, platform, topic?, destHash }
20
+ //
21
+ // The webhook is responsible for sending the actual APNs/FCM notification.
22
+ // The Node only sends a silent wake signal — no message content is included.
23
+ //
24
+ // Self-hosted: one Docker container, one VPS, everything included.
25
+ // Foundation-hosted: same binary, run by the Foundation as public infra.
26
+ // ============================================================
27
+ import * as http from 'node:http';
28
+ import * as https from 'node:https';
29
+ import { WebSocketServer, WebSocket } from 'ws';
30
+ // ============================================================
31
+ // Configuration
32
+ // ============================================================
33
+ const PORT = parseInt(process.env.PORT ?? '8080', 10);
34
+ const BLOB_TTL_HOURS = parseInt(process.env.BLOB_TTL_HOURS ?? '72', 10);
35
+ const MAX_BLOB_SIZE = parseInt(process.env.MAX_BLOB_SIZE ?? String(256 * 1024), 10); // 256 KB
36
+ const MAX_BLOBS_PER_HASH = parseInt(process.env.MAX_BLOBS_PER_HASH ?? '500', 10);
37
+ const MEDIA_TTL_HOURS = parseInt(process.env.MEDIA_TTL_HOURS ?? String(7 * 24), 10); // 7 days
38
+ const MAX_MEDIA_SIZE = parseInt(process.env.MAX_MEDIA_SIZE ?? String(50 * 1024 * 1024), 10); // 50 MB
39
+ const PRUNE_INTERVAL_MS = 5 * 60 * 1000; // prune expired blobs every 5 minutes
40
+ const PUSH_WEBHOOK_URL = process.env.PUSH_WEBHOOK_URL ?? null;
41
+ // Rate limiting (per IP, sliding window)
42
+ const RATE_WINDOW_MS = 60_000; // 1 minute window
43
+ const RATE_LIMIT_MEDIA = parseInt(process.env.RATE_LIMIT_MEDIA ?? '20', 10); // uploads/min
44
+ const RATE_LIMIT_DIR = parseInt(process.env.RATE_LIMIT_DIR ?? '60', 10); // registrations/min
45
+ /** Canonical external base URL for constructing media download links.
46
+ * Set this when the Node is behind a reverse proxy (nginx, Caddy, Cloudflare).
47
+ * Example: BASE_URL=https://msg.myapp.com
48
+ * If unset, the URL is inferred from the Host header (works for local dev). */
49
+ const BASE_URL = (process.env.BASE_URL ?? '').replace(/\/$/, '');
50
+ const rateLimitState = new Map();
51
+ /** Returns true if the request is within limits, false if it should be rejected. */
52
+ function checkRateLimit(ip, bucket, maxPerWindow) {
53
+ const key = `${bucket}:${ip}`;
54
+ const now = Date.now();
55
+ const entry = rateLimitState.get(key);
56
+ if (!entry || now - entry.windowStart >= RATE_WINDOW_MS) {
57
+ rateLimitState.set(key, { count: 1, windowStart: now });
58
+ return true;
59
+ }
60
+ if (entry.count >= maxPerWindow)
61
+ return false;
62
+ entry.count++;
63
+ return true;
64
+ }
65
+ function getClientIp(req) {
66
+ // Respect X-Forwarded-For when behind a proxy
67
+ const forwarded = req.headers['x-forwarded-for'];
68
+ if (typeof forwarded === 'string')
69
+ return forwarded.split(',')[0].trim();
70
+ return req.socket.remoteAddress ?? 'unknown';
71
+ }
72
+ // Prune stale rate limit entries alongside blobs
73
+ function pruneRateLimitState() {
74
+ const cutoff = Date.now() - RATE_WINDOW_MS;
75
+ for (const [key, entry] of rateLimitState.entries()) {
76
+ if (entry.windowStart < cutoff)
77
+ rateLimitState.delete(key);
78
+ }
79
+ }
80
+ // ============================================================
81
+ // Packet header constants (must match SDK wire format)
82
+ //
83
+ // Binary layout (all big-endian):
84
+ // [0] version u8
85
+ // [1] flags u8
86
+ // [2..9] destHash 8 bytes
87
+ // [10..25] senderEphId 16 bytes
88
+ // [26] ttl u8
89
+ // [27..30] payloadLen u32
90
+ // [31..] encrypted payload
91
+ // ============================================================
92
+ const HEADER_SIZE = 31;
93
+ const DEST_HASH_OFFSET = 2;
94
+ const DEST_HASH_LENGTH = 8;
95
+ function readDestHash(buf) {
96
+ if (buf.byteLength < HEADER_SIZE)
97
+ return null;
98
+ const bytes = buf.subarray(DEST_HASH_OFFSET, DEST_HASH_OFFSET + DEST_HASH_LENGTH);
99
+ return Buffer.from(bytes).toString('hex');
100
+ }
101
+ /** Map from destHash (hex) → list of queued blobs. */
102
+ const blobStore = new Map();
103
+ function storeBlob(destHash, data) {
104
+ let queue = blobStore.get(destHash);
105
+ if (!queue) {
106
+ queue = [];
107
+ blobStore.set(destHash, queue);
108
+ }
109
+ if (queue.length >= MAX_BLOBS_PER_HASH) {
110
+ queue.shift(); // drop oldest when full
111
+ }
112
+ queue.push({ data, receivedAt: Date.now() });
113
+ }
114
+ function pullBlobs(destHash) {
115
+ const queue = blobStore.get(destHash);
116
+ if (!queue || queue.length === 0)
117
+ return [];
118
+ blobStore.delete(destHash);
119
+ return queue.map((b) => b.data);
120
+ }
121
+ function pruneExpiredBlobs() {
122
+ const cutoff = Date.now() - BLOB_TTL_HOURS * 60 * 60 * 1000;
123
+ for (const [hash, queue] of blobStore.entries()) {
124
+ const fresh = queue.filter((b) => b.receivedAt > cutoff);
125
+ if (fresh.length === 0) {
126
+ blobStore.delete(hash);
127
+ // Also expire the push token for this dest hash — if no blobs have
128
+ // arrived within the blob TTL window, the device has likely rotated
129
+ // its dest hashes and the token is stale.
130
+ pushTokens.delete(hash);
131
+ }
132
+ else {
133
+ blobStore.set(hash, fresh);
134
+ }
135
+ }
136
+ }
137
+ /** Map from destHash (hex) → push registration for offline wake signals. */
138
+ const pushTokens = new Map();
139
+ function registerPushTokens(destHashes, reg) {
140
+ for (const hash of destHashes) {
141
+ pushTokens.set(hash, reg);
142
+ }
143
+ }
144
+ function deregisterPushTokens(destHashes) {
145
+ for (const hash of destHashes) {
146
+ pushTokens.delete(hash);
147
+ }
148
+ }
149
+ /**
150
+ * Fire-and-forget POST to the configured push webhook.
151
+ * Payload: { token, platform, topic?, destHash }
152
+ * No retry — best-effort. If there is no webhook configured, this is a no-op.
153
+ */
154
+ function notifyPush(destHash, reg) {
155
+ if (!PUSH_WEBHOOK_URL)
156
+ return;
157
+ const body = JSON.stringify({
158
+ token: reg.token,
159
+ platform: reg.platform,
160
+ ...(reg.topic ? { topic: reg.topic } : {}),
161
+ ...(reg.pushSubscription ? { pushSubscription: JSON.parse(reg.pushSubscription) } : {}),
162
+ destHash,
163
+ });
164
+ try {
165
+ const url = new URL(PUSH_WEBHOOK_URL);
166
+ const transport = url.protocol === 'https:' ? https : http;
167
+ const req = transport.request(url, {
168
+ method: 'POST',
169
+ headers: {
170
+ 'Content-Type': 'application/json',
171
+ 'Content-Length': Buffer.byteLength(body),
172
+ },
173
+ });
174
+ req.on('error', () => { });
175
+ req.write(body);
176
+ req.end();
177
+ }
178
+ catch {
179
+ // Misconfigured URL or network error — swallow
180
+ }
181
+ }
182
+ // ============================================================
183
+ // Prekey directory — in-memory, namespace-scoped
184
+ // ============================================================
185
+ /** Map from `${namespace}:${publicKeyHex}` → serialized bundle (base64). */
186
+ const prekeyDirectory = new Map();
187
+ function directoryKey(namespace, publicKey) {
188
+ return `${namespace}:${publicKey}`;
189
+ }
190
+ function registerPrekey(namespace, publicKey, bundle) {
191
+ prekeyDirectory.set(directoryKey(namespace, publicKey), bundle);
192
+ }
193
+ function lookupPrekey(namespace, publicKey) {
194
+ return prekeyDirectory.get(directoryKey(namespace, publicKey)) ?? null;
195
+ }
196
+ /** Map from random media ID (hex) → encrypted media blob. */
197
+ const mediaStore = new Map();
198
+ function generateMediaId() {
199
+ const bytes = new Uint8Array(16);
200
+ globalThis.crypto.getRandomValues(bytes);
201
+ return Buffer.from(bytes).toString('hex');
202
+ }
203
+ function storeMedia(data) {
204
+ const id = generateMediaId();
205
+ const storedAt = Date.now();
206
+ mediaStore.set(id, { data, storedAt });
207
+ return { id, expiresAt: storedAt + MEDIA_TTL_HOURS * 60 * 60 * 1000 };
208
+ }
209
+ function fetchMedia(id) {
210
+ const entry = mediaStore.get(id);
211
+ if (!entry)
212
+ return null;
213
+ const expiresAt = entry.storedAt + MEDIA_TTL_HOURS * 60 * 60 * 1000;
214
+ if (Date.now() > expiresAt) {
215
+ mediaStore.delete(id);
216
+ return null;
217
+ }
218
+ return entry.data;
219
+ }
220
+ function pruneExpiredMedia() {
221
+ const cutoff = Date.now() - MEDIA_TTL_HOURS * 60 * 60 * 1000;
222
+ for (const [id, entry] of mediaStore.entries()) {
223
+ if (entry.storedAt < cutoff)
224
+ mediaStore.delete(id);
225
+ }
226
+ }
227
+ // ============================================================
228
+ // Connected clients — map from destHash (hex) → WebSocket
229
+ // ============================================================
230
+ /** A client may register multiple dest hashes (current + previous epoch). */
231
+ const clientsByHash = new Map();
232
+ /** Reverse map so we can clean up on disconnect. */
233
+ const hashesPerClient = new Map();
234
+ function registerClient(ws, destHashes) {
235
+ // Remove any previous registrations for this socket
236
+ const existing = hashesPerClient.get(ws);
237
+ if (existing) {
238
+ for (const h of existing)
239
+ clientsByHash.delete(h);
240
+ }
241
+ const hashes = new Set();
242
+ for (const h of destHashes) {
243
+ clientsByHash.set(h, ws);
244
+ hashes.add(h);
245
+ }
246
+ hashesPerClient.set(ws, hashes);
247
+ }
248
+ function deregisterClient(ws) {
249
+ const hashes = hashesPerClient.get(ws);
250
+ if (hashes) {
251
+ for (const h of hashes)
252
+ clientsByHash.delete(h);
253
+ // Push tokens are intentionally kept after disconnect — they are needed
254
+ // to wake the device when it is offline. They expire naturally alongside
255
+ // the blobs in the prune cycle.
256
+ hashesPerClient.delete(ws);
257
+ }
258
+ }
259
+ function deliverQueuedBlobs(ws, destHashes) {
260
+ for (const hash of destHashes) {
261
+ const blobs = pullBlobs(hash);
262
+ for (const blob of blobs) {
263
+ if (ws.readyState === WebSocket.OPEN) {
264
+ ws.send(blob, { binary: true });
265
+ }
266
+ }
267
+ }
268
+ }
269
+ // ============================================================
270
+ // Relay — incoming binary packet handler
271
+ // ============================================================
272
+ function handleRelayPacket(data, sender) {
273
+ if (data.byteLength > MAX_BLOB_SIZE)
274
+ return; // drop oversized packets
275
+ const destHash = readDestHash(data);
276
+ if (!destHash)
277
+ return; // malformed header
278
+ const recipient = clientsByHash.get(destHash);
279
+ if (recipient && recipient !== sender && recipient.readyState === WebSocket.OPEN) {
280
+ // Recipient is connected — forward directly
281
+ recipient.send(data, { binary: true });
282
+ }
283
+ else {
284
+ // Recipient offline (or same socket) — store for later delivery
285
+ storeBlob(destHash, data);
286
+ // Wake the recipient via push if they have a registered token
287
+ const pushReg = pushTokens.get(destHash);
288
+ if (pushReg)
289
+ notifyPush(destHash, pushReg);
290
+ }
291
+ }
292
+ // ============================================================
293
+ // WebSocket server
294
+ // ============================================================
295
+ function handleWebSocketConnection(ws) {
296
+ ws.on('message', (raw) => {
297
+ if (raw instanceof ArrayBuffer) {
298
+ handleRelayPacket(new Uint8Array(raw), ws);
299
+ return;
300
+ }
301
+ if (Buffer.isBuffer(raw)) {
302
+ handleRelayPacket(new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength), ws);
303
+ return;
304
+ }
305
+ // JSON control message
306
+ try {
307
+ const msg = JSON.parse(raw.toString());
308
+ if (msg.type === 'hello' && Array.isArray(msg.destHashes)) {
309
+ const hashes = msg.destHashes.filter((h) => typeof h === 'string' && /^[0-9a-f]{16}$/.test(h));
310
+ registerClient(ws, hashes);
311
+ // Register push token/subscription if provided
312
+ if (msg.pushPlatform === 'webpush' && typeof msg.pushSubscription === 'string') {
313
+ const reg = {
314
+ token: msg.pushSubscription, // subscription JSON stored in token field
315
+ platform: 'webpush',
316
+ pushSubscription: msg.pushSubscription,
317
+ };
318
+ registerPushTokens(hashes, reg);
319
+ }
320
+ else if (typeof msg.pushToken === 'string' && msg.pushToken &&
321
+ (msg.pushPlatform === 'apns' || msg.pushPlatform === 'fcm')) {
322
+ const reg = {
323
+ token: msg.pushToken,
324
+ platform: msg.pushPlatform,
325
+ ...(typeof msg.pushTopic === 'string' && msg.pushTopic ? { topic: msg.pushTopic } : {}),
326
+ };
327
+ registerPushTokens(hashes, reg);
328
+ }
329
+ deliverQueuedBlobs(ws, hashes);
330
+ return;
331
+ }
332
+ if (msg.type === 'pull') {
333
+ const hashes = hashesPerClient.get(ws);
334
+ if (hashes)
335
+ deliverQueuedBlobs(ws, [...hashes]);
336
+ return;
337
+ }
338
+ }
339
+ catch {
340
+ // Not JSON or malformed — ignore
341
+ }
342
+ });
343
+ ws.on('close', () => {
344
+ deregisterClient(ws);
345
+ });
346
+ ws.on('error', () => {
347
+ deregisterClient(ws);
348
+ });
349
+ }
350
+ // ============================================================
351
+ // HTTP handler — health check and prekey directory
352
+ // ============================================================
353
+ function parseBody(req) {
354
+ return new Promise((resolve, reject) => {
355
+ const chunks = [];
356
+ req.on('data', (chunk) => chunks.push(chunk));
357
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
358
+ req.on('error', reject);
359
+ });
360
+ }
361
+ function sendJson(res, status, body) {
362
+ const payload = JSON.stringify(body);
363
+ res.writeHead(status, {
364
+ 'Content-Type': 'application/json',
365
+ 'Content-Length': Buffer.byteLength(payload),
366
+ 'Access-Control-Allow-Origin': '*',
367
+ });
368
+ res.end(payload);
369
+ }
370
+ async function handleHttp(req, res) {
371
+ const url = new URL(req.url ?? '/', `http://localhost`);
372
+ const method = req.method ?? 'GET';
373
+ // CORS preflight
374
+ if (method === 'OPTIONS') {
375
+ res.writeHead(204, {
376
+ 'Access-Control-Allow-Origin': '*',
377
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
378
+ 'Access-Control-Allow-Headers': 'Content-Type',
379
+ });
380
+ res.end();
381
+ return;
382
+ }
383
+ // Health check
384
+ if (url.pathname === '/health' && method === 'GET') {
385
+ sendJson(res, 200, {
386
+ status: 'ok',
387
+ clients: clientsByHash.size,
388
+ storedBlobs: [...blobStore.values()].reduce((n, q) => n + q.length, 0),
389
+ prekeyEntries: prekeyDirectory.size,
390
+ pushRegistrations: pushTokens.size,
391
+ mediaEntries: mediaStore.size,
392
+ });
393
+ return;
394
+ }
395
+ // Register prekey bundle
396
+ // POST /directory { namespace, publicKey, bundle }
397
+ if (url.pathname === '/directory' && method === 'POST') {
398
+ if (!checkRateLimit(getClientIp(req), 'dir', RATE_LIMIT_DIR)) {
399
+ sendJson(res, 429, { error: 'Too many requests' });
400
+ return;
401
+ }
402
+ let body;
403
+ try {
404
+ body = JSON.parse(await parseBody(req));
405
+ }
406
+ catch {
407
+ sendJson(res, 400, { error: 'Invalid JSON body' });
408
+ return;
409
+ }
410
+ const { namespace, publicKey, bundle } = body;
411
+ if (typeof namespace !== 'string' || !namespace ||
412
+ typeof publicKey !== 'string' || !publicKey ||
413
+ typeof bundle !== 'string' || !bundle) {
414
+ sendJson(res, 400, { error: 'Missing required fields: namespace, publicKey, bundle' });
415
+ return;
416
+ }
417
+ registerPrekey(namespace, publicKey, bundle);
418
+ sendJson(res, 200, { ok: true });
419
+ return;
420
+ }
421
+ // Lookup prekey bundle
422
+ // GET /directory?namespace=&publicKey=
423
+ if (url.pathname === '/directory' && method === 'GET') {
424
+ const namespace = url.searchParams.get('namespace');
425
+ const publicKey = url.searchParams.get('publicKey');
426
+ if (!namespace || !publicKey) {
427
+ sendJson(res, 400, { error: 'Missing query params: namespace, publicKey' });
428
+ return;
429
+ }
430
+ const bundle = lookupPrekey(namespace, publicKey);
431
+ if (!bundle) {
432
+ sendJson(res, 404, { error: 'Prekey bundle not found' });
433
+ return;
434
+ }
435
+ sendJson(res, 200, { bundle });
436
+ return;
437
+ }
438
+ // Upload encrypted media blob
439
+ // POST /media (binary body, Content-Length required)
440
+ // Returns: { id, url, expiresAt }
441
+ if (url.pathname === '/media' && method === 'POST') {
442
+ if (!checkRateLimit(getClientIp(req), 'media', RATE_LIMIT_MEDIA)) {
443
+ sendJson(res, 429, { error: 'Too many requests' });
444
+ return;
445
+ }
446
+ const contentLength = parseInt(req.headers['content-length'] ?? '0', 10);
447
+ if (contentLength > MAX_MEDIA_SIZE) {
448
+ sendJson(res, 413, { error: `Payload too large (max ${MAX_MEDIA_SIZE} bytes)` });
449
+ return;
450
+ }
451
+ const chunks = [];
452
+ let received = 0;
453
+ let aborted = false;
454
+ await new Promise((resolve, reject) => {
455
+ req.on('data', (chunk) => {
456
+ received += chunk.length;
457
+ if (received > MAX_MEDIA_SIZE) {
458
+ aborted = true;
459
+ req.destroy();
460
+ return;
461
+ }
462
+ chunks.push(chunk);
463
+ });
464
+ req.on('end', resolve);
465
+ req.on('error', reject);
466
+ });
467
+ if (aborted) {
468
+ sendJson(res, 413, { error: `Payload too large (max ${MAX_MEDIA_SIZE} bytes)` });
469
+ return;
470
+ }
471
+ const data = Buffer.concat(chunks);
472
+ const { id, expiresAt } = storeMedia(data);
473
+ const base = BASE_URL || `http://${req.headers['host'] ?? `localhost:${PORT}`}`;
474
+ const mediaUrl = `${base}/media/${id}`;
475
+ sendJson(res, 200, { id, url: mediaUrl, expiresAt });
476
+ return;
477
+ }
478
+ // Download encrypted media blob
479
+ // GET /media/:id
480
+ const mediaMatch = url.pathname.match(/^\/media\/([0-9a-f]{32})$/);
481
+ if (mediaMatch && method === 'GET') {
482
+ const data = fetchMedia(mediaMatch[1]);
483
+ if (!data) {
484
+ sendJson(res, 404, { error: 'Media not found or expired' });
485
+ return;
486
+ }
487
+ res.writeHead(200, {
488
+ 'Content-Type': 'application/octet-stream',
489
+ 'Content-Length': data.length,
490
+ 'Access-Control-Allow-Origin': '*',
491
+ 'Cache-Control': 'private, max-age=604800', // 7 days
492
+ });
493
+ res.end(data);
494
+ return;
495
+ }
496
+ sendJson(res, 404, { error: 'Not found' });
497
+ }
498
+ // ============================================================
499
+ // Server startup
500
+ // ============================================================
501
+ const httpServer = http.createServer((req, res) => {
502
+ handleHttp(req, res).catch((err) => {
503
+ console.error('[ERROR] HTTP handler threw:', err);
504
+ res.writeHead(500).end();
505
+ });
506
+ });
507
+ const wss = new WebSocketServer({ noServer: true });
508
+ wss.on('connection', (ws) => {
509
+ handleWebSocketConnection(ws);
510
+ });
511
+ httpServer.on('upgrade', (req, socket, head) => {
512
+ wss.handleUpgrade(req, socket, head, (ws) => {
513
+ wss.emit('connection', ws, req);
514
+ });
515
+ });
516
+ // Prune expired blobs and media on a regular interval
517
+ const pruneInterval = setInterval(() => {
518
+ pruneExpiredBlobs();
519
+ pruneExpiredMedia();
520
+ pruneRateLimitState();
521
+ }, PRUNE_INTERVAL_MS);
522
+ pruneInterval.unref(); // don't keep process alive for pruning alone
523
+ httpServer.listen(PORT, () => {
524
+ console.log(`MeshWhisper Node listening on port ${PORT}`);
525
+ console.log(` Relay: ws://localhost:${PORT}`);
526
+ console.log(` Directory: http://localhost:${PORT}/directory`);
527
+ console.log(` Media: http://localhost:${PORT}/media`);
528
+ console.log(` Health: http://localhost:${PORT}/health`);
529
+ console.log(` Blob TTL: ${BLOB_TTL_HOURS}h`);
530
+ console.log(` Media TTL: ${MEDIA_TTL_HOURS}h (max ${MAX_MEDIA_SIZE / (1024 * 1024)}MB per file)`);
531
+ console.log(` Base URL: ${BASE_URL || '(inferred from Host header — set BASE_URL in production)'}`);
532
+ console.log(` Push: ${PUSH_WEBHOOK_URL ?? 'disabled (set PUSH_WEBHOOK_URL to enable)'}`);
533
+ });
534
+ // ============================================================
535
+ // Graceful shutdown
536
+ // ============================================================
537
+ function shutdown() {
538
+ console.log('\nShutting down...');
539
+ clearInterval(pruneInterval);
540
+ wss.clients.forEach((ws) => ws.close(1001, 'Node shutting down'));
541
+ wss.close();
542
+ httpServer.close(() => process.exit(0));
543
+ setTimeout(() => process.exit(1), 3000).unref();
544
+ }
545
+ process.on('SIGINT', shutdown);
546
+ process.on('SIGTERM', shutdown);
547
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@meshwhisper/node",
3
+ "version": "0.1.0",
4
+ "description": "MeshWhisper Node — relay, push forwarding, media storage, and prekey directory in a single binary",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "meshwhisper-node": "dist/index.js"
9
+ },
10
+ "files": ["dist"],
11
+ "publishConfig": { "access": "public" },
12
+ "scripts": {
13
+ "prepublishOnly": "npm run build",
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsx src/index.ts"
17
+ },
18
+ "dependencies": {
19
+ "ws": "^8.18.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.0.0",
23
+ "@types/ws": "^8.5.0",
24
+ "tsx": "^4.21.0",
25
+ "typescript": "^5.7.0"
26
+ },
27
+ "license": "MIT"
28
+ }