@plures/pluresdb 1.6.10 → 2.9.6
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/README.md +97 -289
- package/crates/README.md +99 -0
- package/crates/pluresdb-node/README.md +181 -0
- package/crates/pluresdb-node/index.d.ts +0 -0
- package/crates/pluresdb-node/index.js +265 -0
- package/crates/pluresdb-node/package.json +35 -0
- package/dist/napi/index.js +60 -0
- package/embedded.d.ts +1 -0
- package/embedded.js +46 -0
- package/package.json +20 -9
- package/dist/.tsbuildinfo +0 -1
- package/dist/better-sqlite3-shared.d.ts +0 -12
- package/dist/better-sqlite3-shared.d.ts.map +0 -1
- package/dist/better-sqlite3-shared.js +0 -143
- package/dist/better-sqlite3-shared.js.map +0 -1
- package/dist/better-sqlite3.d.ts +0 -4
- package/dist/better-sqlite3.d.ts.map +0 -1
- package/dist/better-sqlite3.js +0 -8
- package/dist/better-sqlite3.js.map +0 -1
- package/dist/cli.d.ts +0 -7
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/local-first/unified-api.d.ts +0 -110
- package/dist/local-first/unified-api.d.ts.map +0 -1
- package/dist/local-first/unified-api.js +0 -348
- package/dist/local-first/unified-api.js.map +0 -1
- package/dist/node-index.d.ts +0 -150
- package/dist/node-index.d.ts.map +0 -1
- package/dist/node-index.js +0 -668
- package/dist/node-index.js.map +0 -1
- package/dist/node-wrapper.d.ts +0 -44
- package/dist/node-wrapper.d.ts.map +0 -1
- package/dist/node-wrapper.js +0 -296
- package/dist/node-wrapper.js.map +0 -1
- package/dist/types/index.d.ts +0 -28
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
- package/dist/types/node-types.d.ts +0 -71
- package/dist/types/node-types.d.ts.map +0 -1
- package/dist/types/node-types.js +0 -6
- package/dist/types/node-types.js.map +0 -1
- package/dist/util/debug.d.ts +0 -3
- package/dist/util/debug.d.ts.map +0 -1
- package/dist/util/debug.js +0 -34
- package/dist/util/debug.js.map +0 -1
- package/dist/vscode/extension.d.ts +0 -81
- package/dist/vscode/extension.d.ts.map +0 -1
- package/dist/vscode/extension.js +0 -309
- package/dist/vscode/extension.js.map +0 -1
- package/examples/basic-usage.d.ts +0 -2
- package/examples/basic-usage.d.ts.map +0 -1
- package/examples/basic-usage.js +0 -26
- package/examples/basic-usage.js.map +0 -1
- package/examples/basic-usage.ts +0 -29
- package/examples/browser-demo/README.md +0 -204
- package/examples/browser-demo/index.html +0 -466
- package/examples/browser-wasm-integration.md +0 -411
- package/examples/ipc-demo/README.md +0 -127
- package/examples/local-first-usage.ts +0 -138
- package/examples/native-ipc-integration.md +0 -526
- package/examples/tauri-demo/README.md +0 -240
- package/examples/tauri-integration.md +0 -260
- package/examples/vscode-extension-example/README.md +0 -95
- package/examples/vscode-extension-example/package.json +0 -49
- package/examples/vscode-extension-example/src/extension.ts +0 -172
- package/examples/vscode-extension-example/tsconfig.json +0 -12
- package/examples/vscode-extension-integration.d.ts +0 -31
- package/examples/vscode-extension-integration.d.ts.map +0 -1
- package/examples/vscode-extension-integration.js +0 -319
- package/examples/vscode-extension-integration.js.map +0 -1
- package/examples/vscode-extension-integration.ts +0 -41
- package/legacy/benchmarks/memory-benchmarks.ts +0 -350
- package/legacy/benchmarks/run-benchmarks.ts +0 -315
- package/legacy/better-sqlite3-shared.ts +0 -157
- package/legacy/better-sqlite3.ts +0 -4
- package/legacy/cli.ts +0 -241
- package/legacy/config.ts +0 -50
- package/legacy/core/crdt.ts +0 -107
- package/legacy/core/database.ts +0 -529
- package/legacy/healthcheck.ts +0 -162
- package/legacy/http/api-server.ts +0 -569
- package/legacy/index.ts +0 -31
- package/legacy/local-first/unified-api.ts +0 -449
- package/legacy/logic/rules.ts +0 -46
- package/legacy/main.rs +0 -3
- package/legacy/main.ts +0 -197
- package/legacy/network/websocket-server.ts +0 -115
- package/legacy/node-index.ts +0 -827
- package/legacy/node-wrapper.ts +0 -329
- package/legacy/plugins/README.md +0 -181
- package/legacy/plugins/example-embedding-plugin.ts +0 -56
- package/legacy/plugins/plugin-system.ts +0 -315
- package/legacy/sqlite-compat.ts +0 -633
- package/legacy/sqlite3-compat.ts +0 -55
- package/legacy/storage/kv-storage.ts +0 -73
- package/legacy/tests/core.test.ts +0 -305
- package/legacy/tests/fixtures/performance-data.json +0 -71
- package/legacy/tests/fixtures/test-data.json +0 -129
- package/legacy/tests/integration/api-server.test.ts +0 -334
- package/legacy/tests/integration/mesh-network.test.ts +0 -303
- package/legacy/tests/logic.test.ts +0 -34
- package/legacy/tests/performance/load.test.ts +0 -290
- package/legacy/tests/security/input-validation.test.ts +0 -286
- package/legacy/tests/unit/core.test.ts +0 -226
- package/legacy/tests/unit/local-first-api.test.ts +0 -65
- package/legacy/tests/unit/plugin-system.test.ts +0 -388
- package/legacy/tests/unit/subscriptions.test.ts +0 -135
- package/legacy/tests/unit/vector-search.test.ts +0 -173
- package/legacy/tests/vscode_extension_test.ts +0 -281
- package/legacy/types/index.ts +0 -32
- package/legacy/types/node-types.ts +0 -80
- package/legacy/util/debug.ts +0 -27
- package/legacy/vector/index.ts +0 -59
- package/legacy/vscode/extension.ts +0 -387
- package/scripts/compiled-crud-verify.ts +0 -30
- package/scripts/dogfood.ts +0 -297
- package/scripts/postinstall.js +0 -156
- package/scripts/publish-crates.sh +0 -95
- package/scripts/release-check.js +0 -224
- package/scripts/run-tests.ts +0 -178
- package/scripts/setup-libclang.ps1 +0 -209
- package/scripts/update-changelog.js +0 -214
- package/scripts/validate-npm-publish.js +0 -228
- package/web/README.md +0 -27
- package/web/svelte/package.json +0 -31
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
import {
|
|
3
|
-
assertEquals,
|
|
4
|
-
assertExists,
|
|
5
|
-
assertRejects,
|
|
6
|
-
} from "jsr:@std/assert@1.0.14";
|
|
7
|
-
import { GunDB } from "../../core/database.ts";
|
|
8
|
-
import { mergeNodes } from "../../core/crdt.ts";
|
|
9
|
-
import type { NodeRecord } from "../../types/index.ts";
|
|
10
|
-
|
|
11
|
-
Deno.test("Core Database - Basic CRUD Operations", async () => {
|
|
12
|
-
const db = new GunDB();
|
|
13
|
-
try {
|
|
14
|
-
const kvPath = await Deno.makeTempFile({
|
|
15
|
-
prefix: "kv_",
|
|
16
|
-
suffix: ".sqlite",
|
|
17
|
-
});
|
|
18
|
-
await db.ready(kvPath);
|
|
19
|
-
|
|
20
|
-
// Test put and get
|
|
21
|
-
const user = { name: "Alice", age: 30, email: "alice@example.com" };
|
|
22
|
-
await db.put("user:alice", user as unknown as Record<string, unknown>);
|
|
23
|
-
const got = await db.get<typeof user>("user:alice");
|
|
24
|
-
|
|
25
|
-
assertEquals(got?.name, "Alice");
|
|
26
|
-
assertEquals(got?.age, 30);
|
|
27
|
-
assertEquals(got?.email, "alice@example.com");
|
|
28
|
-
|
|
29
|
-
// Test update
|
|
30
|
-
await db.put("user:alice", { ...user, age: 31 });
|
|
31
|
-
const updated = await db.get<typeof user>("user:alice");
|
|
32
|
-
assertEquals(updated?.age, 31);
|
|
33
|
-
|
|
34
|
-
// Test delete
|
|
35
|
-
await db.delete("user:alice");
|
|
36
|
-
const deleted = await db.get<typeof user>("user:alice");
|
|
37
|
-
assertEquals(deleted, null);
|
|
38
|
-
} finally {
|
|
39
|
-
await db.close();
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
Deno.test("Core Database - Vector Clock Increments", async () => {
|
|
44
|
-
const db = new GunDB();
|
|
45
|
-
try {
|
|
46
|
-
const kvPath = await Deno.makeTempFile({
|
|
47
|
-
prefix: "kv_",
|
|
48
|
-
suffix: ".sqlite",
|
|
49
|
-
});
|
|
50
|
-
await db.ready(kvPath);
|
|
51
|
-
|
|
52
|
-
const id = "vc:test";
|
|
53
|
-
await db.put(id, { value: 1 });
|
|
54
|
-
await db.put(id, { value: 2 });
|
|
55
|
-
await db.put(id, { value: 3 });
|
|
56
|
-
|
|
57
|
-
// Inspect underlying record
|
|
58
|
-
const { KvStorage } = await import("../../storage/kv-storage.ts");
|
|
59
|
-
const kv = new KvStorage();
|
|
60
|
-
await kv.open(kvPath);
|
|
61
|
-
const node = await kv.getNode(id);
|
|
62
|
-
await kv.close();
|
|
63
|
-
|
|
64
|
-
assertExists(node);
|
|
65
|
-
const clockValues = Object.values(node.vectorClock);
|
|
66
|
-
assertEquals(clockValues.length, 1);
|
|
67
|
-
assertEquals(clockValues[0], 3);
|
|
68
|
-
} finally {
|
|
69
|
-
await db.close();
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
Deno.test("Core Database - Type System", async () => {
|
|
74
|
-
const db = new GunDB();
|
|
75
|
-
try {
|
|
76
|
-
const kvPath = await Deno.makeTempFile({
|
|
77
|
-
prefix: "kv_",
|
|
78
|
-
suffix: ".sqlite",
|
|
79
|
-
});
|
|
80
|
-
await db.ready(kvPath);
|
|
81
|
-
|
|
82
|
-
// Test setType and instancesOf
|
|
83
|
-
await db.put("person:1", { name: "Alice" });
|
|
84
|
-
await db.setType("person:1", "Person");
|
|
85
|
-
|
|
86
|
-
await db.put("company:1", { name: "Acme Corp" });
|
|
87
|
-
await db.setType("company:1", "Company");
|
|
88
|
-
|
|
89
|
-
const people = await db.instancesOf("Person");
|
|
90
|
-
assertEquals(people.length, 1);
|
|
91
|
-
assertEquals(people[0].id, "person:1");
|
|
92
|
-
|
|
93
|
-
const companies = await db.instancesOf("Company");
|
|
94
|
-
assertEquals(companies.length, 1);
|
|
95
|
-
assertEquals(companies[0].id, "company:1");
|
|
96
|
-
} finally {
|
|
97
|
-
await db.close();
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
Deno.test("Core Database - Vector Search", async () => {
|
|
102
|
-
const db = new GunDB();
|
|
103
|
-
try {
|
|
104
|
-
const kvPath = await Deno.makeTempFile({
|
|
105
|
-
prefix: "kv_",
|
|
106
|
-
suffix: ".sqlite",
|
|
107
|
-
});
|
|
108
|
-
await db.ready(kvPath);
|
|
109
|
-
|
|
110
|
-
// Add documents with text content
|
|
111
|
-
await db.put("doc:1", {
|
|
112
|
-
text: "Machine learning and artificial intelligence",
|
|
113
|
-
});
|
|
114
|
-
await db.put("doc:2", { text: "Cooking recipes and food preparation" });
|
|
115
|
-
await db.put("doc:3", { text: "Deep learning neural networks" });
|
|
116
|
-
|
|
117
|
-
// Test vector search
|
|
118
|
-
const results = await db.vectorSearch("machine learning", 2);
|
|
119
|
-
assertExists(results);
|
|
120
|
-
assertEquals(results.length, 2);
|
|
121
|
-
|
|
122
|
-
// Should find the most relevant documents
|
|
123
|
-
const docIds = results.map((r) => r.id);
|
|
124
|
-
assertExists(docIds.includes("doc:1"));
|
|
125
|
-
assertExists(docIds.includes("doc:3"));
|
|
126
|
-
} finally {
|
|
127
|
-
await db.close();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
Deno.test("CRDT Merge - Equal Timestamps", () => {
|
|
132
|
-
const timestamp = Date.now();
|
|
133
|
-
const local: NodeRecord = {
|
|
134
|
-
id: "test:1",
|
|
135
|
-
data: { a: 1, shared: 1, nested: { x: 1, y: 1 } },
|
|
136
|
-
vector: [0.1, 0.2],
|
|
137
|
-
type: "TestType",
|
|
138
|
-
timestamp,
|
|
139
|
-
vectorClock: { peerA: 2 },
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const incoming: NodeRecord = {
|
|
143
|
-
id: "test:1",
|
|
144
|
-
data: { b: 2, shared: 2, nested: { y: 2, z: 3 } },
|
|
145
|
-
timestamp,
|
|
146
|
-
vectorClock: { peerB: 3 },
|
|
147
|
-
} as unknown as NodeRecord;
|
|
148
|
-
|
|
149
|
-
const merged = mergeNodes(local, incoming);
|
|
150
|
-
|
|
151
|
-
assertEquals(merged.id, "test:1");
|
|
152
|
-
assertEquals(merged.timestamp, timestamp);
|
|
153
|
-
assertEquals(merged.data, {
|
|
154
|
-
a: 1,
|
|
155
|
-
shared: 2,
|
|
156
|
-
b: 2,
|
|
157
|
-
nested: { x: 1, y: 2, z: 3 },
|
|
158
|
-
});
|
|
159
|
-
assertEquals(merged.type, "TestType");
|
|
160
|
-
assertEquals(merged.vector, [0.1, 0.2]);
|
|
161
|
-
assertEquals(merged.vectorClock.peerA, 2);
|
|
162
|
-
assertEquals(merged.vectorClock.peerB, 3);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
Deno.test("CRDT Merge - LWW on Different Timestamps", () => {
|
|
166
|
-
const t1 = 1000;
|
|
167
|
-
const t2 = 2000;
|
|
168
|
-
|
|
169
|
-
const older: NodeRecord = {
|
|
170
|
-
id: "test:2",
|
|
171
|
-
data: { a: 1, b: 1 },
|
|
172
|
-
timestamp: t1,
|
|
173
|
-
vectorClock: { p1: 1 },
|
|
174
|
-
} as unknown as NodeRecord;
|
|
175
|
-
|
|
176
|
-
const newer: NodeRecord = {
|
|
177
|
-
id: "test:2",
|
|
178
|
-
data: { a: 999, b: 2, c: 3 },
|
|
179
|
-
timestamp: t2,
|
|
180
|
-
vectorClock: { p2: 1 },
|
|
181
|
-
} as unknown as NodeRecord;
|
|
182
|
-
|
|
183
|
-
const merged = mergeNodes(older, newer);
|
|
184
|
-
|
|
185
|
-
assertEquals(merged.data, { a: 999, b: 2, c: 3 });
|
|
186
|
-
assertEquals(merged.timestamp, t2);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
Deno.test("Core Database - Error Handling", async () => {
|
|
190
|
-
const db = new GunDB();
|
|
191
|
-
|
|
192
|
-
// Test operations before ready
|
|
193
|
-
await assertRejects(
|
|
194
|
-
() => db.put("test", { value: 1 }),
|
|
195
|
-
Error,
|
|
196
|
-
"Database not ready",
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
await assertRejects(() => db.get("test"), Error, "Database not ready");
|
|
200
|
-
|
|
201
|
-
await assertRejects(() => db.delete("test"), Error, "Database not ready");
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
Deno.test("Core Database - Persistence Across Restarts", async () => {
|
|
205
|
-
const kvPath = await Deno.makeTempFile({
|
|
206
|
-
prefix: "kv_",
|
|
207
|
-
suffix: ".sqlite",
|
|
208
|
-
});
|
|
209
|
-
const id = "persist:test";
|
|
210
|
-
|
|
211
|
-
// First session
|
|
212
|
-
const db1 = new GunDB();
|
|
213
|
-
await db1.ready(kvPath);
|
|
214
|
-
await db1.put(id, { value: 123, text: "persistent data" });
|
|
215
|
-
await db1.close();
|
|
216
|
-
|
|
217
|
-
// Second session
|
|
218
|
-
const db2 = new GunDB();
|
|
219
|
-
await db2.ready(kvPath);
|
|
220
|
-
const got = await db2.get<{ value: number; text: string }>(id);
|
|
221
|
-
await db2.close();
|
|
222
|
-
|
|
223
|
-
assertExists(got);
|
|
224
|
-
assertEquals(got.value, 123);
|
|
225
|
-
assertEquals(got.text, "persistent data");
|
|
226
|
-
});
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Local-First Unified API
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { assertEquals, assertExists } from "jsr:@std/assert@1.0.14";
|
|
6
|
-
import { PluresDBLocalFirst } from "../../local-first/unified-api.ts";
|
|
7
|
-
|
|
8
|
-
Deno.test("PluresDBLocalFirst - Runtime detection", () => {
|
|
9
|
-
// Should detect "network" mode in Deno test environment
|
|
10
|
-
const db = new PluresDBLocalFirst({ mode: "auto" });
|
|
11
|
-
const mode = db.getMode();
|
|
12
|
-
|
|
13
|
-
assertEquals(mode, "network", "Should default to network mode in Deno");
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
Deno.test("PluresDBLocalFirst - Manual mode selection", () => {
|
|
17
|
-
// Should allow manual mode selection
|
|
18
|
-
const db = new PluresDBLocalFirst({ mode: "network", port: 34567 });
|
|
19
|
-
const mode = db.getMode();
|
|
20
|
-
|
|
21
|
-
assertEquals(mode, "network", "Should use network mode when explicitly set");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
Deno.test("PluresDBLocalFirst - WASM mode throws not implemented", async () => {
|
|
25
|
-
const db = new PluresDBLocalFirst({ mode: "wasm", dbName: "test-db" });
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
await db.put("test:1", { value: "test" });
|
|
29
|
-
throw new Error("Should have thrown not implemented error");
|
|
30
|
-
} catch (error) {
|
|
31
|
-
assertEquals(
|
|
32
|
-
error instanceof Error && error.message.includes("not yet implemented"),
|
|
33
|
-
true,
|
|
34
|
-
"Should throw not implemented error for WASM mode"
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
Deno.test("PluresDBLocalFirst - IPC mode throws not implemented", async () => {
|
|
40
|
-
const db = new PluresDBLocalFirst({ mode: "ipc", channelName: "test-channel" });
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
await db.put("test:1", { value: "test" });
|
|
44
|
-
throw new Error("Should have thrown not implemented error");
|
|
45
|
-
} catch (error) {
|
|
46
|
-
assertEquals(
|
|
47
|
-
error instanceof Error && error.message.includes("not yet implemented"),
|
|
48
|
-
true,
|
|
49
|
-
"Should throw not implemented error for IPC mode"
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
Deno.test("PluresDBLocalFirst - Network mode API surface", () => {
|
|
55
|
-
const db = new PluresDBLocalFirst({ mode: "network", port: 34567 });
|
|
56
|
-
|
|
57
|
-
// Check that all required methods exist
|
|
58
|
-
assertExists(db.put, "Should have put method");
|
|
59
|
-
assertExists(db.get, "Should have get method");
|
|
60
|
-
assertExists(db.delete, "Should have delete method");
|
|
61
|
-
assertExists(db.list, "Should have list method");
|
|
62
|
-
assertExists(db.vectorSearch, "Should have vectorSearch method");
|
|
63
|
-
assertExists(db.close, "Should have close method");
|
|
64
|
-
assertExists(db.getMode, "Should have getMode method");
|
|
65
|
-
});
|
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
import {
|
|
3
|
-
assertEquals,
|
|
4
|
-
assertExists,
|
|
5
|
-
assertRejects,
|
|
6
|
-
assert,
|
|
7
|
-
} from "jsr:@std/assert@1.0.14";
|
|
8
|
-
import {
|
|
9
|
-
pluginManager,
|
|
10
|
-
type Plugin,
|
|
11
|
-
type EmbeddingProvider,
|
|
12
|
-
type UIPanel,
|
|
13
|
-
type QueryTransformer,
|
|
14
|
-
type DataValidator,
|
|
15
|
-
} from "../../plugins/plugin-system.ts";
|
|
16
|
-
|
|
17
|
-
// Test helpers
|
|
18
|
-
class TestEmbeddingProvider implements EmbeddingProvider {
|
|
19
|
-
name = "test-embeddings";
|
|
20
|
-
dimensions = 128;
|
|
21
|
-
|
|
22
|
-
async embed(text: string): Promise<number[]> {
|
|
23
|
-
return new Array(this.dimensions).fill(0.1);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class TestQueryTransformer implements QueryTransformer {
|
|
28
|
-
id = "test-transformer";
|
|
29
|
-
|
|
30
|
-
async transform(query: any): Promise<any> {
|
|
31
|
-
return { ...query, transformed: true };
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
class TestDataValidator implements DataValidator {
|
|
36
|
-
id = "test-validator";
|
|
37
|
-
|
|
38
|
-
async validate(data: Record<string, unknown>): Promise<{
|
|
39
|
-
valid: boolean;
|
|
40
|
-
errors?: string[];
|
|
41
|
-
}> {
|
|
42
|
-
if (!data.required) {
|
|
43
|
-
return { valid: false, errors: ["Missing required field"] };
|
|
44
|
-
}
|
|
45
|
-
return { valid: true };
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
Deno.test("Plugin System - Plugin Registration", async () => {
|
|
50
|
-
const plugin: Plugin = {
|
|
51
|
-
id: "test-plugin-1",
|
|
52
|
-
name: "Test Plugin",
|
|
53
|
-
version: "1.0.0",
|
|
54
|
-
description: "A test plugin",
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
await pluginManager.register(plugin);
|
|
58
|
-
|
|
59
|
-
const plugins = pluginManager.getPlugins();
|
|
60
|
-
const registered = plugins.find((p) => p.id === "test-plugin-1");
|
|
61
|
-
|
|
62
|
-
assertExists(registered);
|
|
63
|
-
assertEquals(registered.name, "Test Plugin");
|
|
64
|
-
assertEquals(registered.version, "1.0.0");
|
|
65
|
-
|
|
66
|
-
// Cleanup
|
|
67
|
-
await pluginManager.unregister("test-plugin-1");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
Deno.test("Plugin System - Prevent Duplicate Plugin IDs", async () => {
|
|
71
|
-
const plugin1: Plugin = {
|
|
72
|
-
id: "duplicate-test",
|
|
73
|
-
name: "First Plugin",
|
|
74
|
-
version: "1.0.0",
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const plugin2: Plugin = {
|
|
78
|
-
id: "duplicate-test",
|
|
79
|
-
name: "Second Plugin",
|
|
80
|
-
version: "2.0.0",
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
await pluginManager.register(plugin1);
|
|
84
|
-
|
|
85
|
-
// Attempting to register a plugin with duplicate ID should throw
|
|
86
|
-
await assertRejects(
|
|
87
|
-
async () => {
|
|
88
|
-
await pluginManager.register(plugin2);
|
|
89
|
-
},
|
|
90
|
-
Error,
|
|
91
|
-
"already registered",
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
// Cleanup
|
|
95
|
-
await pluginManager.unregister("duplicate-test");
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
Deno.test("Plugin System - Embedding Provider Registration", async () => {
|
|
99
|
-
const provider = new TestEmbeddingProvider();
|
|
100
|
-
const plugin: Plugin = {
|
|
101
|
-
id: "embedding-test",
|
|
102
|
-
name: "Embedding Test",
|
|
103
|
-
version: "1.0.0",
|
|
104
|
-
embeddingProviders: [provider],
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
await pluginManager.register(plugin);
|
|
108
|
-
|
|
109
|
-
const registeredProvider = pluginManager.getEmbeddingProvider(
|
|
110
|
-
"test-embeddings",
|
|
111
|
-
);
|
|
112
|
-
assertExists(registeredProvider);
|
|
113
|
-
assertEquals(registeredProvider.dimensions, 128);
|
|
114
|
-
|
|
115
|
-
const embedding = await registeredProvider.embed("test");
|
|
116
|
-
assertEquals(embedding.length, 128);
|
|
117
|
-
assertEquals(embedding[0], 0.1);
|
|
118
|
-
|
|
119
|
-
// Cleanup
|
|
120
|
-
await pluginManager.unregister("embedding-test");
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
Deno.test("Plugin System - Query Transformer Registration", async () => {
|
|
124
|
-
const transformer = new TestQueryTransformer();
|
|
125
|
-
const plugin: Plugin = {
|
|
126
|
-
id: "transformer-test",
|
|
127
|
-
name: "Transformer Test",
|
|
128
|
-
version: "1.0.0",
|
|
129
|
-
queryTransformers: [transformer],
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
await pluginManager.register(plugin);
|
|
133
|
-
|
|
134
|
-
const registeredTransformer = pluginManager.getQueryTransformer(
|
|
135
|
-
"test-transformer",
|
|
136
|
-
);
|
|
137
|
-
assertExists(registeredTransformer);
|
|
138
|
-
|
|
139
|
-
const query = { field: "value" };
|
|
140
|
-
const transformed = await registeredTransformer.transform(query);
|
|
141
|
-
assertEquals(transformed.field, "value");
|
|
142
|
-
assertEquals(transformed.transformed, true);
|
|
143
|
-
|
|
144
|
-
// Cleanup
|
|
145
|
-
await pluginManager.unregister("transformer-test");
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
Deno.test("Plugin System - Data Validator Registration", async () => {
|
|
149
|
-
const validator = new TestDataValidator();
|
|
150
|
-
const plugin: Plugin = {
|
|
151
|
-
id: "validator-test",
|
|
152
|
-
name: "Validator Test",
|
|
153
|
-
version: "1.0.0",
|
|
154
|
-
dataValidators: [validator],
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
await pluginManager.register(plugin);
|
|
158
|
-
|
|
159
|
-
const registeredValidator = pluginManager.getDataValidator("test-validator");
|
|
160
|
-
assertExists(registeredValidator);
|
|
161
|
-
|
|
162
|
-
// Test valid data
|
|
163
|
-
const validResult = await registeredValidator.validate({ required: true });
|
|
164
|
-
assertEquals(validResult.valid, true);
|
|
165
|
-
|
|
166
|
-
// Test invalid data
|
|
167
|
-
const invalidResult = await registeredValidator.validate({});
|
|
168
|
-
assertEquals(invalidResult.valid, false);
|
|
169
|
-
assertExists(invalidResult.errors);
|
|
170
|
-
assertEquals(invalidResult.errors.length, 1);
|
|
171
|
-
|
|
172
|
-
// Cleanup
|
|
173
|
-
await pluginManager.unregister("validator-test");
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
Deno.test("Plugin System - Plugin Lifecycle (init/destroy)", async () => {
|
|
177
|
-
let initCalled = false;
|
|
178
|
-
let destroyCalled = false;
|
|
179
|
-
|
|
180
|
-
const plugin: Plugin = {
|
|
181
|
-
id: "lifecycle-test",
|
|
182
|
-
name: "Lifecycle Test",
|
|
183
|
-
version: "1.0.0",
|
|
184
|
-
async init() {
|
|
185
|
-
initCalled = true;
|
|
186
|
-
},
|
|
187
|
-
async destroy() {
|
|
188
|
-
destroyCalled = true;
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
await pluginManager.register(plugin);
|
|
193
|
-
assertEquals(initCalled, true);
|
|
194
|
-
|
|
195
|
-
await pluginManager.unregister("lifecycle-test");
|
|
196
|
-
assertEquals(destroyCalled, true);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
Deno.test("Plugin System - Transform Query with Multiple Transformers", async () => {
|
|
200
|
-
const transformer1: QueryTransformer = {
|
|
201
|
-
id: "transformer-1",
|
|
202
|
-
async transform(query: any) {
|
|
203
|
-
return { ...query, step1: true };
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const transformer2: QueryTransformer = {
|
|
208
|
-
id: "transformer-2",
|
|
209
|
-
async transform(query: any) {
|
|
210
|
-
return { ...query, step2: true };
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
const plugin: Plugin = {
|
|
215
|
-
id: "multi-transformer-test",
|
|
216
|
-
name: "Multi Transformer Test",
|
|
217
|
-
version: "1.0.0",
|
|
218
|
-
queryTransformers: [transformer1, transformer2],
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
await pluginManager.register(plugin);
|
|
222
|
-
|
|
223
|
-
const query = { original: true };
|
|
224
|
-
const transformed = await pluginManager.transformQuery(query);
|
|
225
|
-
|
|
226
|
-
assertEquals(transformed.original, true);
|
|
227
|
-
assertEquals(transformed.step1, true);
|
|
228
|
-
assertEquals(transformed.step2, true);
|
|
229
|
-
|
|
230
|
-
// Cleanup
|
|
231
|
-
await pluginManager.unregister("multi-transformer-test");
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
Deno.test("Plugin System - Validate Data with Multiple Validators", async () => {
|
|
235
|
-
const validator1: DataValidator = {
|
|
236
|
-
id: "validator-1",
|
|
237
|
-
async validate(data: Record<string, unknown>) {
|
|
238
|
-
if (!data.field1) {
|
|
239
|
-
return { valid: false, errors: ["Missing field1"] };
|
|
240
|
-
}
|
|
241
|
-
return { valid: true };
|
|
242
|
-
},
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
const validator2: DataValidator = {
|
|
246
|
-
id: "validator-2",
|
|
247
|
-
async validate(data: Record<string, unknown>) {
|
|
248
|
-
if (!data.field2) {
|
|
249
|
-
return { valid: false, errors: ["Missing field2"] };
|
|
250
|
-
}
|
|
251
|
-
return { valid: true };
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
const plugin: Plugin = {
|
|
256
|
-
id: "multi-validator-test",
|
|
257
|
-
name: "Multi Validator Test",
|
|
258
|
-
version: "1.0.0",
|
|
259
|
-
dataValidators: [validator1, validator2],
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
await pluginManager.register(plugin);
|
|
263
|
-
|
|
264
|
-
// Test with all fields valid
|
|
265
|
-
const validResult = await pluginManager.validateData({
|
|
266
|
-
field1: true,
|
|
267
|
-
field2: true,
|
|
268
|
-
});
|
|
269
|
-
assertEquals(validResult.valid, true);
|
|
270
|
-
assertEquals(validResult.errors.length, 0);
|
|
271
|
-
|
|
272
|
-
// Test with missing fields
|
|
273
|
-
const invalidResult = await pluginManager.validateData({});
|
|
274
|
-
assertEquals(invalidResult.valid, false);
|
|
275
|
-
assertEquals(invalidResult.errors.length, 2);
|
|
276
|
-
assert(invalidResult.errors.includes("Missing field1"));
|
|
277
|
-
assert(invalidResult.errors.includes("Missing field2"));
|
|
278
|
-
|
|
279
|
-
// Cleanup
|
|
280
|
-
await pluginManager.unregister("multi-validator-test");
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
Deno.test("Plugin System - Unregister Non-Existent Plugin", async () => {
|
|
284
|
-
// Should not throw error when unregistering non-existent plugin
|
|
285
|
-
await pluginManager.unregister("non-existent-plugin");
|
|
286
|
-
// If we get here without error, test passes
|
|
287
|
-
assert(true);
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
Deno.test("Plugin System - Get All Providers After Registration", async () => {
|
|
291
|
-
const provider1 = new TestEmbeddingProvider();
|
|
292
|
-
provider1.name = "provider-1";
|
|
293
|
-
|
|
294
|
-
const provider2 = new TestEmbeddingProvider();
|
|
295
|
-
provider2.name = "provider-2";
|
|
296
|
-
|
|
297
|
-
const plugin: Plugin = {
|
|
298
|
-
id: "multi-provider-test",
|
|
299
|
-
name: "Multi Provider Test",
|
|
300
|
-
version: "1.0.0",
|
|
301
|
-
embeddingProviders: [provider1, provider2],
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
await pluginManager.register(plugin);
|
|
305
|
-
|
|
306
|
-
const providers = pluginManager.getEmbeddingProviders();
|
|
307
|
-
const testProviders = providers.filter((p) =>
|
|
308
|
-
p.name === "provider-1" || p.name === "provider-2"
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
assertEquals(testProviders.length, 2);
|
|
312
|
-
|
|
313
|
-
// Cleanup
|
|
314
|
-
await pluginManager.unregister("multi-provider-test");
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
Deno.test("Plugin System - UI Panel Registration", async () => {
|
|
318
|
-
const panel: UIPanel = {
|
|
319
|
-
id: "test-panel",
|
|
320
|
-
name: "Test Panel",
|
|
321
|
-
icon: "🧪",
|
|
322
|
-
component: {} as any, // Mock component
|
|
323
|
-
order: 100,
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const plugin: Plugin = {
|
|
327
|
-
id: "panel-test",
|
|
328
|
-
name: "Panel Test",
|
|
329
|
-
version: "1.0.0",
|
|
330
|
-
uiPanels: [panel],
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
await pluginManager.register(plugin);
|
|
334
|
-
|
|
335
|
-
const registeredPanel = pluginManager.getUIPanel("test-panel");
|
|
336
|
-
assertExists(registeredPanel);
|
|
337
|
-
assertEquals(registeredPanel.name, "Test Panel");
|
|
338
|
-
assertEquals(registeredPanel.icon, "🧪");
|
|
339
|
-
assertEquals(registeredPanel.order, 100);
|
|
340
|
-
|
|
341
|
-
// Cleanup
|
|
342
|
-
await pluginManager.unregister("panel-test");
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
Deno.test("Plugin System - UI Panels Sorted by Order", async () => {
|
|
346
|
-
const panel1: UIPanel = {
|
|
347
|
-
id: "panel-1",
|
|
348
|
-
name: "Panel 1",
|
|
349
|
-
component: {} as any,
|
|
350
|
-
order: 30,
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const panel2: UIPanel = {
|
|
354
|
-
id: "panel-2",
|
|
355
|
-
name: "Panel 2",
|
|
356
|
-
component: {} as any,
|
|
357
|
-
order: 10,
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
const panel3: UIPanel = {
|
|
361
|
-
id: "panel-3",
|
|
362
|
-
name: "Panel 3",
|
|
363
|
-
component: {} as any,
|
|
364
|
-
order: 20,
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
const plugin: Plugin = {
|
|
368
|
-
id: "sorted-panels-test",
|
|
369
|
-
name: "Sorted Panels Test",
|
|
370
|
-
version: "1.0.0",
|
|
371
|
-
uiPanels: [panel1, panel2, panel3],
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
await pluginManager.register(plugin);
|
|
375
|
-
|
|
376
|
-
const panels = pluginManager.getUIPanels();
|
|
377
|
-
const testPanels = panels.filter((p) =>
|
|
378
|
-
["panel-1", "panel-2", "panel-3"].includes(p.id)
|
|
379
|
-
);
|
|
380
|
-
|
|
381
|
-
// Should be sorted by order: panel-2 (10), panel-3 (20), panel-1 (30)
|
|
382
|
-
assertEquals(testPanels[0].id, "panel-2");
|
|
383
|
-
assertEquals(testPanels[1].id, "panel-3");
|
|
384
|
-
assertEquals(testPanels[2].id, "panel-1");
|
|
385
|
-
|
|
386
|
-
// Cleanup
|
|
387
|
-
await pluginManager.unregister("sorted-panels-test");
|
|
388
|
-
});
|