@forgeax/engine-remote 0.1.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/LICENSE +202 -0
- package/README.md +269 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/asset-runtime-inspection.unit.test.d.ts +2 -0
- package/dist/__tests__/asset-runtime-inspection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/console.unit.test.d.ts +2 -0
- package/dist/__tests__/console.unit.test.d.ts.map +1 -0
- package/dist/__tests__/errors.unit.test.d.ts +2 -0
- package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/execute-browser-safe.unit.test.d.ts +2 -0
- package/dist/__tests__/execute-browser-safe.unit.test.d.ts.map +1 -0
- package/dist/__tests__/execute-profiler-root.browser.test.d.ts +2 -0
- package/dist/__tests__/execute-profiler-root.browser.test.d.ts.map +1 -0
- package/dist/__tests__/execute.async.test.d.ts +2 -0
- package/dist/__tests__/execute.async.test.d.ts.map +1 -0
- package/dist/__tests__/execution-report-root.unit.test.d.ts +2 -0
- package/dist/__tests__/execution-report-root.unit.test.d.ts.map +1 -0
- package/dist/__tests__/introspect-profiler.unit.test.d.ts +2 -0
- package/dist/__tests__/introspect-profiler.unit.test.d.ts.map +1 -0
- package/dist/__tests__/method-roster-profiler.test.d.ts +2 -0
- package/dist/__tests__/method-roster-profiler.test.d.ts.map +1 -0
- package/dist/__tests__/rhi-capture-remote.integration.test.d.ts +2 -0
- package/dist/__tests__/rhi-capture-remote.integration.test.d.ts.map +1 -0
- package/dist/__tests__/server.unit.test.d.ts +2 -0
- package/dist/__tests__/server.unit.test.d.ts.map +1 -0
- package/dist/error-messages.d.ts +3 -0
- package/dist/error-messages.d.ts.map +1 -0
- package/dist/errors.d.ts +82 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.mjs +37 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/execute.d.ts +31 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.mjs +93 -0
- package/dist/execute.mjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +30 -0
- package/dist/index.mjs.map +1 -0
- package/dist/introspect.d.ts +21 -0
- package/dist/introspect.d.ts.map +1 -0
- package/dist/introspect.mjs +173 -0
- package/dist/introspect.mjs.map +1 -0
- package/dist/server.d.ts +35 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.mjs +473 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +78 -0
- package/src/__tests__/asset-runtime-inspection.unit.test.ts +16 -0
- package/src/__tests__/console.unit.test.ts +12 -0
- package/src/__tests__/errors.unit.test.ts +102 -0
- package/src/__tests__/execute-browser-safe.unit.test.ts +43 -0
- package/src/__tests__/execute-profiler-root.browser.test.ts +41 -0
- package/src/__tests__/execute.async.test.ts +369 -0
- package/src/__tests__/execution-report-root.unit.test.ts +38 -0
- package/src/__tests__/introspect-profiler.unit.test.ts +55 -0
- package/src/__tests__/method-roster-profiler.test.ts +80 -0
- package/src/__tests__/rhi-capture-remote.integration.test.ts +58 -0
- package/src/__tests__/server.unit.test.ts +856 -0
- package/src/__tests__/vm-async-eval-verify.mjs +149 -0
- package/src/error-messages.ts +9 -0
- package/src/errors.ts +143 -0
- package/src/execute.ts +152 -0
- package/src/index.ts +19 -0
- package/src/introspect.ts +223 -0
- package/src/server.ts +331 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createProfiler } from '@forgeax/engine-profiler';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { WebSocket } from 'ws';
|
|
4
|
+
|
|
5
|
+
import { startServer } from '../server';
|
|
6
|
+
|
|
7
|
+
type Response = {
|
|
8
|
+
result?: { methods?: Array<{ name: string }>; roots?: Record<string, unknown> };
|
|
9
|
+
error?: { code: number; data?: { code?: string } };
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
async function connect(port: number): Promise<WebSocket> {
|
|
13
|
+
const ws = new WebSocket(`ws://127.0.0.1:${port}/inspector`);
|
|
14
|
+
await new Promise<void>((resolve, reject) => {
|
|
15
|
+
ws.once('open', resolve);
|
|
16
|
+
ws.once('error', reject);
|
|
17
|
+
});
|
|
18
|
+
return ws;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function request(ws: WebSocket, payload: unknown): Promise<Response> {
|
|
22
|
+
return new Promise<Response>((resolve, reject) => {
|
|
23
|
+
const onMessage = (raw: WebSocket.RawData): void => {
|
|
24
|
+
ws.off('message', onMessage);
|
|
25
|
+
try {
|
|
26
|
+
resolve(JSON.parse(raw.toString()) as Response);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
reject(error);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
ws.on('message', onMessage);
|
|
32
|
+
ws.send(JSON.stringify(payload));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('remote profiler method roster', () => {
|
|
37
|
+
it('keeps profiler capability inside eval/introspect without adding an RPC method', async () => {
|
|
38
|
+
const profiler = createProfiler();
|
|
39
|
+
const started = await startServer({ port: 0, host: '127.0.0.1', world: {}, profiler });
|
|
40
|
+
expect(started.ok).toBe(true);
|
|
41
|
+
if (!started.ok) return;
|
|
42
|
+
|
|
43
|
+
const ws = await connect(started.value.port);
|
|
44
|
+
try {
|
|
45
|
+
const response = await request(ws, {
|
|
46
|
+
jsonrpc: '2.0',
|
|
47
|
+
method: 'introspect',
|
|
48
|
+
id: 1,
|
|
49
|
+
});
|
|
50
|
+
expect(response.result?.methods?.map((method) => method.name)).toEqual([
|
|
51
|
+
'eval',
|
|
52
|
+
'introspect',
|
|
53
|
+
]);
|
|
54
|
+
expect(response.result?.roots?.profiler).toBeDefined();
|
|
55
|
+
} finally {
|
|
56
|
+
ws.close();
|
|
57
|
+
await started.value.close();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('keeps the existing JSON-RPC error mapping for unknown methods', async () => {
|
|
62
|
+
const started = await startServer({ port: 0, host: '127.0.0.1', world: {} });
|
|
63
|
+
expect(started.ok).toBe(true);
|
|
64
|
+
if (!started.ok) return;
|
|
65
|
+
|
|
66
|
+
const ws = await connect(started.value.port);
|
|
67
|
+
try {
|
|
68
|
+
const response = await request(ws, {
|
|
69
|
+
jsonrpc: '2.0',
|
|
70
|
+
method: 'profile.capture',
|
|
71
|
+
id: 2,
|
|
72
|
+
});
|
|
73
|
+
expect(response.error?.code).toBe(-32601);
|
|
74
|
+
expect(response.error?.data).toBeUndefined();
|
|
75
|
+
} finally {
|
|
76
|
+
ws.close();
|
|
77
|
+
await started.value.close();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ok } from '@forgeax/engine-types';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { executeScript } from '../execute';
|
|
4
|
+
import { buildIntrospectDoc } from '../introspect';
|
|
5
|
+
|
|
6
|
+
const rhiCapture = {
|
|
7
|
+
captureFrame: async () =>
|
|
8
|
+
ok({
|
|
9
|
+
kind: 'rhi-tape' as const,
|
|
10
|
+
digest: 'sha256:remote-contract',
|
|
11
|
+
bytes: new Uint8Array([1, 2, 3]),
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
describe('remote RHI capture capability', () => {
|
|
16
|
+
it('exposes capture only and returns the terminal artifact', async () => {
|
|
17
|
+
const result = await executeScript('rhiCapture.captureFrame()', {
|
|
18
|
+
world: {},
|
|
19
|
+
renderer: {},
|
|
20
|
+
assets: {},
|
|
21
|
+
rhiCapture,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(result).toEqual({
|
|
25
|
+
ok: true,
|
|
26
|
+
value: {
|
|
27
|
+
ok: true,
|
|
28
|
+
value: {
|
|
29
|
+
kind: 'rhi-tape',
|
|
30
|
+
digest: 'sha256:remote-contract',
|
|
31
|
+
bytes: new Uint8Array([1, 2, 3]),
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('introspects one capture capability without live replay roots', () => {
|
|
38
|
+
const document = buildIntrospectDoc('127.0.0.1', 5732, {
|
|
39
|
+
world: {},
|
|
40
|
+
renderer: {},
|
|
41
|
+
assets: {},
|
|
42
|
+
rhiCapture,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(document).toMatchObject({
|
|
46
|
+
roots: {
|
|
47
|
+
rhiCapture: {
|
|
48
|
+
available: true,
|
|
49
|
+
type: 'RhiCapture',
|
|
50
|
+
capability: 'rhi-capture-v1',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
expect((document as { roots: Record<string, unknown> }).roots).not.toHaveProperty(
|
|
55
|
+
'legacyCapture',
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|