orez 0.0.46 → 0.0.47

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 (58) hide show
  1. package/README.md +4 -8
  2. package/dist/admin/http-proxy.d.ts +31 -0
  3. package/dist/admin/http-proxy.d.ts.map +1 -0
  4. package/dist/admin/http-proxy.js +140 -0
  5. package/dist/admin/http-proxy.js.map +1 -0
  6. package/dist/admin/log-store.d.ts +22 -0
  7. package/dist/admin/log-store.d.ts.map +1 -0
  8. package/dist/admin/log-store.js +86 -0
  9. package/dist/admin/log-store.js.map +1 -0
  10. package/dist/admin/server.d.ts +19 -0
  11. package/dist/admin/server.d.ts.map +1 -0
  12. package/dist/admin/server.js +110 -0
  13. package/dist/admin/server.js.map +1 -0
  14. package/dist/admin/ui.d.ts +2 -0
  15. package/dist/admin/ui.d.ts.map +1 -0
  16. package/dist/admin/ui.js +683 -0
  17. package/dist/admin/ui.js.map +1 -0
  18. package/dist/cli.js +48 -1
  19. package/dist/cli.js.map +1 -1
  20. package/dist/config.d.ts +4 -0
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +4 -0
  23. package/dist/config.js.map +1 -1
  24. package/dist/index.d.ts +9 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +180 -20
  27. package/dist/index.js.map +1 -1
  28. package/dist/log.d.ts +9 -0
  29. package/dist/log.d.ts.map +1 -1
  30. package/dist/log.js +24 -1
  31. package/dist/log.js.map +1 -1
  32. package/dist/pg-proxy.d.ts.map +1 -1
  33. package/dist/pg-proxy.js +19 -4
  34. package/dist/pg-proxy.js.map +1 -1
  35. package/dist/pglite-manager.d.ts +1 -0
  36. package/dist/pglite-manager.d.ts.map +1 -1
  37. package/dist/pglite-manager.js +1 -1
  38. package/dist/pglite-manager.js.map +1 -1
  39. package/dist/replication/handler.d.ts.map +1 -1
  40. package/dist/replication/handler.js +20 -2
  41. package/dist/replication/handler.js.map +1 -1
  42. package/dist/vite-plugin.d.ts +3 -0
  43. package/dist/vite-plugin.d.ts.map +1 -1
  44. package/dist/vite-plugin.js +24 -0
  45. package/dist/vite-plugin.js.map +1 -1
  46. package/package.json +4 -2
  47. package/src/admin/http-proxy.ts +186 -0
  48. package/src/admin/log-store.ts +111 -0
  49. package/src/admin/server.ts +148 -0
  50. package/src/admin/ui.ts +682 -0
  51. package/src/cli.ts +49 -1
  52. package/src/config.ts +8 -0
  53. package/src/index.ts +192 -20
  54. package/src/log.ts +25 -1
  55. package/src/pg-proxy.ts +26 -6
  56. package/src/pglite-manager.ts +1 -1
  57. package/src/replication/handler.ts +21 -2
  58. package/src/vite-plugin.ts +28 -0
package/README.md CHANGED
@@ -1,18 +1,14 @@
1
1
  # orez
2
2
 
3
- [Zero](https://zero.rocicorp.dev) and [PGlite](https://pglite.dev) made to play well together, with no native dependencies. Helped by a custom WASM fork of SQLite's [bedrock branch](https://sqlite.org/src/timeline?t=begin-concurrent) called [bedrock-sqlite](https://www.npmjs.com/package/bedrock-sqlite), and [pgsql-parser](https://www.npmjs.com/package/pgsql-parser) (the real PostgreSQL C parser compiled to WASM) for SQL analysis. No Docker, no Postgres install, no `node-gyp`, no platform-specific binaries.
3
+ [Zero](https://zero.rocicorp.dev) is amazing, but setting it up alongside Postgres requires effort, native dependencies, and oftentimes Docker.
4
+
5
+ orez makes [PGlite](https://pglite.dev) work with Zero with a few things - a proxy that adds logical replication to PGLite, and then a bunch of iterations figuring out setup and setting that make them both happy together. To remove all native dependences, orez also ships a custom WASM fork of the same SQLite [bedrock branch](https://sqlite.org/src/timeline?t=begin-concurrent) that Zero uses. Inlcudes a CLI, programmatic API, and Vite plugin.
4
6
 
5
7
  ```
6
8
  bunx orez
7
9
  ```
8
10
 
9
- Starts PGlite (WASM Postgres), a TCP proxy, and zero-cache with WASM SQLite. Exports a CLI, programmatic API, and Vite plugin. Comes with PGlite extensions `pgvector` and `pg_trgm` enabled by default. Includes `pg_dump` and `pg_restore` subcommands that can restore production Postgres dumps directly into PGlite — handling COPY→INSERT conversion, unsupported extension filtering, idempotent DDL rewriting, and WASM memory management automatically.
10
-
11
- Auto-configures Node heap size based on system memory, adaptively polls for replication changes (~500x faster catch-up after large restores), purges consumed WAL changes to prevent WASM OOM, and auto-tracks tables created at runtime via DDL event triggers.
12
-
13
- <p align="center">
14
- <img src="logo.svg" alt="orez is hebrew for rice — zero, pglite, and sqlite-wasm hanging out" width="320" />
15
- </p>
11
+ orez auto-configures Node heap size based on system memory, adaptively polls for replication changes (~500x faster catch-up after large restores), purges consumed WAL changes to prevent WASM OOM, and auto-tracks tables created at runtime via DDL event triggers. Includes `pg_dump` and `pg_restore` subcommands that can restore production Postgres dumps directly into PGlite — handling COPY→INSERT conversion, unsupported extension filtering, idempotent DDL rewriting, and WASM memory management automatically. It uses [pgsql-parser](https://www.npmjs.com/package/pgsql-parser) (the real PostgreSQL C parser, compiled to WASM) for SQL analysis. Comes with PGlite extensions `pgvector` and `pg_trgm` enabled by default.
16
12
 
17
13
  ## CLI
18
14
 
@@ -0,0 +1,31 @@
1
+ import { type Server } from 'node:http';
2
+ export interface HttpLogEntry {
3
+ id: number;
4
+ ts: number;
5
+ method: string;
6
+ path: string;
7
+ status: number;
8
+ duration: number;
9
+ reqSize: number;
10
+ resSize: number;
11
+ reqHeaders: Record<string, string>;
12
+ resHeaders: Record<string, string>;
13
+ }
14
+ export interface HttpLogStore {
15
+ push(entry: Omit<HttpLogEntry, 'id'>): void;
16
+ query(opts?: {
17
+ since?: number;
18
+ path?: string;
19
+ }): {
20
+ entries: HttpLogEntry[];
21
+ cursor: number;
22
+ };
23
+ clear(): void;
24
+ }
25
+ export declare function createHttpLogStore(): HttpLogStore;
26
+ export declare function startHttpProxy(opts: {
27
+ listenPort: number;
28
+ targetPort: number;
29
+ httpLog: HttpLogStore;
30
+ }): Promise<Server>;
31
+ //# sourceMappingURL=http-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-proxy.d.ts","sourceRoot":"","sources":["../../src/admin/http-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,MAAM,EAGZ,MAAM,WAAW,CAAA;AAGlB,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;IAC3C,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5F,KAAK,IAAI,IAAI,CAAA;CACd;AAID,wBAAgB,kBAAkB,IAAI,YAAY,CAsCjD;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,YAAY,CAAA;CACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuGlB"}
@@ -0,0 +1,140 @@
1
+ import { createServer, request as httpRequest, } from 'node:http';
2
+ const MAX_ENTRIES = 10_000;
3
+ export function createHttpLogStore() {
4
+ const entries = [];
5
+ let nextId = 1;
6
+ function push(entry) {
7
+ const full = { ...entry, id: nextId++ };
8
+ entries.push(full);
9
+ if (entries.length > MAX_ENTRIES)
10
+ entries.splice(0, entries.length - MAX_ENTRIES);
11
+ }
12
+ function query(opts) {
13
+ let result = entries;
14
+ if (opts?.since) {
15
+ const since = opts.since;
16
+ let lo = 0;
17
+ let hi = result.length;
18
+ while (lo < hi) {
19
+ const mid = (lo + hi) >>> 1;
20
+ if (result[mid].id <= since)
21
+ lo = mid + 1;
22
+ else
23
+ hi = mid;
24
+ }
25
+ result = result.slice(lo);
26
+ }
27
+ if (opts?.path) {
28
+ const p = opts.path;
29
+ result = result.filter((e) => e.path.includes(p));
30
+ }
31
+ return {
32
+ entries: result,
33
+ cursor: entries.length > 0 ? entries[entries.length - 1].id : 0,
34
+ };
35
+ }
36
+ function clear() {
37
+ entries.length = 0;
38
+ }
39
+ return { push, query, clear };
40
+ }
41
+ function flatHeaders(headers) {
42
+ const out = {};
43
+ for (const [k, v] of Object.entries(headers)) {
44
+ out[k] = Array.isArray(v) ? v.join(', ') : String(v ?? '');
45
+ }
46
+ return out;
47
+ }
48
+ export function startHttpProxy(opts) {
49
+ const { listenPort, targetPort, httpLog } = opts;
50
+ const server = createServer((req, res) => {
51
+ const start = Date.now();
52
+ let reqSize = 0;
53
+ const reqChunks = [];
54
+ req.on('data', (chunk) => {
55
+ reqSize += chunk.length;
56
+ reqChunks.push(chunk);
57
+ });
58
+ req.on('end', () => {
59
+ const proxyReq = httpRequest({
60
+ hostname: '127.0.0.1',
61
+ port: targetPort,
62
+ path: req.url,
63
+ method: req.method,
64
+ headers: req.headers,
65
+ }, (proxyRes) => {
66
+ let resSize = 0;
67
+ proxyRes.on('data', (chunk) => {
68
+ resSize += chunk.length;
69
+ });
70
+ proxyRes.on('end', () => {
71
+ httpLog.push({
72
+ ts: start,
73
+ method: req.method || 'GET',
74
+ path: req.url || '/',
75
+ status: proxyRes.statusCode || 0,
76
+ duration: Date.now() - start,
77
+ reqSize,
78
+ resSize,
79
+ reqHeaders: flatHeaders(req.headers),
80
+ resHeaders: flatHeaders(proxyRes.headers),
81
+ });
82
+ });
83
+ res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
84
+ proxyRes.pipe(res);
85
+ });
86
+ proxyReq.on('error', (err) => {
87
+ res.writeHead(502);
88
+ res.end('proxy error: ' + err.message);
89
+ });
90
+ for (const chunk of reqChunks)
91
+ proxyReq.write(chunk);
92
+ proxyReq.end();
93
+ });
94
+ });
95
+ // websocket upgrade passthrough
96
+ server.on('upgrade', (req, socket, head) => {
97
+ const start = Date.now();
98
+ const proxyReq = httpRequest({
99
+ hostname: '127.0.0.1',
100
+ port: targetPort,
101
+ path: req.url,
102
+ method: req.method,
103
+ headers: req.headers,
104
+ });
105
+ proxyReq.on('upgrade', (proxyRes, proxySocket, proxyHead) => {
106
+ httpLog.push({
107
+ ts: start,
108
+ method: 'WS',
109
+ path: req.url || '/',
110
+ status: 101,
111
+ duration: Date.now() - start,
112
+ reqSize: 0,
113
+ resSize: 0,
114
+ reqHeaders: flatHeaders(req.headers),
115
+ resHeaders: flatHeaders(proxyRes.headers),
116
+ });
117
+ // forward the 101 response
118
+ let rawHeaders = 'HTTP/1.1 101 Switching Protocols\r\n';
119
+ for (const [k, v] of Object.entries(proxyRes.headers)) {
120
+ rawHeaders += `${k}: ${Array.isArray(v) ? v.join(', ') : v}\r\n`;
121
+ }
122
+ rawHeaders += '\r\n';
123
+ socket.write(rawHeaders);
124
+ if (proxyHead.length)
125
+ socket.write(proxyHead);
126
+ proxySocket.pipe(socket);
127
+ socket.pipe(proxySocket);
128
+ proxySocket.on('error', () => socket.destroy());
129
+ socket.on('error', () => proxySocket.destroy());
130
+ });
131
+ proxyReq.on('error', () => socket.destroy());
132
+ proxyReq.write(head);
133
+ proxyReq.end();
134
+ });
135
+ return new Promise((resolve, reject) => {
136
+ server.listen(listenPort, '127.0.0.1', () => resolve(server));
137
+ server.on('error', reject);
138
+ });
139
+ }
140
+ //# sourceMappingURL=http-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-proxy.js","sourceRoot":"","sources":["../../src/admin/http-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface LogEntry {
2
+ id: number;
3
+ ts: number;
4
+ source: string;
5
+ level: string;
6
+ msg: string;
7
+ }
8
+ export interface LogStore {
9
+ push(source: string, level: string, msg: string): void;
10
+ query(opts?: {
11
+ source?: string;
12
+ level?: string;
13
+ since?: number;
14
+ }): {
15
+ entries: LogEntry[];
16
+ cursor: number;
17
+ };
18
+ getAll(): LogEntry[];
19
+ clear(): void;
20
+ }
21
+ export declare function createLogStore(dataDir: string, writeToDisk?: boolean): LogStore;
22
+ //# sourceMappingURL=log-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-store.d.ts","sourceRoot":"","sources":["../../src/admin/log-store.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACtD,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QACjE,OAAO,EAAE,QAAQ,EAAE,CAAA;QACnB,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,MAAM,IAAI,QAAQ,EAAE,CAAA;IACpB,KAAK,IAAI,IAAI,CAAA;CACd;AAOD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,UAAO,GAAG,QAAQ,CAoF5E"}
@@ -0,0 +1,86 @@
1
+ import { existsSync, mkdirSync, appendFileSync, statSync, renameSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const ANSI_RE = /\x1b\[[0-9;]*m/g;
4
+ const MAX_ENTRIES = 50_000;
5
+ const MAX_FILE_SIZE = 5 * 1024 * 1024;
6
+ const LEVEL_PRIORITY = { error: 0, warn: 1, info: 2, debug: 3 };
7
+ export function createLogStore(dataDir, writeToDisk = true) {
8
+ const entries = [];
9
+ let nextId = 1;
10
+ const logsDir = join(dataDir, 'logs');
11
+ const logFile = join(logsDir, 'orez.log');
12
+ const backupFile = join(logsDir, 'orez.log.1');
13
+ if (writeToDisk) {
14
+ mkdirSync(logsDir, { recursive: true });
15
+ }
16
+ function rotateIfNeeded() {
17
+ if (!writeToDisk)
18
+ return;
19
+ try {
20
+ if (!existsSync(logFile))
21
+ return;
22
+ const stat = statSync(logFile);
23
+ if (stat.size > MAX_FILE_SIZE) {
24
+ renameSync(logFile, backupFile);
25
+ }
26
+ }
27
+ catch { }
28
+ }
29
+ function push(source, level, msg) {
30
+ const entry = {
31
+ id: nextId++,
32
+ ts: Date.now(),
33
+ source,
34
+ level,
35
+ msg: msg.replace(ANSI_RE, ''),
36
+ };
37
+ entries.push(entry);
38
+ if (entries.length > MAX_ENTRIES) {
39
+ entries.splice(0, entries.length - MAX_ENTRIES);
40
+ }
41
+ if (writeToDisk) {
42
+ try {
43
+ const ts = new Date(entry.ts).toISOString();
44
+ appendFileSync(logFile, '[' + ts + '] [' + source + '] [' + level + '] ' + entry.msg + '\n');
45
+ rotateIfNeeded();
46
+ }
47
+ catch { }
48
+ }
49
+ }
50
+ function query(opts) {
51
+ let result = entries;
52
+ if (opts?.since) {
53
+ const since = opts.since;
54
+ let lo = 0;
55
+ let hi = result.length;
56
+ while (lo < hi) {
57
+ const mid = (lo + hi) >>> 1;
58
+ if (result[mid].id <= since)
59
+ lo = mid + 1;
60
+ else
61
+ hi = mid;
62
+ }
63
+ result = result.slice(lo);
64
+ }
65
+ if (opts?.source) {
66
+ const source = opts.source;
67
+ result = result.filter((e) => e.source === source);
68
+ }
69
+ if (opts?.level) {
70
+ const maxPriority = LEVEL_PRIORITY[opts.level] ?? 3;
71
+ result = result.filter((e) => (LEVEL_PRIORITY[e.level] ?? 3) <= maxPriority);
72
+ }
73
+ return {
74
+ entries: result,
75
+ cursor: entries.length > 0 ? entries[entries.length - 1].id : 0,
76
+ };
77
+ }
78
+ function getAll() {
79
+ return [...entries];
80
+ }
81
+ function clear() {
82
+ entries.length = 0;
83
+ }
84
+ return { push, query, getAll, clear };
85
+ }
86
+ //# sourceMappingURL=log-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-store.js","sourceRoot":"","sources":["../../src/admin/log-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type Server } from 'node:http';
2
+ import type { LogStore } from './log-store.js';
3
+ import type { HttpLogStore } from './http-proxy.js';
4
+ import type { ZeroLiteConfig } from '../config.js';
5
+ export interface AdminActions {
6
+ restartZero?: () => Promise<void>;
7
+ resetZero?: () => Promise<void>;
8
+ }
9
+ export interface AdminServerOpts {
10
+ port: number;
11
+ logStore: LogStore;
12
+ config: ZeroLiteConfig;
13
+ zeroEnv: Record<string, string>;
14
+ actions?: AdminActions;
15
+ startTime: number;
16
+ httpLog?: HttpLogStore;
17
+ }
18
+ export declare function startAdminServer(opts: AdminServerOpts): Promise<Server>;
19
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/admin/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAGZ,MAAM,WAAW,CAAA;AAGlB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,QAAQ,CAAA;IAClB,MAAM,EAAE,cAAc,CAAA;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB;AAgBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA0GvE"}
@@ -0,0 +1,110 @@
1
+ import { createServer, } from 'node:http';
2
+ import { log } from '../log.js';
3
+ import { getAdminHtml } from './ui.js';
4
+ function corsHeaders() {
5
+ return {
6
+ 'Access-Control-Allow-Origin': '*',
7
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
8
+ 'Access-Control-Allow-Headers': '*',
9
+ };
10
+ }
11
+ function json(res, data, status = 200) {
12
+ const headers = { ...corsHeaders(), 'Content-Type': 'application/json' };
13
+ res.writeHead(status, headers);
14
+ res.end(JSON.stringify(data));
15
+ }
16
+ export function startAdminServer(opts) {
17
+ const { logStore, config, zeroEnv, actions, startTime } = opts;
18
+ const html = getAdminHtml();
19
+ const server = createServer(async (req, res) => {
20
+ const headers = corsHeaders();
21
+ if (req.method === 'OPTIONS') {
22
+ res.writeHead(200, headers);
23
+ res.end();
24
+ return;
25
+ }
26
+ const url = new URL(req.url || '/', 'http://localhost:' + opts.port);
27
+ try {
28
+ if (req.method === 'GET' && url.pathname === '/') {
29
+ res.writeHead(200, { ...headers, 'Content-Type': 'text/html' });
30
+ res.end(html);
31
+ return;
32
+ }
33
+ if (req.method === 'GET' && url.pathname === '/api/logs') {
34
+ const source = url.searchParams.get('source') || undefined;
35
+ const level = url.searchParams.get('level') || undefined;
36
+ const sinceStr = url.searchParams.get('since');
37
+ const since = sinceStr ? Number(sinceStr) : undefined;
38
+ json(res, logStore.query({ source, level, since }));
39
+ return;
40
+ }
41
+ if (req.method === 'GET' && url.pathname === '/api/env') {
42
+ const filtered = Object.entries(zeroEnv)
43
+ .filter(([k]) => k.startsWith('ZERO_') || k === 'NODE_ENV' || k === 'NODE_OPTIONS')
44
+ .sort(([a], [b]) => a.localeCompare(b));
45
+ json(res, { env: Object.fromEntries(filtered) });
46
+ return;
47
+ }
48
+ if (req.method === 'GET' && url.pathname === '/api/status') {
49
+ json(res, {
50
+ pgPort: config.pgPort,
51
+ zeroPort: config.zeroPort,
52
+ adminPort: opts.port,
53
+ uptime: Math.floor((Date.now() - startTime) / 1000),
54
+ logLevel: config.logLevel,
55
+ skipZeroCache: config.skipZeroCache,
56
+ });
57
+ return;
58
+ }
59
+ if (req.method === 'POST' && url.pathname === '/api/actions/restart-zero') {
60
+ if (!actions?.restartZero) {
61
+ json(res, { ok: false, message: 'zero-cache not running' }, 400);
62
+ return;
63
+ }
64
+ log.orez('admin: restarting zero-cache');
65
+ await actions.restartZero();
66
+ json(res, { ok: true, message: 'zero-cache restarted' });
67
+ return;
68
+ }
69
+ if (req.method === 'POST' && url.pathname === '/api/actions/reset-zero') {
70
+ if (!actions?.resetZero) {
71
+ json(res, { ok: false, message: 'zero-cache not running' }, 400);
72
+ return;
73
+ }
74
+ log.orez('admin: resetting zero-cache');
75
+ await actions.resetZero();
76
+ json(res, { ok: true, message: 'zero-cache reset and restarted' });
77
+ return;
78
+ }
79
+ if (req.method === 'POST' && url.pathname === '/api/actions/clear-logs') {
80
+ logStore.clear();
81
+ json(res, { ok: true, message: 'logs cleared' });
82
+ return;
83
+ }
84
+ if (req.method === 'GET' && url.pathname === '/api/http-log') {
85
+ const sinceStr = url.searchParams.get('since');
86
+ const path = url.searchParams.get('path') || undefined;
87
+ const since = sinceStr ? Number(sinceStr) : undefined;
88
+ json(res, opts.httpLog?.query({ since, path }) || { entries: [], cursor: 0 });
89
+ return;
90
+ }
91
+ if (req.method === 'POST' && url.pathname === '/api/actions/clear-http') {
92
+ opts.httpLog?.clear();
93
+ json(res, { ok: true, message: 'http log cleared' });
94
+ return;
95
+ }
96
+ res.writeHead(404, headers);
97
+ res.end('not found');
98
+ }
99
+ catch (err) {
100
+ json(res, { error: err?.message ?? 'internal error' }, 500);
101
+ }
102
+ });
103
+ return new Promise((resolve, reject) => {
104
+ server.listen(opts.port, '127.0.0.1', () => {
105
+ resolve(server);
106
+ });
107
+ server.on('error', reject);
108
+ });
109
+ }
110
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/admin/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function getAdminHtml(): string;
2
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/admin/ui.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,IAAI,MAAM,CAyqBrC"}