@plures/pluresdb 1.4.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.
- package/LICENSE +72 -0
- package/README.md +450 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/better-sqlite3-shared.d.ts +12 -0
- package/dist/better-sqlite3-shared.d.ts.map +1 -0
- package/dist/better-sqlite3-shared.js +143 -0
- package/dist/better-sqlite3-shared.js.map +1 -0
- package/dist/better-sqlite3.d.ts +4 -0
- package/dist/better-sqlite3.d.ts.map +1 -0
- package/dist/better-sqlite3.js +8 -0
- package/dist/better-sqlite3.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +258 -0
- package/dist/cli.js.map +1 -0
- package/dist/node-index.d.ts +148 -0
- package/dist/node-index.d.ts.map +1 -0
- package/dist/node-index.js +665 -0
- package/dist/node-index.js.map +1 -0
- package/dist/node-wrapper.d.ts +44 -0
- package/dist/node-wrapper.d.ts.map +1 -0
- package/dist/node-wrapper.js +296 -0
- package/dist/node-wrapper.js.map +1 -0
- package/dist/types/index.d.ts +28 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/node-types.d.ts +71 -0
- package/dist/types/node-types.d.ts.map +1 -0
- package/dist/types/node-types.js +6 -0
- package/dist/types/node-types.js.map +1 -0
- package/dist/vscode/extension.d.ts +81 -0
- package/dist/vscode/extension.d.ts.map +1 -0
- package/dist/vscode/extension.js +309 -0
- package/dist/vscode/extension.js.map +1 -0
- package/examples/basic-usage.d.ts +2 -0
- package/examples/basic-usage.d.ts.map +1 -0
- package/examples/basic-usage.js +26 -0
- package/examples/basic-usage.js.map +1 -0
- package/examples/basic-usage.ts +29 -0
- package/examples/vscode-extension-example/README.md +95 -0
- package/examples/vscode-extension-example/package.json +49 -0
- package/examples/vscode-extension-example/src/extension.ts +172 -0
- package/examples/vscode-extension-example/tsconfig.json +12 -0
- package/examples/vscode-extension-integration.d.ts +31 -0
- package/examples/vscode-extension-integration.d.ts.map +1 -0
- package/examples/vscode-extension-integration.js +319 -0
- package/examples/vscode-extension-integration.js.map +1 -0
- package/examples/vscode-extension-integration.ts +41 -0
- package/legacy/benchmarks/memory-benchmarks.ts +350 -0
- package/legacy/benchmarks/run-benchmarks.ts +315 -0
- package/legacy/better-sqlite3-shared.ts +157 -0
- package/legacy/better-sqlite3.ts +4 -0
- package/legacy/cli.ts +241 -0
- package/legacy/config.ts +50 -0
- package/legacy/core/crdt.ts +107 -0
- package/legacy/core/database.ts +529 -0
- package/legacy/healthcheck.ts +162 -0
- package/legacy/http/api-server.ts +438 -0
- package/legacy/index.ts +28 -0
- package/legacy/logic/rules.ts +46 -0
- package/legacy/main.rs +3 -0
- package/legacy/main.ts +197 -0
- package/legacy/network/websocket-server.ts +115 -0
- package/legacy/node-index.ts +823 -0
- package/legacy/node-wrapper.ts +329 -0
- package/legacy/sqlite-compat.ts +633 -0
- package/legacy/sqlite3-compat.ts +55 -0
- package/legacy/storage/kv-storage.ts +73 -0
- package/legacy/tests/core.test.ts +305 -0
- package/legacy/tests/fixtures/performance-data.json +71 -0
- package/legacy/tests/fixtures/test-data.json +129 -0
- package/legacy/tests/integration/api-server.test.ts +334 -0
- package/legacy/tests/integration/mesh-network.test.ts +303 -0
- package/legacy/tests/logic.test.ts +34 -0
- package/legacy/tests/performance/load.test.ts +290 -0
- package/legacy/tests/security/input-validation.test.ts +286 -0
- package/legacy/tests/unit/core.test.ts +226 -0
- package/legacy/tests/unit/subscriptions.test.ts +135 -0
- package/legacy/tests/unit/vector-search.test.ts +173 -0
- package/legacy/tests/vscode_extension_test.ts +281 -0
- package/legacy/types/index.ts +32 -0
- package/legacy/types/node-types.ts +80 -0
- package/legacy/util/debug.ts +14 -0
- package/legacy/vector/index.ts +59 -0
- package/legacy/vscode/extension.ts +387 -0
- package/package.json +127 -0
- package/scripts/compiled-crud-verify.ts +30 -0
- package/scripts/dogfood.ts +297 -0
- package/scripts/postinstall.js +156 -0
- package/scripts/release-check.js +190 -0
- package/scripts/run-tests.ts +178 -0
- package/scripts/setup-libclang.ps1 +209 -0
- package/scripts/update-changelog.js +214 -0
- package/web/README.md +27 -0
- package/web/svelte/package.json +31 -0
package/legacy/main.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { GunDB } from "./core/database.ts";
|
|
2
|
+
import { debugLog as _debugLog } from "./util/debug.ts";
|
|
3
|
+
import { startApiServer } from "./http/api-server.ts";
|
|
4
|
+
import { loadConfig, saveConfig } from "./config.ts";
|
|
5
|
+
|
|
6
|
+
function printUsage() {
|
|
7
|
+
console.log(
|
|
8
|
+
[
|
|
9
|
+
"Usage:",
|
|
10
|
+
" deno run -A src/main.ts serve [--port <port>] [--kv <path>] [ws://peer ...]",
|
|
11
|
+
" deno run -A src/main.ts put <id> <json> [--kv <path>]",
|
|
12
|
+
" deno run -A src/main.ts get <id> [--kv <path>]",
|
|
13
|
+
" deno run -A src/main.ts delete <id> [--kv <path>]",
|
|
14
|
+
" deno run -A src/main.ts vsearch <query> <k> [--kv <path>]",
|
|
15
|
+
" deno run -A src/main.ts type <id> <TypeName> [--kv <path>]",
|
|
16
|
+
" deno run -A src/main.ts instances <TypeName> [--kv <path>]",
|
|
17
|
+
" deno run -A src/main.ts list [--kv <path>]",
|
|
18
|
+
"",
|
|
19
|
+
].join("\n"),
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (import.meta.main) {
|
|
24
|
+
const [cmd, ...rest] = Deno.args;
|
|
25
|
+
switch (cmd) {
|
|
26
|
+
case "serve": {
|
|
27
|
+
const cfg = await loadConfig();
|
|
28
|
+
let port = cfg.port ?? 8080;
|
|
29
|
+
let kvPath: string | undefined = cfg.kvPath;
|
|
30
|
+
const pi = rest.indexOf("--port");
|
|
31
|
+
if (pi >= 0 && rest[pi + 1]) {
|
|
32
|
+
const n = Number(rest[pi + 1]);
|
|
33
|
+
if (Number.isFinite(n)) port = n;
|
|
34
|
+
}
|
|
35
|
+
const ki = rest.indexOf("--kv");
|
|
36
|
+
if (ki >= 0 && rest[ki + 1]) kvPath = rest[ki + 1];
|
|
37
|
+
const peers = (cfg.peers ?? []).concat(
|
|
38
|
+
rest.filter((v) => v.startsWith("ws://") || v.startsWith("wss://")),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const db = new GunDB();
|
|
42
|
+
await db.ready(kvPath);
|
|
43
|
+
db.serve({ port });
|
|
44
|
+
for (const p of peers) db.connect(p);
|
|
45
|
+
|
|
46
|
+
const api = startApiServer({ port: port + (cfg.apiPortOffset ?? 1), db });
|
|
47
|
+
console.log(`PluresDB node serving on ws://localhost:${port}`);
|
|
48
|
+
console.log(`HTTP API/UI on ${api.url}`);
|
|
49
|
+
if (peers.length) console.log("Connected to peers:", peers.join(", "));
|
|
50
|
+
|
|
51
|
+
// Keep process alive
|
|
52
|
+
await new Promise(() => {});
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case "put": {
|
|
56
|
+
const [id, json, ...flags] = rest;
|
|
57
|
+
if (!id || !json) {
|
|
58
|
+
printUsage();
|
|
59
|
+
Deno.exit(1);
|
|
60
|
+
}
|
|
61
|
+
let kvPath: string | undefined;
|
|
62
|
+
const ki = flags.indexOf("--kv");
|
|
63
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
64
|
+
const db = new GunDB();
|
|
65
|
+
await db.ready(kvPath);
|
|
66
|
+
const obj = JSON.parse(json);
|
|
67
|
+
await db.put(id, obj);
|
|
68
|
+
console.log("ok");
|
|
69
|
+
await db.close();
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "get": {
|
|
73
|
+
const [id, ...flags] = rest;
|
|
74
|
+
if (!id) {
|
|
75
|
+
printUsage();
|
|
76
|
+
Deno.exit(1);
|
|
77
|
+
}
|
|
78
|
+
let kvPath: string | undefined;
|
|
79
|
+
const ki = flags.indexOf("--kv");
|
|
80
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
81
|
+
const db = new GunDB();
|
|
82
|
+
await db.ready(kvPath);
|
|
83
|
+
const val = await db.get<Record<string, unknown>>(id);
|
|
84
|
+
console.log(JSON.stringify(val));
|
|
85
|
+
await db.close();
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "delete": {
|
|
89
|
+
const [id, ...flags] = rest;
|
|
90
|
+
if (!id) {
|
|
91
|
+
printUsage();
|
|
92
|
+
Deno.exit(1);
|
|
93
|
+
}
|
|
94
|
+
let kvPath: string | undefined;
|
|
95
|
+
const ki = flags.indexOf("--kv");
|
|
96
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
97
|
+
const db = new GunDB();
|
|
98
|
+
await db.ready(kvPath);
|
|
99
|
+
await db.delete(id);
|
|
100
|
+
console.log("ok");
|
|
101
|
+
await db.close();
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "vsearch": {
|
|
105
|
+
const [query, kRaw, ...flags] = rest;
|
|
106
|
+
if (!query || !kRaw) {
|
|
107
|
+
printUsage();
|
|
108
|
+
Deno.exit(1);
|
|
109
|
+
}
|
|
110
|
+
const k = Number(kRaw);
|
|
111
|
+
if (!Number.isFinite(k)) {
|
|
112
|
+
printUsage();
|
|
113
|
+
Deno.exit(1);
|
|
114
|
+
}
|
|
115
|
+
let kvPath: string | undefined;
|
|
116
|
+
const ki = flags.indexOf("--kv");
|
|
117
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
118
|
+
const db = new GunDB();
|
|
119
|
+
await db.ready(kvPath);
|
|
120
|
+
const results = await db.vectorSearch(query, k);
|
|
121
|
+
console.log(
|
|
122
|
+
JSON.stringify(results.map((n) => ({ id: n.id, data: n.data }))),
|
|
123
|
+
);
|
|
124
|
+
await db.close();
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case "type": {
|
|
128
|
+
const [id, typeName, ...flags] = rest;
|
|
129
|
+
if (!id || !typeName) {
|
|
130
|
+
printUsage();
|
|
131
|
+
Deno.exit(1);
|
|
132
|
+
}
|
|
133
|
+
let kvPath: string | undefined;
|
|
134
|
+
const ki = flags.indexOf("--kv");
|
|
135
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
136
|
+
const db = new GunDB();
|
|
137
|
+
await db.ready(kvPath);
|
|
138
|
+
await db.setType(id, typeName);
|
|
139
|
+
console.log("ok");
|
|
140
|
+
await db.close();
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "instances": {
|
|
144
|
+
const [typeName, ...flags] = rest;
|
|
145
|
+
if (!typeName) {
|
|
146
|
+
printUsage();
|
|
147
|
+
Deno.exit(1);
|
|
148
|
+
}
|
|
149
|
+
let kvPath: string | undefined;
|
|
150
|
+
const ki = flags.indexOf("--kv");
|
|
151
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
152
|
+
const db = new GunDB();
|
|
153
|
+
await db.ready(kvPath);
|
|
154
|
+
const rows = await db.instancesOf(typeName);
|
|
155
|
+
console.log(
|
|
156
|
+
JSON.stringify(rows.map((n) => ({ id: n.id, data: n.data }))),
|
|
157
|
+
);
|
|
158
|
+
await db.close();
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
case "list": {
|
|
162
|
+
const flags = rest;
|
|
163
|
+
let kvPath: string | undefined;
|
|
164
|
+
const ki = flags.indexOf("--kv");
|
|
165
|
+
if (ki >= 0 && flags[ki + 1]) kvPath = flags[ki + 1];
|
|
166
|
+
const db = new GunDB();
|
|
167
|
+
await db.ready(kvPath);
|
|
168
|
+
const nodes = await db.getAll();
|
|
169
|
+
const out = nodes.map((node) => ({
|
|
170
|
+
id: node.id,
|
|
171
|
+
data: node.data as Record<string, unknown>,
|
|
172
|
+
}));
|
|
173
|
+
console.log(JSON.stringify(out));
|
|
174
|
+
await db.close();
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "config": {
|
|
178
|
+
const cfg = await loadConfig();
|
|
179
|
+
console.log(JSON.stringify(cfg, null, 2));
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case "config:set": {
|
|
183
|
+
const [key, value] = rest;
|
|
184
|
+
if (!key || value === undefined) {
|
|
185
|
+
printUsage();
|
|
186
|
+
Deno.exit(1);
|
|
187
|
+
}
|
|
188
|
+
const cfg = await loadConfig();
|
|
189
|
+
(cfg as any)[key] = /^[0-9]+$/.test(value) ? Number(value) : value;
|
|
190
|
+
await saveConfig(cfg);
|
|
191
|
+
console.log("ok");
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
default:
|
|
195
|
+
printUsage();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { debugLog } from "../util/debug.ts";
|
|
2
|
+
export interface MeshServer {
|
|
3
|
+
url: string;
|
|
4
|
+
broadcast: (obj: unknown, exclude?: WebSocket) => void;
|
|
5
|
+
close: () => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function startMeshServer(args: {
|
|
9
|
+
port: number;
|
|
10
|
+
onMessage: (payload: {
|
|
11
|
+
msg: unknown;
|
|
12
|
+
source: WebSocket;
|
|
13
|
+
send: (obj: unknown) => void;
|
|
14
|
+
broadcast: (obj: unknown, exclude?: WebSocket) => void;
|
|
15
|
+
}) => void;
|
|
16
|
+
}): MeshServer {
|
|
17
|
+
const sockets = new Set<WebSocket>();
|
|
18
|
+
// Debug logging is gated by env var in util/debug.ts
|
|
19
|
+
|
|
20
|
+
const broadcast = (obj: unknown, exclude?: WebSocket) => {
|
|
21
|
+
const data = JSON.stringify(obj);
|
|
22
|
+
for (const s of sockets) {
|
|
23
|
+
if (s === exclude) continue;
|
|
24
|
+
try {
|
|
25
|
+
s.send(data);
|
|
26
|
+
} catch {
|
|
27
|
+
// ignore
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const server = Deno.serve({ port: args.port, onListen: () => {} }, (req) => {
|
|
33
|
+
debugLog("ws:incoming request");
|
|
34
|
+
const upgrade = Deno.upgradeWebSocket(req);
|
|
35
|
+
const socket = upgrade.socket;
|
|
36
|
+
|
|
37
|
+
socket.onopen = () => {
|
|
38
|
+
debugLog("ws:open");
|
|
39
|
+
sockets.add(socket);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
socket.onmessage = (event: MessageEvent<string>) => {
|
|
43
|
+
try {
|
|
44
|
+
const msg = JSON.parse(event.data);
|
|
45
|
+
debugLog("ws:message", { type: (msg as { type?: string }).type });
|
|
46
|
+
args.onMessage({
|
|
47
|
+
msg,
|
|
48
|
+
source: socket,
|
|
49
|
+
send: (obj: unknown) => {
|
|
50
|
+
try {
|
|
51
|
+
socket.send(JSON.stringify(obj));
|
|
52
|
+
} catch {
|
|
53
|
+
/* ignore */
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
broadcast,
|
|
57
|
+
});
|
|
58
|
+
} catch {
|
|
59
|
+
// ignore malformed message
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const cleanup = () => sockets.delete(socket);
|
|
64
|
+
socket.onclose = cleanup;
|
|
65
|
+
socket.onerror = cleanup;
|
|
66
|
+
|
|
67
|
+
return upgrade.response;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
url: `ws://localhost:${args.port}`,
|
|
72
|
+
broadcast,
|
|
73
|
+
close: () => {
|
|
74
|
+
try {
|
|
75
|
+
server.shutdown();
|
|
76
|
+
} catch {
|
|
77
|
+
/* ignore */
|
|
78
|
+
}
|
|
79
|
+
for (const s of sockets) {
|
|
80
|
+
try {
|
|
81
|
+
s.close();
|
|
82
|
+
} catch {
|
|
83
|
+
/* ignore */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
sockets.clear();
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function connectToPeer(
|
|
92
|
+
url: string,
|
|
93
|
+
handlers: {
|
|
94
|
+
onOpen?: (socket: WebSocket) => void;
|
|
95
|
+
onMessage?: (msg: unknown, socket: WebSocket) => void;
|
|
96
|
+
onClose?: (socket: WebSocket) => void;
|
|
97
|
+
},
|
|
98
|
+
): WebSocket {
|
|
99
|
+
const socket = new WebSocket(url);
|
|
100
|
+
if (handlers.onOpen) socket.onopen = () => handlers.onOpen?.(socket);
|
|
101
|
+
if (handlers.onMessage) {
|
|
102
|
+
socket.onmessage = (e) => {
|
|
103
|
+
try {
|
|
104
|
+
handlers.onMessage?.(JSON.parse(e.data), socket);
|
|
105
|
+
} catch {
|
|
106
|
+
/* ignore */
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (handlers.onClose) socket.onclose = () => handlers.onClose?.(socket);
|
|
111
|
+
socket.onerror = () => {
|
|
112
|
+
/* ignore */
|
|
113
|
+
};
|
|
114
|
+
return socket;
|
|
115
|
+
}
|