@kedem/okdb 1.0.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 +57 -0
- package/README.md +344 -0
- package/banner.jpg +0 -0
- package/bin/okdb.js +2 -0
- package/docs/OKDB-ARCHITECTURE.md +1036 -0
- package/docs/auth-and-sync.md +558 -0
- package/docs/auth-permissions.md +143 -0
- package/docs/change-log.md +169 -0
- package/docs/data-model.md +174 -0
- package/docs/embeddings.md +338 -0
- package/docs/files.md +131 -0
- package/docs/fts.md +139 -0
- package/docs/functions.md +514 -0
- package/docs/getting-started.md +233 -0
- package/docs/http-api.md +705 -0
- package/docs/index.md +115 -0
- package/docs/indexes.md +207 -0
- package/docs/logging.md +116 -0
- package/docs/manifest.json +38 -0
- package/docs/migration.md +154 -0
- package/docs/pipelines.md +598 -0
- package/docs/plugins.md +144 -0
- package/docs/querying.md +204 -0
- package/docs/queue.md +637 -0
- package/docs/sync.md +156 -0
- package/docs/transactions.md +140 -0
- package/docs/ttl.md +375 -0
- package/okdb.js +1 -0
- package/package.json +26 -0
- package/public/admin-app.js +1 -0
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/components/admin-route-host.ok.js +1 -0
- package/public/components/env-picker.ok.js +1 -0
- package/public/components/field-path-input.ok.js +1 -0
- package/public/components/field.html +6 -0
- package/public/components/geo-map.ok.js +1 -0
- package/public/components/ok-cron-input.ok.js +1 -0
- package/public/components/ok-dropzone.ok.js +1 -0
- package/public/components/ok-js-input.ok.js +1 -0
- package/public/components/ok-json-input.ok.js +1 -0
- package/public/components/ok-text-monaco-input.ok.js +1 -0
- package/public/components/theme-toggle.ok.js +1 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/images/logo.png +0 -0
- package/public/images/logo.svg +333 -0
- package/public/index.html +6 -0
- package/public/layouts/_default.ok.html +1 -0
- package/public/layouts/okdb-cube.ok.html +1 -0
- package/public/login-app.js +1 -0
- package/public/login.html +1 -0
- package/public/modules/ok.js +1 -0
- package/public/sections/api/index.ok.html +1 -0
- package/public/sections/api/parts/api-endpoint.ok.js +1 -0
- package/public/sections/auth/index.ok.html +1 -0
- package/public/sections/auth/modals/create-token-modal.ok.js +1 -0
- package/public/sections/auth/modals/edit-token-modal.ok.js +1 -0
- package/public/sections/auth/modals/perm-info-popover.ok.js +1 -0
- package/public/sections/auth/parts/token-detail.ok.js +1 -0
- package/public/sections/auth/parts/token-list.ok.js +1 -0
- package/public/sections/db/index.ok.html +1 -0
- package/public/sections/db/modals/add-item-modal.ok.js +1 -0
- package/public/sections/db/modals/create-env-modal.ok.js +1 -0
- package/public/sections/db/modals/create-fts-modal.ok.js +1 -0
- package/public/sections/db/modals/create-index-modal.ok.js +1 -0
- package/public/sections/db/modals/create-pipeline-modal.ok.js +1 -0
- package/public/sections/db/modals/demo-env-modal.ok.js +1 -0
- package/public/sections/db/modals/remove-env-modal.ok.js +1 -0
- package/public/sections/db/modals/schema-edit-modal.ok.js +1 -0
- package/public/sections/db/parts/db-overview.ok.js +1 -0
- package/public/sections/db/parts/db-pipelines-panel.ok.js +1 -0
- package/public/sections/db/parts/edit-row.ok.js +1 -0
- package/public/sections/db/parts/tm-timeline.ok.js +1 -0
- package/public/sections/db/parts/type-changelog.ok.js +1 -0
- package/public/sections/db/parts/type-list.ok.js +1 -0
- package/public/sections/db/parts/type-pipelines-tab.ok.js +1 -0
- package/public/sections/db/parts/type-schema-tab.ok.js +1 -0
- package/public/sections/db/parts/type-viewer.ok.js +1 -0
- package/public/sections/db/parts/type-violations-tab.ok.js +1 -0
- package/public/sections/docs/index.ok.html +1 -0
- package/public/sections/embeddings/index.ok.html +1 -0
- package/public/sections/embeddings/modals/register-model-modal.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-create-panel.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-embedder-panel.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-engine-declaration-editor.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-engine-list.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-indexer-panel.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-lifecycle-bar.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-model-catalog.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-overview.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-search-panel.ok.js +1 -0
- package/public/sections/embeddings/parts/embed-worker-panel.ok.js +1 -0
- package/public/sections/embeddings/parts/embeddings-engine-panel.ok.js +1 -0
- package/public/sections/embeddings/parts/engines-overview.ok.js +1 -0
- package/public/sections/embeddings/parts/pipeline-create-panel.ok.js +1 -0
- package/public/sections/engines/engine-panel-shared-style.js +1 -0
- package/public/sections/engines/engine-ui-utils.js +1 -0
- package/public/sections/engines/index.ok.html +1 -0
- package/public/sections/engines/modals/engine-modal.ok.js +1 -0
- package/public/sections/engines/parts/engine-declaration-editor.ok.js +1 -0
- package/public/sections/engines/parts/engine-lifecycle-actions.ok.js +1 -0
- package/public/sections/engines/parts/engine-panel-shell.ok.js +1 -0
- package/public/sections/engines/parts/engine-resource-card.ok.js +1 -0
- package/public/sections/engines/parts/engine-row-item.ok.js +1 -0
- package/public/sections/engines/parts/generic-engine-panel.ok.js +1 -0
- package/public/sections/files/index.ok.html +1 -0
- package/public/sections/files/parts/files-blob-status.ok.js +1 -0
- package/public/sections/files/parts/files-collection-list.ok.js +1 -0
- package/public/sections/files/parts/files-collection-panel.ok.js +1 -0
- package/public/sections/files/parts/files-file-list.ok.js +1 -0
- package/public/sections/files/parts/files-overview.ok.js +1 -0
- package/public/sections/files/parts/files-path-browser.ok.js +1 -0
- package/public/sections/files/parts/files-upload-panel.ok.js +1 -0
- package/public/sections/functions/index.ok.html +1 -0
- package/public/sections/functions/modals/function-modal.ok.js +1 -0
- package/public/sections/functions/parts/function-detail.ok.js +1 -0
- package/public/sections/functions/parts/function-logs.ok.js +1 -0
- package/public/sections/functions/parts/function-runner.ok.js +1 -0
- package/public/sections/functions/parts/functions-list.ok.js +1 -0
- package/public/sections/license/index.ok.html +1 -0
- package/public/sections/license/parts/license-panel.ok.js +1 -0
- package/public/sections/processors/index.ok.html +1 -0
- package/public/sections/queue/index.ok.html +1 -0
- package/public/sections/queue/modals/create-bucket-modal.ok.js +1 -0
- package/public/sections/queue/modals/edit-bucket-modal.ok.js +1 -0
- package/public/sections/queue/modals/edit-job-modal.ok.js +1 -0
- package/public/sections/queue/modals/enqueue-job-modal.ok.js +1 -0
- package/public/sections/queue/modals/job-type-modal.ok.js +1 -0
- package/public/sections/queue/parts/ok-job-form.ok.js +1 -0
- package/public/sections/queue/parts/queue-buckets.ok.js +1 -0
- package/public/sections/queue/parts/queue-job-types.ok.js +1 -0
- package/public/sections/queue/parts/queue-jobs.ok.js +1 -0
- package/public/sections/queue/parts/queue-types.ok.js +1 -0
- package/public/sections/queue/parts/queue-workers.ok.js +1 -0
- package/public/sections/sync/index.ok.html +5 -0
- package/public/sections/sync/parts/sync-node-detail.ok.js +1 -0
- package/public/sections/sync/parts/sync-retention.ok.js +1 -0
- package/public/sections/sync/parts/sync-topology.ok.js +1 -0
- package/public/sections/system/index.ok.html +1 -0
- package/public/sections/system/modals/data-ops-modal.ok.js +1 -0
- package/public/sections/system/parts/system-api-panel.ok.js +1 -0
- package/public/sections/system/parts/system-auth-panel.ok.js +1 -0
- package/public/sections/system/parts/system-log-history.ok.js +1 -0
- package/public/sections/system/parts/system-log.ok.js +1 -0
- package/public/sections/system/parts/system-status.ok.js +1 -0
- package/public/sections/system/parts/system-sync-panel.ok.js +1 -0
- package/public/sections/views/index.ok.html +1 -0
- package/public/sections/views/modals/create-view-modal.ok.js +1 -0
- package/public/sections/views/parts/view-detail.ok.js +1 -0
- package/public/sections/views/parts/views-list.ok.js +1 -0
- package/public/sections/views/parts/views-overview.ok.js +1 -0
- package/public/setup-app.js +1 -0
- package/public/setup.html +1 -0
- package/public/site.webmanifest +1 -0
- package/public/stores/auth-store.js +1 -0
- package/public/stores/events-store.js +1 -0
- package/public/stores/functions-store.js +1 -0
- package/public/stores/okdb-store.js +1 -0
- package/public/stores/theme-store.js +1 -0
- package/public/styles.css +1 -0
- package/public/test-cron-input.html +10 -0
- package/public/test-json-input.html +101 -0
- package/public/util/permissions.js +1 -0
- package/public/util/sift-schema.js +1 -0
- package/public/vendor/okjs/ok.esm.min.js +2 -0
- package/public/vendor/okjs/toolkit/behavior/async.ok.js +1 -0
- package/public/vendor/okjs/toolkit/components/ok-chart.ok.js +1 -0
- package/public/vendor/okjs/toolkit/components/ok-doc-viewer.ok.js +1 -0
- package/public/vendor/okjs/toolkit/components/ok-marked.ok.js +1 -0
- package/public/vendor/okjs/toolkit/components/ok-monaco.ok.js +1 -0
- package/public/vendor/okjs/toolkit/core/ok-layer-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/core/ok-layer.ok.js +1 -0
- package/public/vendor/okjs/toolkit/core/ok-overlay.ok.js +1 -0
- package/public/vendor/okjs/toolkit/core/ok-sandbox.ok.js +1 -0
- package/public/vendor/okjs/toolkit/core/transition.ok.js +1 -0
- package/public/vendor/okjs/toolkit/core/virtualized.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-console-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-console.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-inspector-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-inspector.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-js-tree.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-timeline-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/devtools/ok-timeline.ok.js +1 -0
- package/public/vendor/okjs/toolkit/docs/doc-viewer.ok.js +1 -0
- package/public/vendor/okjs/toolkit/editor/ok-live-component.ok.js +1 -0
- package/public/vendor/okjs/toolkit/editor/ok-live-example.ok.js +1 -0
- package/public/vendor/okjs/toolkit/editor/ok-live-shell.ok.js +1 -0
- package/public/vendor/okjs/toolkit/elements/ok-dropdown.ok.js +1 -0
- package/public/vendor/okjs/toolkit/elements/ok-icon.ok.js +1 -0
- package/public/vendor/okjs/toolkit/elements/ok-select.ok.js +1 -0
- package/public/vendor/okjs/toolkit/elements/ok-table.ok.js +1 -0
- package/public/vendor/okjs/toolkit/errors/ok-crash-boundary.ok.js +1 -0
- package/public/vendor/okjs/toolkit/errors/ok-crash-info.ok.js +1 -0
- package/public/vendor/okjs/toolkit/i18n/i18n-editor-examples.ok.js +1 -0
- package/public/vendor/okjs/toolkit/i18n/i18n-editor.ok.js +1 -0
- package/public/vendor/okjs/toolkit/i18n/i18n-key-editor-tips.ok.js +1 -0
- package/public/vendor/okjs/toolkit/i18n/i18n-key-editor.ok.js +1 -0
- package/public/vendor/okjs/toolkit/i18n/i18n-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/i18n/ok-i18n.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-contextmenu.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-dismiss-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-draggable.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-flyover-panel.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-flyover.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-highlight-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-highlight.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-hotkeys-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-picker-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-popout-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-popout.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-portal-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/interaction/ok-submenu.ok.js +1 -0
- package/public/vendor/okjs/toolkit/layout/ok-resizer.ok.js +1 -0
- package/public/vendor/okjs/toolkit/manifest.js +1 -0
- package/public/vendor/okjs/toolkit/modals/ok-modal-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/modals/ok-modal.ok.js +1 -0
- package/public/vendor/okjs/toolkit/modals/ok-toast-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/modals/ok-window.ok.js +1 -0
- package/public/vendor/okjs/toolkit/navigation/hash-router.ok.js +1 -0
- package/public/vendor/okjs/toolkit/navigation/history-router.ok.js +1 -0
- package/public/vendor/okjs/toolkit/navigation/router.ok.js +1 -0
- package/public/vendor/okjs/toolkit/sync/reactive-sync-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/sync/reactive-sync.js +1 -0
- package/public/vendor/okjs/toolkit/theming/blocks/ok-design-button.css.js +1 -0
- package/public/vendor/okjs/toolkit/theming/blocks/ok-design-input.css.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-design-style.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-design-vars.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-design.ok.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-input.ok.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-service.ok.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-style.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-utils.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-variable.ok.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-vm.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor.ok.js +1 -0
- package/public/vendor/okjs/toolkit/theming/ok-theme.ok.js +1 -0
- package/public/view-models/type-query-vm.js +1 -0
- package/types/environment.d.ts +130 -0
- package/types/errors.d.ts +98 -0
- package/types/features/admin.d.ts +4 -0
- package/types/features/api.d.ts +18 -0
- package/types/features/auth.d.ts +31 -0
- package/types/features/embeddings.d.ts +39 -0
- package/types/features/engines.d.ts +23 -0
- package/types/features/files.d.ts +29 -0
- package/types/features/fts.d.ts +25 -0
- package/types/features/functions.d.ts +23 -0
- package/types/features/mcp.d.ts +17 -0
- package/types/features/pipelines.d.ts +19 -0
- package/types/features/queue.d.ts +189 -0
- package/types/features/sync.d.ts +34 -0
- package/types/features/time-machine.d.ts +32 -0
- package/types/features/views.d.ts +16 -0
- package/types/index.d.ts +153 -0
- package/types/options.d.ts +202 -0
package/docs/files.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Files
|
|
2
|
+
|
|
3
|
+
OKDB includes content-addressable blob storage integrated with the database. Files are stored as SHA-256-hashed blobs on disk and tracked as metadata records in the `~files` OKDB type.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Storing a file
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// From a Buffer
|
|
11
|
+
const file = await okdb.files.put(buffer, {
|
|
12
|
+
path: '/uploads/docs/report.pdf',
|
|
13
|
+
mime: 'application/pdf',
|
|
14
|
+
});
|
|
15
|
+
// file = { id, hash, size, mime, path, createdAt }
|
|
16
|
+
|
|
17
|
+
// From a stream
|
|
18
|
+
const stream = fs.createReadStream('/local/file.jpg');
|
|
19
|
+
const file = await okdb.files.put(stream, {
|
|
20
|
+
path: '/avatars/alice.jpg',
|
|
21
|
+
mime: 'image/jpeg',
|
|
22
|
+
id: 'avatar-alice', // optional explicit ID (UUID generated if omitted)
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The blob is written to `<okdb-root>/blobs/<first2>/<rest>` using the SHA-256 hex as the filename. Storing the same bytes twice stores them once — the second `put` returns a record pointing to the existing blob.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Reading a file
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
// Get metadata by ID
|
|
34
|
+
const meta = okdb.files.get('avatar-alice');
|
|
35
|
+
// { id, hash, size, mime, path, createdAt }
|
|
36
|
+
|
|
37
|
+
// Get the raw Buffer
|
|
38
|
+
const buf = await okdb.files.read('avatar-alice');
|
|
39
|
+
|
|
40
|
+
// Stream the blob
|
|
41
|
+
const stream = okdb.files.stream('avatar-alice');
|
|
42
|
+
stream.pipe(response);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Deleting a file
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
await okdb.files.remove('avatar-alice');
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Deletion removes the metadata record. The blob bytes are garbage-collected when no other `~files` record references the same hash.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Listing files
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
// All files
|
|
61
|
+
for (const meta of okdb.files.list()) {
|
|
62
|
+
console.log(meta.path, meta.size, meta.hash);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// By path prefix
|
|
66
|
+
for (const meta of okdb.files.list({ prefix: '/uploads/' })) { ... }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## HTTP upload and download
|
|
72
|
+
|
|
73
|
+
When the HTTP server is running, files are accessible via REST:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Upload (multipart or raw body)
|
|
77
|
+
curl -X POST http://localhost:8080/api/files \
|
|
78
|
+
-H "Authorization: Bearer my-token" \
|
|
79
|
+
-F "file=@report.pdf" \
|
|
80
|
+
-F "path=/docs/report.pdf"
|
|
81
|
+
|
|
82
|
+
# Download by ID
|
|
83
|
+
curl http://localhost:8080/api/files/avatar-alice \
|
|
84
|
+
-H "Authorization: Bearer my-token" \
|
|
85
|
+
--output avatar.jpg
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Files per environment
|
|
91
|
+
|
|
92
|
+
Each OKDB environment has its own `~files` type (metadata lives in that env), but all environments share the same blob directory at the OKDB root level. This means:
|
|
93
|
+
|
|
94
|
+
- A blob stored in the `default` env and the same blob in `analytics` share the same bytes on disk
|
|
95
|
+
- Reference counting tracks how many metadata records point to each hash
|
|
96
|
+
- The blob is only deleted when the ref count drops to zero
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// Files in a custom environment
|
|
100
|
+
const analyticsEnv = okdb.env('analytics');
|
|
101
|
+
const file = await analyticsEnv.files.put(buffer, { path: '/exports/data.csv', mime: 'text/csv' });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Storage layout
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
<okdb-root>/blobs/
|
|
110
|
+
ab/cdef1234... ← blob file (path = first2/rest of SHA-256 hex)
|
|
111
|
+
ff/0123abcd...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
In LMDB (default env):
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
~files ← metadata records (id → { hash, size, mime, path, createdAt })
|
|
118
|
+
~file:blob_status ← ref-counting sub-db (hash → { refs, nodes })
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Sync
|
|
124
|
+
|
|
125
|
+
`~files` metadata **is synced** across cluster nodes. Blob bytes are **not** — they are transferred separately via a blob mesh protocol (HTTP) when a node needs a blob it doesn't have locally.
|
|
126
|
+
|
|
127
|
+
This means: metadata replicates instantly; actual bytes follow on demand.
|
|
128
|
+
|
|
129
|
+
:::note
|
|
130
|
+
Blob sync is pull-based. A node will fetch the blob from a peer only when a consumer requests it and the local blob is missing.
|
|
131
|
+
:::
|
package/docs/fts.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Full-Text Search
|
|
2
|
+
|
|
3
|
+
OKDB includes a built-in full-text search engine backed by an LMDB inverted index. Each FTS index lives in its own LMDB environment (separate directory) so it can be independently compacted or rebuilt without touching user data.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Registering an FTS index
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
await okdb.fts.register('articles', 'content', {
|
|
11
|
+
fields: ['title', 'body'], // fields to index
|
|
12
|
+
tokenizer: {
|
|
13
|
+
minTokenLength: 2,
|
|
14
|
+
maxTokenLength: 64,
|
|
15
|
+
keepNumbers: true,
|
|
16
|
+
toLower: true, // case-insensitive search
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The index builds from existing data immediately after registration. Wait for it:
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
await okdb.fts.ready('articles', 'content');
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Multiple FTS indexes on one type
|
|
28
|
+
|
|
29
|
+
You can have several FTS indexes on the same type, each covering different fields or using different tokenizer settings:
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
await okdb.fts.register('products', 'name', { fields: ['name'] });
|
|
33
|
+
await okdb.fts.register('products', 'description', { fields: ['description'], tokenizer: { minTokenLength: 3 } });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Querying
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
const results = okdb.ftsQuery('articles', 'content', 'embedded database Node.js');
|
|
42
|
+
for (const { key, value } of results) {
|
|
43
|
+
console.log(key, value.title);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`ftsQuery` returns records that contain **any** of the query tokens (OR semantics). Results are not ranked by relevance — they are returned in primary-key order.
|
|
48
|
+
|
|
49
|
+
### Combining FTS with field filters
|
|
50
|
+
|
|
51
|
+
Pass a sift-compatible filter as the fourth argument to narrow results:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
// Articles matching the query that are also published
|
|
55
|
+
const results = okdb.ftsQuery('articles', 'content', 'database performance', {
|
|
56
|
+
status: 'published',
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Options
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
const results = okdb.ftsQuery('articles', 'content', 'hello world', null, {
|
|
64
|
+
limit: 20,
|
|
65
|
+
offset: 0,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Index management
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
// Check if an index exists
|
|
75
|
+
okdb.fts.has('articles', 'content'); // → boolean
|
|
76
|
+
|
|
77
|
+
// Get status
|
|
78
|
+
okdb.fts.status('articles', 'content'); // → 'creating' | 'ready' | null
|
|
79
|
+
|
|
80
|
+
// List all FTS indexes on a type
|
|
81
|
+
okdb.fts.list('articles');
|
|
82
|
+
// → [{ name, status, config, created, updated, sizeBytes }]
|
|
83
|
+
|
|
84
|
+
// Drop an index
|
|
85
|
+
await okdb.fts.drop('articles', 'content');
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## How it works
|
|
91
|
+
|
|
92
|
+
OKDB's FTS engine is a simple inverted posting list:
|
|
93
|
+
|
|
94
|
+
1. On every write, the changed record's indexed fields are tokenized
|
|
95
|
+
2. Removed tokens are deleted from the posting list (`post` sub-db)
|
|
96
|
+
3. Added tokens are inserted (`token → docKey` pairs in a `dupSort` LMDB sub-db)
|
|
97
|
+
4. A forward index (`docs` sub-db: `docKey → [tokens]`) tracks which tokens each doc holds, enabling correct updates
|
|
98
|
+
|
|
99
|
+
Token processing (default):
|
|
100
|
+
|
|
101
|
+
- Split on whitespace and punctuation
|
|
102
|
+
- Lowercase
|
|
103
|
+
- Discard tokens shorter than `minTokenLength` (default 2) or longer than `maxTokenLength` (default 64)
|
|
104
|
+
- Numbers kept by default (`keepNumbers: true`)
|
|
105
|
+
|
|
106
|
+
### Storage layout
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
~fts/<envName>/<type>/<indexName>/
|
|
110
|
+
post dupSort=true token → docKey (inverted list)
|
|
111
|
+
docs docKey → tokens (forward index)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
FTS environments are `sync: false` — they are never replicated. On a new node they rebuild from synced type data automatically.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Example: articles with FTS
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
await okdb.ensureType('articles');
|
|
122
|
+
await okdb.fts.register('articles', 'search', {
|
|
123
|
+
fields: ['title', 'body', 'tags'],
|
|
124
|
+
});
|
|
125
|
+
await okdb.fts.ready('articles', 'search');
|
|
126
|
+
|
|
127
|
+
await okdb.put('articles', 'a1', {
|
|
128
|
+
title: 'Getting started with LMDB',
|
|
129
|
+
body: 'LMDB is a B+ tree key-value store with MVCC...',
|
|
130
|
+
tags: ['database', 'lmdb', 'storage'],
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const results = okdb.ftsQuery('articles', 'search', 'LMDB key value');
|
|
134
|
+
// → includes 'a1'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
:::tip
|
|
138
|
+
FTS is good for keyword search across free-form text. For semantic similarity ("find documents about the same topic"), use [Embeddings](./embeddings.md) instead.
|
|
139
|
+
:::
|