@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,411 +0,0 @@
|
|
|
1
|
-
# Browser WASM Integration Example
|
|
2
|
-
|
|
3
|
-
This example demonstrates how to use PluresDB directly in the browser with WebAssembly, providing true local-first database functionality without any server.
|
|
4
|
-
|
|
5
|
-
## Architecture
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
┌─────────────────────────────────────┐
|
|
9
|
-
│ Browser (HTML/JS/TS) │
|
|
10
|
-
│ │
|
|
11
|
-
│ PluresDBLocalFirst (auto-detect) │
|
|
12
|
-
│ │ │
|
|
13
|
-
│ ▼ │
|
|
14
|
-
│ WebAssembly Module │
|
|
15
|
-
│ (pluresdb-wasm) │
|
|
16
|
-
│ │ │
|
|
17
|
-
│ ▼ │
|
|
18
|
-
│ IndexedDB (persistence) │
|
|
19
|
-
└─────────────────────────────────────┘
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Setup
|
|
23
|
-
|
|
24
|
-
### 1. Install PluresDB
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm install @plures/pluresdb
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Or via CDN:
|
|
31
|
-
|
|
32
|
-
```html
|
|
33
|
-
<script type="module">
|
|
34
|
-
import { PluresDBLocalFirst } from "https://esm.sh/@plures/pluresdb/local-first";
|
|
35
|
-
</script>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### 2. Basic Usage
|
|
39
|
-
|
|
40
|
-
```html
|
|
41
|
-
<!DOCTYPE html>
|
|
42
|
-
<html>
|
|
43
|
-
<head>
|
|
44
|
-
<title>PluresDB Browser Example</title>
|
|
45
|
-
</head>
|
|
46
|
-
<body>
|
|
47
|
-
<h1>PluresDB in Browser</h1>
|
|
48
|
-
|
|
49
|
-
<div>
|
|
50
|
-
<input id="userId" placeholder="User ID" value="user:1" />
|
|
51
|
-
<input id="userName" placeholder="Name" value="Alice" />
|
|
52
|
-
<input id="userEmail" placeholder="Email" value="alice@example.com" />
|
|
53
|
-
<button onclick="addUser()">Add User</button>
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<div>
|
|
57
|
-
<input id="getUserId" placeholder="User ID" value="user:1" />
|
|
58
|
-
<button onclick="getUser()">Get User</button>
|
|
59
|
-
</div>
|
|
60
|
-
|
|
61
|
-
<div>
|
|
62
|
-
<button onclick="listUsers()">List All Users</button>
|
|
63
|
-
</div>
|
|
64
|
-
|
|
65
|
-
<div>
|
|
66
|
-
<input id="searchQuery" placeholder="Search query" value="developers in London" />
|
|
67
|
-
<button onclick="searchUsers()">Vector Search</button>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<pre id="output"></pre>
|
|
71
|
-
|
|
72
|
-
<script type="module">
|
|
73
|
-
import { PluresDBLocalFirst } from "https://esm.sh/@plures/pluresdb/local-first";
|
|
74
|
-
|
|
75
|
-
// Initialize database (auto-detects browser environment)
|
|
76
|
-
const db = new PluresDBLocalFirst({
|
|
77
|
-
mode: "auto", // Will use WASM in browser
|
|
78
|
-
dbName: "my-app-database"
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Make db available globally for demo buttons
|
|
82
|
-
window.db = db;
|
|
83
|
-
|
|
84
|
-
// Helper to display output
|
|
85
|
-
function output(data) {
|
|
86
|
-
document.getElementById("output").textContent =
|
|
87
|
-
JSON.stringify(data, null, 2);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Add user
|
|
91
|
-
window.addUser = async function() {
|
|
92
|
-
try {
|
|
93
|
-
const id = document.getElementById("userId").value;
|
|
94
|
-
const name = document.getElementById("userName").value;
|
|
95
|
-
const email = document.getElementById("userEmail").value;
|
|
96
|
-
|
|
97
|
-
await db.put(id, {
|
|
98
|
-
type: "User",
|
|
99
|
-
name,
|
|
100
|
-
email,
|
|
101
|
-
createdAt: new Date().toISOString()
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
output({ success: true, message: `User ${id} added` });
|
|
105
|
-
} catch (error) {
|
|
106
|
-
output({ error: error.message });
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
// Get user
|
|
111
|
-
window.getUser = async function() {
|
|
112
|
-
try {
|
|
113
|
-
const id = document.getElementById("getUserId").value;
|
|
114
|
-
const user = await db.get(id);
|
|
115
|
-
output(user || { message: "User not found" });
|
|
116
|
-
} catch (error) {
|
|
117
|
-
output({ error: error.message });
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// List all users
|
|
122
|
-
window.listUsers = async function() {
|
|
123
|
-
try {
|
|
124
|
-
const users = await db.list();
|
|
125
|
-
output({ count: users.length, users });
|
|
126
|
-
} catch (error) {
|
|
127
|
-
output({ error: error.message });
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// Vector search
|
|
132
|
-
window.searchUsers = async function() {
|
|
133
|
-
try {
|
|
134
|
-
const query = document.getElementById("searchQuery").value;
|
|
135
|
-
const results = await db.vectorSearch(query, 10);
|
|
136
|
-
output({ query, results });
|
|
137
|
-
} catch (error) {
|
|
138
|
-
output({ error: error.message });
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
console.log("PluresDB initialized in mode:", db.getMode());
|
|
143
|
-
</script>
|
|
144
|
-
</body>
|
|
145
|
-
</html>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### 3. React Example
|
|
149
|
-
|
|
150
|
-
```tsx
|
|
151
|
-
import React, { useEffect, useState } from "react";
|
|
152
|
-
import { PluresDBLocalFirst } from "@plures/pluresdb/local-first";
|
|
153
|
-
|
|
154
|
-
// Initialize database once
|
|
155
|
-
const db = new PluresDBLocalFirst({
|
|
156
|
-
mode: "auto",
|
|
157
|
-
dbName: "react-app-db",
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
interface User {
|
|
161
|
-
name: string;
|
|
162
|
-
email: string;
|
|
163
|
-
role: string;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function App() {
|
|
167
|
-
const [users, setUsers] = useState<any[]>([]);
|
|
168
|
-
const [formData, setFormData] = useState({
|
|
169
|
-
id: "",
|
|
170
|
-
name: "",
|
|
171
|
-
email: "",
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// Load users on mount
|
|
175
|
-
useEffect(() => {
|
|
176
|
-
loadUsers();
|
|
177
|
-
}, []);
|
|
178
|
-
|
|
179
|
-
async function loadUsers() {
|
|
180
|
-
const allUsers = await db.list();
|
|
181
|
-
setUsers(allUsers);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
async function addUser(e: React.FormEvent) {
|
|
185
|
-
e.preventDefault();
|
|
186
|
-
|
|
187
|
-
await db.put(formData.id, {
|
|
188
|
-
type: "User",
|
|
189
|
-
name: formData.name,
|
|
190
|
-
email: formData.email,
|
|
191
|
-
createdAt: new Date().toISOString(),
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
setFormData({ id: "", name: "", email: "" });
|
|
195
|
-
loadUsers();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async function deleteUser(id: string) {
|
|
199
|
-
await db.delete(id);
|
|
200
|
-
loadUsers();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<div>
|
|
205
|
-
<h1>PluresDB React App</h1>
|
|
206
|
-
|
|
207
|
-
<form onSubmit={addUser}>
|
|
208
|
-
<input
|
|
209
|
-
placeholder="User ID"
|
|
210
|
-
value={formData.id}
|
|
211
|
-
onChange={(e) => setFormData({ ...formData, id: e.target.value })}
|
|
212
|
-
/>
|
|
213
|
-
<input
|
|
214
|
-
placeholder="Name"
|
|
215
|
-
value={formData.name}
|
|
216
|
-
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
217
|
-
/>
|
|
218
|
-
<input
|
|
219
|
-
placeholder="Email"
|
|
220
|
-
value={formData.email}
|
|
221
|
-
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
222
|
-
/>
|
|
223
|
-
<button type="submit">Add User</button>
|
|
224
|
-
</form>
|
|
225
|
-
|
|
226
|
-
<h2>Users ({users.length})</h2>
|
|
227
|
-
<ul>
|
|
228
|
-
{users.map((user) => (
|
|
229
|
-
<li key={user.id}>
|
|
230
|
-
{user.data.name} - {user.data.email}
|
|
231
|
-
<button onClick={() => deleteUser(user.id)}>Delete</button>
|
|
232
|
-
</li>
|
|
233
|
-
))}
|
|
234
|
-
</ul>
|
|
235
|
-
</div>
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export default App;
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### 4. Vue Example
|
|
243
|
-
|
|
244
|
-
```vue
|
|
245
|
-
<template>
|
|
246
|
-
<div>
|
|
247
|
-
<h1>PluresDB Vue App</h1>
|
|
248
|
-
|
|
249
|
-
<form @submit.prevent="addUser">
|
|
250
|
-
<input v-model="formData.id" placeholder="User ID" />
|
|
251
|
-
<input v-model="formData.name" placeholder="Name" />
|
|
252
|
-
<input v-model="formData.email" placeholder="Email" />
|
|
253
|
-
<button type="submit">Add User</button>
|
|
254
|
-
</form>
|
|
255
|
-
|
|
256
|
-
<h2>Users ({{ users.length }})</h2>
|
|
257
|
-
<ul>
|
|
258
|
-
<li v-for="user in users" :key="user.id">
|
|
259
|
-
{{ user.data.name }} - {{ user.data.email }}
|
|
260
|
-
<button @click="deleteUser(user.id)">Delete</button>
|
|
261
|
-
</li>
|
|
262
|
-
</ul>
|
|
263
|
-
</div>
|
|
264
|
-
</template>
|
|
265
|
-
|
|
266
|
-
<script setup lang="ts">
|
|
267
|
-
import { ref, onMounted } from "vue";
|
|
268
|
-
import { PluresDBLocalFirst } from "@plures/pluresdb/local-first";
|
|
269
|
-
|
|
270
|
-
const db = new PluresDBLocalFirst({
|
|
271
|
-
mode: "auto",
|
|
272
|
-
dbName: "vue-app-db",
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
const users = ref([]);
|
|
276
|
-
const formData = ref({
|
|
277
|
-
id: "",
|
|
278
|
-
name: "",
|
|
279
|
-
email: "",
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
async function loadUsers() {
|
|
283
|
-
users.value = await db.list();
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async function addUser() {
|
|
287
|
-
await db.put(formData.value.id, {
|
|
288
|
-
type: "User",
|
|
289
|
-
name: formData.value.name,
|
|
290
|
-
email: formData.value.email,
|
|
291
|
-
createdAt: new Date().toISOString(),
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
formData.value = { id: "", name: "", email: "" };
|
|
295
|
-
loadUsers();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
async function deleteUser(id: string) {
|
|
299
|
-
await db.delete(id);
|
|
300
|
-
loadUsers();
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
onMounted(() => {
|
|
304
|
-
loadUsers();
|
|
305
|
-
});
|
|
306
|
-
</script>
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## Features
|
|
310
|
-
|
|
311
|
-
✅ **No Server Required**: Runs entirely in browser
|
|
312
|
-
✅ **Offline-First**: Works without internet connection
|
|
313
|
-
✅ **IndexedDB Persistence**: Data survives page reloads
|
|
314
|
-
✅ **Fast Performance**: In-memory operations with persistent storage
|
|
315
|
-
✅ **Type-Safe**: Full TypeScript support
|
|
316
|
-
✅ **Framework Agnostic**: Works with React, Vue, Svelte, Angular, etc.
|
|
317
|
-
|
|
318
|
-
## Performance Benefits
|
|
319
|
-
|
|
320
|
-
Compared to traditional REST API:
|
|
321
|
-
|
|
322
|
-
| Metric | REST API | WASM | Improvement |
|
|
323
|
-
|--------|----------|------|-------------|
|
|
324
|
-
| **Latency** | ~50-100ms | ~0.1ms | **500-1000x faster** |
|
|
325
|
-
| **Throughput** | ~100 ops/s | ~100k ops/s | **1000x faster** |
|
|
326
|
-
| **Offline Support** | ❌ | ✅ | **100% available** |
|
|
327
|
-
| **Network Usage** | High | None | **Zero bandwidth** |
|
|
328
|
-
|
|
329
|
-
## Data Persistence
|
|
330
|
-
|
|
331
|
-
Data is automatically persisted to IndexedDB:
|
|
332
|
-
|
|
333
|
-
```javascript
|
|
334
|
-
// Data survives:
|
|
335
|
-
// - Page reloads
|
|
336
|
-
// - Browser restarts
|
|
337
|
-
// - Application updates
|
|
338
|
-
|
|
339
|
-
// Data is cleared when:
|
|
340
|
-
// - User clears browser data
|
|
341
|
-
// - Application explicitly calls db.clear()
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
## Browser Compatibility
|
|
345
|
-
|
|
346
|
-
| Browser | Version | Support |
|
|
347
|
-
|---------|---------|---------|
|
|
348
|
-
| Chrome | 57+ | ✅ Full |
|
|
349
|
-
| Firefox | 52+ | ✅ Full |
|
|
350
|
-
| Safari | 11+ | ✅ Full |
|
|
351
|
-
| Edge | 79+ | ✅ Full |
|
|
352
|
-
| Opera | 44+ | ✅ Full |
|
|
353
|
-
|
|
354
|
-
Requirements:
|
|
355
|
-
- WebAssembly support
|
|
356
|
-
- IndexedDB support
|
|
357
|
-
- ES2022+ JavaScript
|
|
358
|
-
|
|
359
|
-
## Security Considerations
|
|
360
|
-
|
|
361
|
-
✅ **Sandboxed**: Runs in browser security sandbox
|
|
362
|
-
✅ **Same-Origin Policy**: Data isolated per domain
|
|
363
|
-
✅ **No Network Exposure**: Zero network attack surface
|
|
364
|
-
⚠️ **Client-Side Storage**: Data accessible to user (don't store secrets)
|
|
365
|
-
⚠️ **Clear on Browser Reset**: User can clear data
|
|
366
|
-
|
|
367
|
-
## Implementation Status
|
|
368
|
-
|
|
369
|
-
**Note**: The WASM backend is planned for Phase 1 of the local-first integration roadmap.
|
|
370
|
-
|
|
371
|
-
Current status:
|
|
372
|
-
- [ ] WASM bindings (pluresdb-wasm crate)
|
|
373
|
-
- [ ] IndexedDB persistence layer
|
|
374
|
-
- [ ] Browser integration examples
|
|
375
|
-
- [x] Unified API with auto-detection
|
|
376
|
-
- [x] Documentation
|
|
377
|
-
|
|
378
|
-
Until WASM implementation is complete, the unified API will fall back to network mode in browser environments. To track progress or contribute, see:
|
|
379
|
-
|
|
380
|
-
- [LOCAL_FIRST_INTEGRATION.md](../../docs/LOCAL_FIRST_INTEGRATION.md)
|
|
381
|
-
- [GitHub Issues](https://github.com/plures/pluresdb/issues)
|
|
382
|
-
|
|
383
|
-
## Next Steps
|
|
384
|
-
|
|
385
|
-
- See [Tauri Integration](./tauri-integration.md) for desktop apps
|
|
386
|
-
- Explore [IPC Integration](./native-ipc-integration.md) for native apps
|
|
387
|
-
- Read [Migration Guide](../../docs/LOCAL_FIRST_INTEGRATION.md#migration-path) for existing apps
|
|
388
|
-
|
|
389
|
-
## Troubleshooting
|
|
390
|
-
|
|
391
|
-
### "WASM backend not yet implemented" error
|
|
392
|
-
|
|
393
|
-
The WASM implementation is in progress. For now, use network mode:
|
|
394
|
-
|
|
395
|
-
```typescript
|
|
396
|
-
const db = new PluresDBLocalFirst({ mode: "network", port: 34567 });
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### IndexedDB quota exceeded
|
|
400
|
-
|
|
401
|
-
Browsers limit IndexedDB storage (typically 50% of free disk space). To handle:
|
|
402
|
-
|
|
403
|
-
```javascript
|
|
404
|
-
try {
|
|
405
|
-
await db.put(id, data);
|
|
406
|
-
} catch (error) {
|
|
407
|
-
if (error.name === "QuotaExceededError") {
|
|
408
|
-
// Handle cleanup or notify user
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
```
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
# PluresDB IPC Demo
|
|
2
|
-
|
|
3
|
-
This example demonstrates how to use PluresDB's IPC (Inter-Process Communication) layer for high-performance local-first database access between processes.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The IPC layer uses shared memory for zero-copy communication, providing:
|
|
8
|
-
- **Low latency**: ~0.5ms per operation
|
|
9
|
-
- **High throughput**: ~50k ops/s
|
|
10
|
-
- **No network exposure**: Secure process isolation
|
|
11
|
-
- **Simple API**: Same interface as other PluresDB modes
|
|
12
|
-
|
|
13
|
-
## Running the Demo
|
|
14
|
-
|
|
15
|
-
### Server Process
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
cargo run --example ipc-server
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### Client Process (in another terminal)
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
cargo run --example ipc-client
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## How It Works
|
|
28
|
-
|
|
29
|
-
1. **Server** creates a shared memory region and starts listening for requests
|
|
30
|
-
2. **Client** connects to the shared memory region
|
|
31
|
-
3. **Messages** are serialized and written to shared memory
|
|
32
|
-
4. **Server** processes requests and writes responses back
|
|
33
|
-
5. **Client** reads responses and returns data to the application
|
|
34
|
-
|
|
35
|
-
## Code Examples
|
|
36
|
-
|
|
37
|
-
### Server
|
|
38
|
-
|
|
39
|
-
```rust
|
|
40
|
-
use pluresdb_ipc::IPCServer;
|
|
41
|
-
use pluresdb_core::CrdtStore;
|
|
42
|
-
use std::sync::{Arc, Mutex};
|
|
43
|
-
|
|
44
|
-
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
45
|
-
// Create database store
|
|
46
|
-
let store = Arc::new(Mutex::new(CrdtStore::default()));
|
|
47
|
-
|
|
48
|
-
// Start IPC server
|
|
49
|
-
let mut server = IPCServer::new("my-app", store)?;
|
|
50
|
-
println!("IPC server started on channel: my-app");
|
|
51
|
-
|
|
52
|
-
// Run server (blocks until shutdown)
|
|
53
|
-
server.start()?;
|
|
54
|
-
|
|
55
|
-
Ok(())
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Client
|
|
60
|
-
|
|
61
|
-
```rust
|
|
62
|
-
use pluresdb_ipc::IPCClient;
|
|
63
|
-
use serde_json::json;
|
|
64
|
-
|
|
65
|
-
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
66
|
-
// Connect to IPC server
|
|
67
|
-
let mut client = IPCClient::connect("my-app")?;
|
|
68
|
-
println!("Connected to IPC server");
|
|
69
|
-
|
|
70
|
-
// Insert data
|
|
71
|
-
let id = client.put("user:1", json!({
|
|
72
|
-
"name": "Alice",
|
|
73
|
-
"email": "alice@example.com"
|
|
74
|
-
}))?;
|
|
75
|
-
println!("Inserted: {}", id);
|
|
76
|
-
|
|
77
|
-
// Retrieve data
|
|
78
|
-
let user = client.get("user:1")?;
|
|
79
|
-
println!("Retrieved: {:?}", user);
|
|
80
|
-
|
|
81
|
-
// List all nodes
|
|
82
|
-
let all = client.list()?;
|
|
83
|
-
println!("Total nodes: {}", all.len());
|
|
84
|
-
|
|
85
|
-
Ok(())
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Performance
|
|
90
|
-
|
|
91
|
-
| Operation | Latency | Throughput |
|
|
92
|
-
|-----------|---------|------------|
|
|
93
|
-
| PUT | ~0.5ms | ~50k ops/s |
|
|
94
|
-
| GET | ~0.3ms | ~70k ops/s |
|
|
95
|
-
| DELETE | ~0.4ms | ~60k ops/s |
|
|
96
|
-
| LIST | ~2ms | ~10k ops/s |
|
|
97
|
-
|
|
98
|
-
Compared to HTTP REST:
|
|
99
|
-
- **10x lower latency**
|
|
100
|
-
- **50x higher throughput**
|
|
101
|
-
- **No network overhead**
|
|
102
|
-
- **No port exposure**
|
|
103
|
-
|
|
104
|
-
## Use Cases
|
|
105
|
-
|
|
106
|
-
- **Desktop Applications**: Electron, Tauri apps that need database access
|
|
107
|
-
- **Microservices**: Local services communicating with a shared database
|
|
108
|
-
- **Multi-Process Apps**: Applications with separate UI and backend processes
|
|
109
|
-
- **Native Apps**: macOS, Windows, Linux applications
|
|
110
|
-
|
|
111
|
-
## Troubleshooting
|
|
112
|
-
|
|
113
|
-
### "Failed to open shared memory"
|
|
114
|
-
- Make sure the server is running first
|
|
115
|
-
- Check that both processes use the same channel name
|
|
116
|
-
- On Unix systems, check `/dev/shm/` permissions
|
|
117
|
-
|
|
118
|
-
### "Request timeout"
|
|
119
|
-
- Server might be overloaded or crashed
|
|
120
|
-
- Increase timeout in client code if needed
|
|
121
|
-
- Check server logs for errors
|
|
122
|
-
|
|
123
|
-
## Next Steps
|
|
124
|
-
|
|
125
|
-
- See `docs/LOCAL_FIRST_INTEGRATION.md` for integration guide
|
|
126
|
-
- See `examples/native-ipc-integration.md` for more examples
|
|
127
|
-
- See `crates/pluresdb-ipc/` for API documentation
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local-First Integration Example
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates how to use PluresDB with the new local-first
|
|
5
|
-
* integration API that automatically selects the best integration method
|
|
6
|
-
* based on the runtime environment.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { PluresDBLocalFirst } from "../legacy/local-first/unified-api.ts";
|
|
10
|
-
|
|
11
|
-
async function main() {
|
|
12
|
-
console.log("=== PluresDB Local-First Integration Example ===\n");
|
|
13
|
-
|
|
14
|
-
// Initialize database with auto-detection
|
|
15
|
-
// In browser: Uses WASM
|
|
16
|
-
// In Tauri: Uses native integration
|
|
17
|
-
// In Node/Deno with PLURESDB_IPC=true: Uses IPC
|
|
18
|
-
// Otherwise: Uses network (HTTP REST)
|
|
19
|
-
const db = new PluresDBLocalFirst({ mode: "auto" });
|
|
20
|
-
|
|
21
|
-
console.log(`✅ Initialized in ${db.getMode()} mode\n`);
|
|
22
|
-
|
|
23
|
-
// Note: Currently defaults to network mode since WASM and IPC
|
|
24
|
-
// are not yet implemented. This demonstrates the API surface.
|
|
25
|
-
|
|
26
|
-
if (db.getMode() === "network") {
|
|
27
|
-
console.log("⚠️ Running in network mode (fallback)");
|
|
28
|
-
console.log(" To use this example, start PluresDB server:");
|
|
29
|
-
console.log(" npm start\n");
|
|
30
|
-
console.log(" Or set PLURESDB_IPC=true for IPC mode (when available)\n");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
// Example 1: Basic CRUD operations
|
|
35
|
-
console.log("Example 1: Basic CRUD Operations");
|
|
36
|
-
console.log("-----------------------------------");
|
|
37
|
-
|
|
38
|
-
// Create
|
|
39
|
-
await db.put("user:alice", {
|
|
40
|
-
type: "User",
|
|
41
|
-
name: "Alice",
|
|
42
|
-
email: "alice@example.com",
|
|
43
|
-
role: "admin",
|
|
44
|
-
createdAt: new Date().toISOString(),
|
|
45
|
-
});
|
|
46
|
-
console.log("✅ Created user:alice");
|
|
47
|
-
|
|
48
|
-
await db.put("user:bob", {
|
|
49
|
-
type: "User",
|
|
50
|
-
name: "Bob",
|
|
51
|
-
email: "bob@example.com",
|
|
52
|
-
role: "user",
|
|
53
|
-
createdAt: new Date().toISOString(),
|
|
54
|
-
});
|
|
55
|
-
console.log("✅ Created user:bob");
|
|
56
|
-
|
|
57
|
-
// Read
|
|
58
|
-
const alice = await db.get("user:alice");
|
|
59
|
-
console.log(`✅ Retrieved user:alice - Name: ${alice?.name}`);
|
|
60
|
-
|
|
61
|
-
// Update
|
|
62
|
-
await db.put("user:alice", {
|
|
63
|
-
...alice,
|
|
64
|
-
role: "superadmin",
|
|
65
|
-
updatedAt: new Date().toISOString(),
|
|
66
|
-
});
|
|
67
|
-
console.log("✅ Updated user:alice role to superadmin");
|
|
68
|
-
|
|
69
|
-
// List all
|
|
70
|
-
const allUsers = await db.list();
|
|
71
|
-
console.log(`✅ Listed ${allUsers.length} total nodes\n`);
|
|
72
|
-
|
|
73
|
-
// Example 2: Vector Search (semantic similarity)
|
|
74
|
-
console.log("Example 2: Vector Search");
|
|
75
|
-
console.log("------------------------");
|
|
76
|
-
|
|
77
|
-
await db.put("note:1", {
|
|
78
|
-
type: "Note",
|
|
79
|
-
text: "I love visiting museums in London",
|
|
80
|
-
tags: ["travel", "culture"],
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
await db.put("note:2", {
|
|
84
|
-
type: "Note",
|
|
85
|
-
text: "Best pizza places in New York",
|
|
86
|
-
tags: ["food", "travel"],
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
await db.put("note:3", {
|
|
90
|
-
type: "Note",
|
|
91
|
-
text: "Art galleries and parks in London are amazing",
|
|
92
|
-
tags: ["culture", "nature"],
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
console.log("✅ Created 3 notes with different content");
|
|
96
|
-
|
|
97
|
-
// Semantic search for London-related content
|
|
98
|
-
const results = await db.vectorSearch("Things about London", 5);
|
|
99
|
-
console.log(`\n🔍 Vector search: "Things about London"`);
|
|
100
|
-
console.log(` Found ${results.length} results`);
|
|
101
|
-
results.forEach((result: any, i: number) => {
|
|
102
|
-
console.log(` ${i + 1}. ${result.data?.text || result.id}`);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Example 3: Cleanup
|
|
106
|
-
console.log("\nExample 3: Cleanup");
|
|
107
|
-
console.log("------------------");
|
|
108
|
-
|
|
109
|
-
await db.delete("user:bob");
|
|
110
|
-
console.log("✅ Deleted user:bob");
|
|
111
|
-
|
|
112
|
-
const afterDelete = await db.list();
|
|
113
|
-
console.log(`✅ ${afterDelete.length} nodes remaining after deletion\n`);
|
|
114
|
-
|
|
115
|
-
} catch (error) {
|
|
116
|
-
if (error instanceof Error && error.message.includes("Failed")) {
|
|
117
|
-
console.error("\n❌ Error:", error.message);
|
|
118
|
-
console.log("\nMake sure PluresDB server is running:");
|
|
119
|
-
console.log(" npm start");
|
|
120
|
-
console.log("\nOr check the documentation for other integration modes:");
|
|
121
|
-
console.log(" docs/LOCAL_FIRST_INTEGRATION.md");
|
|
122
|
-
} else {
|
|
123
|
-
throw error;
|
|
124
|
-
}
|
|
125
|
-
} finally {
|
|
126
|
-
// Close connection
|
|
127
|
-
await db.close();
|
|
128
|
-
console.log("✅ Database connection closed");
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Run the example
|
|
133
|
-
if (import.meta.main) {
|
|
134
|
-
main().catch((error) => {
|
|
135
|
-
console.error("Fatal error:", error);
|
|
136
|
-
Deno.exit(1);
|
|
137
|
-
});
|
|
138
|
-
}
|