dolphin-server-modules 2.11.0 → 2.11.2
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.
- package/TUTORIAL_NEPALI.md +181 -0
- package/dist/adapters/mongoose/index.d.ts +4 -4
- package/dist/adapters/mongoose/index.js.map +1 -1
- package/dist/adapters/mongoose/index.test.d.ts +1 -0
- package/dist/adapters/mongoose/index.test.js +145 -0
- package/dist/adapters/mongoose/index.test.js.map +1 -0
- package/dist/adapters/mongoose/integration.test.d.ts +5 -0
- package/dist/adapters/mongoose/integration.test.js +217 -0
- package/dist/adapters/mongoose/integration.test.js.map +1 -0
- package/dist/ai/dolphin-agent/agent.d.ts +5 -0
- package/dist/ai/dolphin-agent/agent.js +93 -35
- package/dist/ai/dolphin-agent/agent.js.map +1 -1
- package/dist/ai/dolphin-agent/config.js +30 -37
- package/dist/ai/dolphin-agent/config.js.map +1 -1
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +286 -0
- package/dist/auth/auth.test.js.map +1 -0
- package/dist/authController/authController.test.d.ts +1 -0
- package/dist/authController/authController.test.js +359 -0
- package/dist/authController/authController.test.js.map +1 -0
- package/dist/bin/cli.js +494 -165
- package/dist/bin/cli.js.map +1 -1
- package/dist/client.test.d.ts +22 -0
- package/dist/client.test.js +573 -0
- package/dist/client.test.js.map +1 -0
- package/dist/controller/controller.test.d.ts +1 -0
- package/dist/controller/controller.test.js +37 -0
- package/dist/controller/controller.test.js.map +1 -0
- package/dist/curd/crud.test.d.ts +1 -0
- package/dist/curd/crud.test.js +104 -0
- package/dist/curd/crud.test.js.map +1 -0
- package/dist/demo-server.d.ts +1 -0
- package/dist/demo-server.js +191 -0
- package/dist/demo-server.js.map +1 -0
- package/dist/djson/djson.test.d.ts +1 -0
- package/dist/djson/djson.test.js +200 -0
- package/dist/djson/djson.test.js.map +1 -0
- package/dist/dolphin-bench.d.ts +1 -0
- package/dist/dolphin-bench.js +63 -0
- package/dist/dolphin-bench.js.map +1 -0
- package/dist/hard-performance-test.d.ts +1 -0
- package/dist/hard-performance-test.js +97 -0
- package/dist/hard-performance-test.js.map +1 -0
- package/dist/middleware/zod.test.d.ts +1 -0
- package/dist/middleware/zod.test.js +74 -0
- package/dist/middleware/zod.test.js.map +1 -0
- package/dist/performance-test.d.ts +1 -0
- package/dist/performance-test.js +92 -0
- package/dist/performance-test.js.map +1 -0
- package/dist/real-test-mongoose.d.ts +1 -0
- package/dist/real-test-mongoose.js +104 -0
- package/dist/real-test-mongoose.js.map +1 -0
- package/dist/realtime/camera.d.ts +119 -0
- package/dist/realtime/camera.js +299 -0
- package/dist/realtime/camera.js.map +1 -0
- package/dist/realtime/camera.test.d.ts +1 -0
- package/dist/realtime/camera.test.js +345 -0
- package/dist/realtime/camera.test.js.map +1 -0
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.js +2 -0
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/realtime.test.d.ts +1 -0
- package/dist/realtime/realtime.test.js +623 -0
- package/dist/realtime/realtime.test.js.map +1 -0
- package/dist/realtime/rtsp.d.ts +65 -0
- package/dist/realtime/rtsp.js +410 -0
- package/dist/realtime/rtsp.js.map +1 -0
- package/dist/realtime/rtsp.test.d.ts +1 -0
- package/dist/realtime/rtsp.test.js +361 -0
- package/dist/realtime/rtsp.test.js.map +1 -0
- package/dist/router/router.test.d.ts +1 -0
- package/dist/router/router.test.js +45 -0
- package/dist/router/router.test.js.map +1 -0
- package/dist/server/server.test.d.ts +1 -0
- package/dist/server/server.test.js +299 -0
- package/dist/server/server.test.js.map +1 -0
- package/dist/services/ai-service.js +22 -11
- package/dist/services/ai-service.js.map +1 -1
- package/dist/signaling/signaling.test.d.ts +1 -0
- package/dist/signaling/signaling.test.js +112 -0
- package/dist/signaling/signaling.test.js.map +1 -0
- package/dist/swagger/swagger.js +31 -31
- package/dist/swagger/swagger.test.d.ts +1 -0
- package/dist/swagger/swagger.test.js +38 -0
- package/dist/swagger/swagger.test.js.map +1 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.js +282 -105
- package/dist/templates/index.js.map +1 -1
- package/dist/test-2fa-real.d.ts +1 -0
- package/dist/test-2fa-real.js +105 -0
- package/dist/test-2fa-real.js.map +1 -0
- package/dist/test-dolphin.d.ts +1 -0
- package/dist/test-dolphin.js +98 -0
- package/dist/test-dolphin.js.map +1 -0
- package/dist/utils/ctx.d.ts +50 -0
- package/dist/utils/ctx.js +82 -0
- package/dist/utils/ctx.js.map +1 -0
- package/package.json +155 -45
- package/scripts/client.js +838 -0
- package/scripts/dolphin-persist.js +211 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createDolphinServer } from './server/server';
|
|
2
|
+
import http from 'http';
|
|
3
|
+
const PORT = 3007;
|
|
4
|
+
const CONCURRENCY = 50;
|
|
5
|
+
const DURATION_MS = 5000;
|
|
6
|
+
async function benchmark() {
|
|
7
|
+
const app = createDolphinServer();
|
|
8
|
+
app.get('/perf', (ctx) => {
|
|
9
|
+
ctx.json({ status: 'ok', rps_test: true });
|
|
10
|
+
});
|
|
11
|
+
const server = app.listen(PORT, async () => {
|
|
12
|
+
console.log(`🐬 Dolphin Benchmark Server running on port ${PORT}`);
|
|
13
|
+
const getMemory = () => {
|
|
14
|
+
const mem = process.memoryUsage();
|
|
15
|
+
return {
|
|
16
|
+
rss: (mem.rss / 1024 / 1024).toFixed(2) + ' MB',
|
|
17
|
+
heapUsed: (mem.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
|
|
18
|
+
heapTotal: (mem.heapTotal / 1024 / 1024).toFixed(2) + ' MB'
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const memBefore = getMemory();
|
|
22
|
+
console.log(`🧠 Memory BEFORE load: RSS: ${memBefore.rss}, Heap: ${memBefore.heapUsed}/${memBefore.heapTotal}`);
|
|
23
|
+
let successfulRequests = 0;
|
|
24
|
+
let totalLatency = 0;
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
const makeRequest = () => {
|
|
27
|
+
const requestStart = Date.now();
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
if (Date.now() - startTime > DURATION_MS)
|
|
30
|
+
return resolve();
|
|
31
|
+
const req = http.get(`http://localhost:${PORT}/perf`, (res) => {
|
|
32
|
+
if (res.statusCode === 200)
|
|
33
|
+
successfulRequests++;
|
|
34
|
+
totalLatency += Date.now() - requestStart;
|
|
35
|
+
res.resume();
|
|
36
|
+
res.on('end', () => {
|
|
37
|
+
if (Date.now() - startTime < DURATION_MS)
|
|
38
|
+
makeRequest().then(resolve);
|
|
39
|
+
else
|
|
40
|
+
resolve();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
req.on('error', () => resolve());
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
console.log(`🚀 Starting single-process benchmark (Concurrency: ${CONCURRENCY})...`);
|
|
47
|
+
const promises = Array.from({ length: CONCURRENCY }, () => makeRequest());
|
|
48
|
+
await Promise.all(promises);
|
|
49
|
+
const actualDuration = (Date.now() - startTime) / 1000;
|
|
50
|
+
const rps = (successfulRequests / actualDuration).toFixed(2);
|
|
51
|
+
const avgLatency = (totalLatency / successfulRequests).toFixed(2);
|
|
52
|
+
const memAfter = getMemory();
|
|
53
|
+
console.log('\n📊 DOLPHIN PERFORMANCE RESULTS (Single Process):');
|
|
54
|
+
console.log(`Requests Per Second: ${rps}`);
|
|
55
|
+
console.log(`Average Latency: ${avgLatency}ms`);
|
|
56
|
+
console.log(`Total Successful Requests: ${successfulRequests}`);
|
|
57
|
+
console.log(`🧠 Memory AFTER load: RSS: ${memAfter.rss}, Heap: ${memAfter.heapUsed}/${memAfter.heapTotal}`);
|
|
58
|
+
server.close();
|
|
59
|
+
process.exit(0);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
benchmark().catch(console.error);
|
|
63
|
+
//# sourceMappingURL=dolphin-bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dolphin-bench.js","sourceRoot":"","sources":["../src/dolphin-bench.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// hard-performance-test.ts - Intensive performance test
|
|
2
|
+
import { createServer } from "http";
|
|
3
|
+
import { cpus } from "os";
|
|
4
|
+
import cluster from "cluster";
|
|
5
|
+
const PORT = 3006;
|
|
6
|
+
const CONCURRENCY = 100; // Increased concurrency
|
|
7
|
+
const DURATION_MS = 10000; // Longer duration
|
|
8
|
+
if (cluster.isMaster) {
|
|
9
|
+
const numWorkers = cpus().length;
|
|
10
|
+
console.log(`🍴 Master running, forking ${numWorkers} workers for hard test...`);
|
|
11
|
+
for (let i = 0; i < numWorkers; i++) {
|
|
12
|
+
cluster.fork();
|
|
13
|
+
}
|
|
14
|
+
let results = [];
|
|
15
|
+
for (const id in cluster.workers) {
|
|
16
|
+
cluster.workers[id]?.on("message", (msg) => {
|
|
17
|
+
if (msg.type === "result") {
|
|
18
|
+
results.push(msg.data);
|
|
19
|
+
if (results.length === numWorkers) {
|
|
20
|
+
console.log("\n📊 HARD CLUSTER PERFORMANCE RESULTS:");
|
|
21
|
+
results.forEach((r) => {
|
|
22
|
+
console.log(`Worker ${r.workerId}: ${r.rps} RPS | Avg Latency: ${r.latency}ms | Total: ${r.total}, Success: ${r.success}`);
|
|
23
|
+
});
|
|
24
|
+
const totalRPS = results.reduce((sum, r) => sum + r.rps, 0);
|
|
25
|
+
console.log(`\nTotal RPS across all workers: ${totalRPS.toFixed(2)}`);
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Worker process
|
|
34
|
+
const app = createServer((req, res) => {
|
|
35
|
+
if (req.url === "/hard-perf") {
|
|
36
|
+
// Simulate some processing delay
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
39
|
+
res.end(JSON.stringify({ status: "ok", time: Date.now() }));
|
|
40
|
+
}, Math.random() * 10); // Random delay 0-10ms
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
res.writeHead(404);
|
|
44
|
+
res.end();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
app.listen(PORT, () => {
|
|
48
|
+
console.log(`Worker ${process.pid} listening on port ${PORT}`);
|
|
49
|
+
// Benchmark inside worker
|
|
50
|
+
let totalRequests = 0;
|
|
51
|
+
let successfulRequests = 0;
|
|
52
|
+
let totalLatency = 0;
|
|
53
|
+
const startTime = Date.now();
|
|
54
|
+
const http = require("http");
|
|
55
|
+
const makeRequest = () => {
|
|
56
|
+
const requestStart = Date.now();
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
if (Date.now() - startTime > DURATION_MS)
|
|
59
|
+
return resolve();
|
|
60
|
+
const req = http.get(`http://localhost:${PORT}/hard-perf`, (res) => {
|
|
61
|
+
totalRequests++;
|
|
62
|
+
if (res.statusCode === 200)
|
|
63
|
+
successfulRequests++;
|
|
64
|
+
totalLatency += Date.now() - requestStart;
|
|
65
|
+
res.resume();
|
|
66
|
+
res.on("end", () => {
|
|
67
|
+
if (Date.now() - startTime < DURATION_MS)
|
|
68
|
+
makeRequest().then(resolve);
|
|
69
|
+
else
|
|
70
|
+
resolve();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
req.on("error", () => {
|
|
74
|
+
totalRequests++;
|
|
75
|
+
resolve();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const promises = Array.from({ length: CONCURRENCY }, () => makeRequest());
|
|
80
|
+
Promise.all(promises).then(() => {
|
|
81
|
+
const actualDuration = (Date.now() - startTime) / 1000;
|
|
82
|
+
const rps = (successfulRequests / actualDuration).toFixed(2);
|
|
83
|
+
const avgLatency = successfulRequests > 0 ? (totalLatency / successfulRequests).toFixed(2) : '0';
|
|
84
|
+
process.send?.({
|
|
85
|
+
type: "result",
|
|
86
|
+
data: {
|
|
87
|
+
workerId: process.pid,
|
|
88
|
+
total: totalRequests,
|
|
89
|
+
success: successfulRequests,
|
|
90
|
+
rps: Number(rps),
|
|
91
|
+
latency: Number(avgLatency),
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=hard-performance-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hard-performance-test.js","sourceRoot":"","sources":["../src/hard-performance-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { validateStructure, validatePagesRequest, validateAppRoute } from './zod';
|
|
3
|
+
describe('Zod Validation Middleware', () => {
|
|
4
|
+
const userSchema = z.object({
|
|
5
|
+
name: z.string().min(2),
|
|
6
|
+
age: z.number().gte(18)
|
|
7
|
+
});
|
|
8
|
+
describe('validateStructure', () => {
|
|
9
|
+
it('validates and returns data if valid', () => {
|
|
10
|
+
const data = { name: 'Alice', age: 25 };
|
|
11
|
+
const res = validateStructure(userSchema, data);
|
|
12
|
+
expect(res).toEqual(data);
|
|
13
|
+
});
|
|
14
|
+
it('throws custom error object if invalid', () => {
|
|
15
|
+
expect(() => validateStructure(userSchema, { name: 'A', age: 10 })).toThrowError();
|
|
16
|
+
try {
|
|
17
|
+
validateStructure(userSchema, { name: 'A', age: 10 });
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
expect(err.status).toBe(400);
|
|
21
|
+
expect(err.errors.length).toBe(2);
|
|
22
|
+
expect(err.errors[0].field).toBe('name');
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('validatePagesRequest', () => {
|
|
27
|
+
it('calls next if valid', () => {
|
|
28
|
+
const middleware = validatePagesRequest({ body: userSchema });
|
|
29
|
+
const req = { body: { name: 'Alice', age: 25 } };
|
|
30
|
+
const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
|
|
31
|
+
const next = jest.fn();
|
|
32
|
+
middleware(req, res, next);
|
|
33
|
+
expect(next).toHaveBeenCalled();
|
|
34
|
+
expect(res.status).not.toHaveBeenCalled();
|
|
35
|
+
});
|
|
36
|
+
it('returns 400 if invalid', () => {
|
|
37
|
+
const middleware = validatePagesRequest({ body: userSchema });
|
|
38
|
+
const req = { body: { name: 'A' } };
|
|
39
|
+
const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
|
|
40
|
+
const next = jest.fn();
|
|
41
|
+
middleware(req, res, next);
|
|
42
|
+
expect(next).not.toHaveBeenCalled();
|
|
43
|
+
expect(res.status).toHaveBeenCalledWith(400);
|
|
44
|
+
expect(res.json).toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('validateAppRoute', () => {
|
|
48
|
+
it('passes validated data to the handler', async () => {
|
|
49
|
+
const handler = jest.fn().mockReturnValue(new Response('OK'));
|
|
50
|
+
const wrapped = validateAppRoute(userSchema, handler);
|
|
51
|
+
const request = new Request('http://localhost', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
body: JSON.stringify({ name: 'Alice', age: 25 })
|
|
54
|
+
});
|
|
55
|
+
const response = await wrapped(request);
|
|
56
|
+
expect(handler).toHaveBeenCalledWith(request, { name: 'Alice', age: 25 });
|
|
57
|
+
});
|
|
58
|
+
it('returns a 400 response on validation failure', async () => {
|
|
59
|
+
const handler = jest.fn();
|
|
60
|
+
const wrapped = validateAppRoute(userSchema, handler);
|
|
61
|
+
const request = new Request('http://localhost', {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
body: JSON.stringify({ name: 'A', age: 10 })
|
|
64
|
+
});
|
|
65
|
+
const response = await wrapped(request);
|
|
66
|
+
expect(handler).not.toHaveBeenCalled();
|
|
67
|
+
expect(response.status).toBe(400);
|
|
68
|
+
const body = await response.json();
|
|
69
|
+
expect(body.message).toBe('Validation Error');
|
|
70
|
+
expect(body.errors.length).toBe(2);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=zod.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.test.js","sourceRoot":"","sources":["../../src/middleware/zod.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// performance-cluster.ts
|
|
2
|
+
import { createServer } from "http";
|
|
3
|
+
import { cpus } from "os";
|
|
4
|
+
import cluster from "cluster";
|
|
5
|
+
const PORT = 3005;
|
|
6
|
+
const CONCURRENCY = 50;
|
|
7
|
+
const DURATION_MS = 5000;
|
|
8
|
+
if (cluster.isMaster) {
|
|
9
|
+
const numWorkers = cpus().length;
|
|
10
|
+
console.log(`🍴 Master running, forking ${numWorkers} workers...`);
|
|
11
|
+
for (let i = 0; i < numWorkers; i++) {
|
|
12
|
+
cluster.fork();
|
|
13
|
+
}
|
|
14
|
+
let results = [];
|
|
15
|
+
for (const id in cluster.workers) {
|
|
16
|
+
cluster.workers[id]?.on("message", (msg) => {
|
|
17
|
+
if (msg.type === "result") {
|
|
18
|
+
results.push(msg.data);
|
|
19
|
+
if (results.length === numWorkers) {
|
|
20
|
+
console.log("\n📊 CLUSTER PERFORMANCE RESULTS:");
|
|
21
|
+
results.forEach((r) => {
|
|
22
|
+
console.log(`Worker ${r.workerId}: ${r.rps} RPS | Avg Latency: ${r.latency}ms | Total: ${r.total}, Success: ${r.success}`);
|
|
23
|
+
});
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Worker process
|
|
32
|
+
const app = createServer((req, res) => {
|
|
33
|
+
if (req.url === "/perf") {
|
|
34
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
35
|
+
res.end(JSON.stringify({ status: "ok", time: Date.now() }));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
res.writeHead(404);
|
|
39
|
+
res.end();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
app.listen(PORT, () => {
|
|
43
|
+
console.log(`Worker ${process.pid} listening on port ${PORT}`);
|
|
44
|
+
// Benchmark inside worker
|
|
45
|
+
let totalRequests = 0;
|
|
46
|
+
let successfulRequests = 0;
|
|
47
|
+
let totalLatency = 0;
|
|
48
|
+
const startTime = Date.now();
|
|
49
|
+
const http = require("http");
|
|
50
|
+
const makeRequest = () => {
|
|
51
|
+
const requestStart = Date.now();
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
if (Date.now() - startTime > DURATION_MS)
|
|
54
|
+
return resolve();
|
|
55
|
+
const req = http.get(`http://localhost:${PORT}/perf`, (res) => {
|
|
56
|
+
totalRequests++;
|
|
57
|
+
if (res.statusCode === 200)
|
|
58
|
+
successfulRequests++;
|
|
59
|
+
totalLatency += Date.now() - requestStart;
|
|
60
|
+
res.resume();
|
|
61
|
+
res.on("end", () => {
|
|
62
|
+
if (Date.now() - startTime < DURATION_MS)
|
|
63
|
+
makeRequest().then(resolve);
|
|
64
|
+
else
|
|
65
|
+
resolve();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
req.on("error", () => {
|
|
69
|
+
totalRequests++;
|
|
70
|
+
resolve();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const promises = Array.from({ length: CONCURRENCY }, () => makeRequest());
|
|
75
|
+
Promise.all(promises).then(() => {
|
|
76
|
+
const actualDuration = (Date.now() - startTime) / 1000;
|
|
77
|
+
const rps = (successfulRequests / actualDuration).toFixed(2);
|
|
78
|
+
const avgLatency = (totalLatency / successfulRequests).toFixed(2);
|
|
79
|
+
process.send?.({
|
|
80
|
+
type: "result",
|
|
81
|
+
data: {
|
|
82
|
+
workerId: process.pid,
|
|
83
|
+
total: totalRequests,
|
|
84
|
+
success: successfulRequests,
|
|
85
|
+
rps: Number(rps),
|
|
86
|
+
latency: Number(avgLatency),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=performance-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-test.js","sourceRoot":"","sources":["../src/performance-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
import { MongoMemoryServer } from 'mongodb-memory-server';
|
|
3
|
+
import { createDolphinServer } from './server/server';
|
|
4
|
+
import { createMongooseAdapter } from './adapters/mongoose';
|
|
5
|
+
import { createCrudController } from './curd/crud';
|
|
6
|
+
// Define a sample schema
|
|
7
|
+
const ProductSchema = new mongoose.Schema({
|
|
8
|
+
name: String,
|
|
9
|
+
price: Number,
|
|
10
|
+
category: String,
|
|
11
|
+
createdAt: String,
|
|
12
|
+
updatedAt: String,
|
|
13
|
+
});
|
|
14
|
+
const Product = mongoose.model('Product', ProductSchema);
|
|
15
|
+
const UserSchema = new mongoose.Schema({
|
|
16
|
+
email: String
|
|
17
|
+
});
|
|
18
|
+
const User = mongoose.model('User', UserSchema);
|
|
19
|
+
const RefreshTokenSchema = new mongoose.Schema({
|
|
20
|
+
token: String
|
|
21
|
+
});
|
|
22
|
+
const RefreshToken = mongoose.model('RefreshToken', RefreshTokenSchema);
|
|
23
|
+
async function runTest() {
|
|
24
|
+
console.log('🌱 Starting MongoDB Memory Server...');
|
|
25
|
+
const mongod = await MongoMemoryServer.create();
|
|
26
|
+
const uri = mongod.getUri();
|
|
27
|
+
await mongoose.connect(uri);
|
|
28
|
+
console.log('✅ Connected to MongoDB Memory Server');
|
|
29
|
+
// Create Mongoose adapter for Dolphin CRUD
|
|
30
|
+
const db = createMongooseAdapter({
|
|
31
|
+
User,
|
|
32
|
+
RefreshToken,
|
|
33
|
+
models: { Product },
|
|
34
|
+
leanByDefault: true,
|
|
35
|
+
softDelete: false
|
|
36
|
+
});
|
|
37
|
+
const app = createDolphinServer();
|
|
38
|
+
// Create CRUD Controller, disable enforceOwnership so it works publicly
|
|
39
|
+
const crud = createCrudController(db, "Product", { enforceOwnership: false });
|
|
40
|
+
// Map Routes
|
|
41
|
+
app.get('/products', crud.getAll);
|
|
42
|
+
app.get('/products/:id', crud.getOne);
|
|
43
|
+
app.post('/products', crud.create);
|
|
44
|
+
app.put('/products/:id', crud.update);
|
|
45
|
+
app.delete('/products/:id', crud.delete);
|
|
46
|
+
const server = app.listen(3002, async () => {
|
|
47
|
+
console.log('🚀 Server running on port 3002\n');
|
|
48
|
+
console.log('--- RUNNING TESTS ---\n');
|
|
49
|
+
try {
|
|
50
|
+
// 1. Create a Product
|
|
51
|
+
console.log('➡️ POST /products');
|
|
52
|
+
let res = await fetch('http://localhost:3002/products', {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: { 'Content-Type': 'application/json' },
|
|
55
|
+
body: JSON.stringify({ name: 'Real Mongoose iPhone', price: 999, category: 'Electronics' })
|
|
56
|
+
});
|
|
57
|
+
const createdItem = await res.json();
|
|
58
|
+
console.log('✅ Created:', createdItem, '\n');
|
|
59
|
+
// 2. Read All Products
|
|
60
|
+
const itemId = createdItem.id || createdItem._id;
|
|
61
|
+
console.log('➡️ GET /products');
|
|
62
|
+
res = await fetch('http://localhost:3002/products');
|
|
63
|
+
const allItems = await res.json();
|
|
64
|
+
console.log('✅ All Products:', allItems, '\n');
|
|
65
|
+
// 3. Read Single Product by ID
|
|
66
|
+
console.log(`➡️ GET /products/${itemId}`);
|
|
67
|
+
res = await fetch(`http://localhost:3002/products/${itemId}`);
|
|
68
|
+
let singleItem = await res.json();
|
|
69
|
+
console.log('✅ Single Product:', singleItem, '\n');
|
|
70
|
+
// 4. Update Product
|
|
71
|
+
console.log(`➡️ PUT /products/${itemId}`);
|
|
72
|
+
res = await fetch(`http://localhost:3002/products/${itemId}`, {
|
|
73
|
+
method: 'PUT',
|
|
74
|
+
headers: { 'Content-Type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({ price: 899 })
|
|
76
|
+
});
|
|
77
|
+
const updatedItem = await res.json();
|
|
78
|
+
console.log('✅ Updated Product:', updatedItem, '\n');
|
|
79
|
+
// 5. Delete Product
|
|
80
|
+
console.log(`➡️ DELETE /products/${createdItem.id}`);
|
|
81
|
+
res = await fetch(`http://localhost:3002/products/${createdItem.id}`, { method: 'DELETE' });
|
|
82
|
+
const deleteResult = await res.json();
|
|
83
|
+
console.log('✅ Delete Result:', deleteResult, '\n');
|
|
84
|
+
// 6. Ensure empty list now
|
|
85
|
+
console.log('➡️ GET /products (After Delete)');
|
|
86
|
+
res = await fetch('http://localhost:3002/products');
|
|
87
|
+
const finalItems = await res.json();
|
|
88
|
+
console.log('✅ All Products:', finalItems, '\n');
|
|
89
|
+
console.log('🎉 REAL MONGODB CRUD CONTROLLER TESTS PASSED!');
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
console.error('❌ Test failed:', err);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
// Cleanup
|
|
96
|
+
server.close();
|
|
97
|
+
await mongoose.disconnect();
|
|
98
|
+
await mongod.stop();
|
|
99
|
+
process.exit(0);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
runTest().catch(console.error);
|
|
104
|
+
//# sourceMappingURL=real-test-mongoose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"real-test-mongoose.js","sourceRoot":"","sources":["../src/real-test-mongoose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { RealtimeCore } from './core';
|
|
3
|
+
/**
|
|
4
|
+
* Supported camera frame codec types
|
|
5
|
+
*/
|
|
6
|
+
export type CameraCodec = 'MJPEG' | 'H264' | 'H265' | 'RAW_RGB' | 'RAW_YUV' | 'UNKNOWN';
|
|
7
|
+
/**
|
|
8
|
+
* Parsed camera frame metadata
|
|
9
|
+
*/
|
|
10
|
+
export interface CameraFrame {
|
|
11
|
+
cameraId: string;
|
|
12
|
+
codec: CameraCodec;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
frameIndex: number;
|
|
17
|
+
isKeyFrame: boolean;
|
|
18
|
+
data: Buffer;
|
|
19
|
+
sizeBytes: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Camera registration options
|
|
23
|
+
*/
|
|
24
|
+
export interface CameraOptions {
|
|
25
|
+
cameraId: string;
|
|
26
|
+
codec?: CameraCodec;
|
|
27
|
+
expectedWidth?: number;
|
|
28
|
+
expectedHeight?: number;
|
|
29
|
+
maxFps?: number;
|
|
30
|
+
recordingEnabled?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Camera stats per camera
|
|
34
|
+
*/
|
|
35
|
+
interface CameraStats {
|
|
36
|
+
cameraId: string;
|
|
37
|
+
framesReceived: number;
|
|
38
|
+
bytesReceived: number;
|
|
39
|
+
fps: number;
|
|
40
|
+
lastFrameAt: number;
|
|
41
|
+
codec: CameraCodec;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
isOnline: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* CameraFrameModule — Direct binary camera frame handler for RealtimeCore
|
|
48
|
+
*
|
|
49
|
+
* Handles raw binary frames from IP cameras without needing FFmpeg.
|
|
50
|
+
* Supports MJPEG, H.264, H.265, RAW_RGB, RAW_YUV formats.
|
|
51
|
+
*
|
|
52
|
+
* Usage:
|
|
53
|
+
* const cam = new CameraFrameModule(rt);
|
|
54
|
+
* cam.registerCamera({ cameraId: 'cam1', codec: 'MJPEG' });
|
|
55
|
+
* cam.ingestFrame('cam1', frameBuffer);
|
|
56
|
+
* cam.subscribe('cam1', (frame) => { ... });
|
|
57
|
+
*/
|
|
58
|
+
export declare class CameraFrameModule extends EventEmitter {
|
|
59
|
+
private rt;
|
|
60
|
+
private cameras;
|
|
61
|
+
private frameCounters;
|
|
62
|
+
private fpsTrackers;
|
|
63
|
+
private offlineTimers;
|
|
64
|
+
private readonly OFFLINE_TIMEOUT_MS;
|
|
65
|
+
private readonly FPS_WINDOW_MS;
|
|
66
|
+
constructor(rt: RealtimeCore);
|
|
67
|
+
/**
|
|
68
|
+
* Register a camera before ingesting frames
|
|
69
|
+
*/
|
|
70
|
+
registerCamera(opts: CameraOptions): void;
|
|
71
|
+
/**
|
|
72
|
+
* Ingest a raw binary frame from a camera.
|
|
73
|
+
* Auto-detects codec if not registered.
|
|
74
|
+
* Publishes to RealtimeCore topic: camera/<cameraId>/frame
|
|
75
|
+
*/
|
|
76
|
+
ingestFrame(cameraId: string, rawBuffer: Buffer): CameraFrame | null;
|
|
77
|
+
/**
|
|
78
|
+
* Subscribe to frames from a specific camera
|
|
79
|
+
*/
|
|
80
|
+
subscribe(cameraId: string, fn: (frame: CameraFrame) => void): void;
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe to ALL cameras
|
|
83
|
+
*/
|
|
84
|
+
subscribeAll(fn: (frame: CameraFrame) => void): void;
|
|
85
|
+
/**
|
|
86
|
+
* Unsubscribe from a camera
|
|
87
|
+
*/
|
|
88
|
+
unsubscribe(cameraId: string, fn: (frame: CameraFrame) => void): void;
|
|
89
|
+
/**
|
|
90
|
+
* Get live stats for a camera
|
|
91
|
+
*/
|
|
92
|
+
getStats(cameraId: string): CameraStats | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Get stats for all cameras
|
|
95
|
+
*/
|
|
96
|
+
getAllStats(): CameraStats[];
|
|
97
|
+
/**
|
|
98
|
+
* List registered camera IDs
|
|
99
|
+
*/
|
|
100
|
+
listCameras(): string[];
|
|
101
|
+
/**
|
|
102
|
+
* Mark a camera as offline manually
|
|
103
|
+
*/
|
|
104
|
+
markOffline(cameraId: string): void;
|
|
105
|
+
/**
|
|
106
|
+
* Remove a camera from the module
|
|
107
|
+
*/
|
|
108
|
+
removeCamera(cameraId: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Destroy the module and clean up
|
|
111
|
+
*/
|
|
112
|
+
destroy(): void;
|
|
113
|
+
private _resetOfflineTimer;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Factory function
|
|
117
|
+
*/
|
|
118
|
+
export declare function createCameraModule(rt: RealtimeCore): CameraFrameModule;
|
|
119
|
+
export {};
|