@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/plugins.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Plugins
|
|
2
|
+
|
|
3
|
+
Plugins are first-class addons that extend OKDB before it opens. They integrate into the lifecycle cleanly: registered before `open()`, started after `open()`, stopped before `close()`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Registering a plugin
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
const okdb = new OKDB('./db');
|
|
11
|
+
|
|
12
|
+
okdb.plugins.register(MyPlugin, {
|
|
13
|
+
/* options */
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
await okdb.open();
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Plugins must be registered **before** `okdb.open()`. Attempting to register after open throws `INVALID_STATE`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Writing a plugin
|
|
24
|
+
|
|
25
|
+
A plugin module is a plain object with a `name`, an optional `requires` list, and a `register` function that returns an instance.
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// my-plugin.js
|
|
29
|
+
module.exports = {
|
|
30
|
+
name: 'my-plugin',
|
|
31
|
+
|
|
32
|
+
// Other plugin names that must be registered first
|
|
33
|
+
requires: [],
|
|
34
|
+
|
|
35
|
+
// Called synchronously during okdb.plugins.register().
|
|
36
|
+
// Must NOT do IO. Returns the plugin instance.
|
|
37
|
+
register(okdb, options) {
|
|
38
|
+
// Attach routes, listen to events, etc.
|
|
39
|
+
okdb.http.get('/api/my-plugin/ping', async (req, res) => {
|
|
40
|
+
res.json({ ok: true });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// The returned object becomes the instance
|
|
44
|
+
return {
|
|
45
|
+
async start(okdb) {
|
|
46
|
+
// Called after okdb.open() — IO is allowed here
|
|
47
|
+
console.log('my-plugin started');
|
|
48
|
+
},
|
|
49
|
+
async stop(okdb) {
|
|
50
|
+
// Called before okdb.close() — clean up everything
|
|
51
|
+
console.log('my-plugin stopped');
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
const MyPlugin = require('./my-plugin');
|
|
60
|
+
okdb.plugins.register(MyPlugin, {
|
|
61
|
+
/* options passed to register() */
|
|
62
|
+
});
|
|
63
|
+
await okdb.open();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
After registration, `okdb.my-plugin` is set to the instance object — so the plugin becomes a property on `okdb`:
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
okdb['my-plugin']; // → the instance returned by register()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
:::note
|
|
73
|
+
Plugin name must not conflict with existing OKDB properties (`env`, `put`, `get`, `http`, etc.). Registration throws `PLUGIN_NAME_CONFLICT` if there's a clash.
|
|
74
|
+
:::
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Lifecycle contract
|
|
79
|
+
|
|
80
|
+
| Phase | Hook | IO allowed | Purpose |
|
|
81
|
+
| ------------------------- | ----- | ---------- | --------------------------------------------- |
|
|
82
|
+
| `register(okdb, options)` | sync | **no** | Attach routes, event listeners, declare types |
|
|
83
|
+
| `instance.start(okdb)` | async | **yes** | Start servers, timers, workers |
|
|
84
|
+
| `instance.stop(okdb)` | async | **yes** | Stop everything started in `start()` |
|
|
85
|
+
|
|
86
|
+
If any plugin's `start()` throws, all already-started plugins are stopped in reverse order before the error propagates.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Plugin dependencies
|
|
91
|
+
|
|
92
|
+
Use `requires` to declare that another plugin must be registered first:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
module.exports = {
|
|
96
|
+
name: 'payments',
|
|
97
|
+
requires: ['auth'], // 'auth' plugin must be registered before 'payments'
|
|
98
|
+
register(okdb, options) { ... },
|
|
99
|
+
};
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
OKDB checks this at registration time and throws `PLUGIN_DEPENDENCY_MISSING` if the dependency isn't registered yet.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Example: type initializer plugin
|
|
107
|
+
|
|
108
|
+
A common pattern is a plugin that ensures types and indexes exist at startup:
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
module.exports = {
|
|
112
|
+
name: 'schema',
|
|
113
|
+
register(okdb, options) {
|
|
114
|
+
return {
|
|
115
|
+
async start(okdb) {
|
|
116
|
+
await okdb.ensureType('users', {
|
|
117
|
+
indexes: [['email'], ['role', 'createdAt']],
|
|
118
|
+
});
|
|
119
|
+
await okdb.ensureType('sessions', {
|
|
120
|
+
indexes: [['userId'], ['expiresAt']],
|
|
121
|
+
});
|
|
122
|
+
console.log('[schema] types ready');
|
|
123
|
+
},
|
|
124
|
+
async stop() {},
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Listing registered plugins
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
const names = okdb.plugins._plugins.map((p) => p.module.name);
|
|
136
|
+
// e.g. ['schema', 'auth', 'payments']
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The `okdb.info` response also includes the plugin list:
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
const info = await fetch('/api/info').then((r) => r.json());
|
|
143
|
+
info.plugins; // → ['schema', 'auth', 'payments']
|
|
144
|
+
```
|
package/docs/querying.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Querying
|
|
2
|
+
|
|
3
|
+
OKDB provides a layered query model: fast synchronous reads by key, ordered range scans, index-narrowed scans, and MongoDB-style in-process filtering.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Single record reads
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// Returns value or undefined
|
|
11
|
+
const user = okdb.get('users', 'alice');
|
|
12
|
+
|
|
13
|
+
// Returns { value, version } or undefined
|
|
14
|
+
const entry = okdb.getEntry('users', 'alice');
|
|
15
|
+
|
|
16
|
+
// Multiple keys at once — returns an array in the same order (undefined for missing)
|
|
17
|
+
const [alice, bob] = okdb.getMany('users', ['alice', 'bob']);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
All reads are **synchronous**. LMDB maps the database file directly into process memory; there's no async I/O, no network call, no serialisation beyond a single decode.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Range scans
|
|
25
|
+
|
|
26
|
+
Range scans return **lazy LMDB iterables**. They are cursor-backed and produce `{ key, value, version }` entries.
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
// All records in default order (key-lexicographic)
|
|
30
|
+
for (const { key, value } of okdb.getRange('users')) {
|
|
31
|
+
console.log(key, value.name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Bounded range
|
|
35
|
+
for (const { key, value } of okdb.getRange('users', {
|
|
36
|
+
start: 'a', // inclusive lower bound
|
|
37
|
+
end: 'b', // inclusive upper bound
|
|
38
|
+
limit: 100,
|
|
39
|
+
reverse: false,
|
|
40
|
+
})) { ... }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Convenience iterables for when you only need one dimension:
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Keys only
|
|
47
|
+
for (const key of okdb.getKeys('users')) { ... }
|
|
48
|
+
|
|
49
|
+
// Values only
|
|
50
|
+
for (const value of okdb.getValues('users')) { ... }
|
|
51
|
+
|
|
52
|
+
// Lexicographic prefix
|
|
53
|
+
for (const { key, value } of okdb.getByPrefix('users', 'team:')) { ... }
|
|
54
|
+
|
|
55
|
+
// Record count (no scan — read from index metadata)
|
|
56
|
+
const total = okdb.getCount('users');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
:::warning Cursor invalidation
|
|
60
|
+
Lazy iterables are invalidated the moment a write transaction opens on the same environment. If you `await` anything between iterating and finishing the cursor, materialise first:
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
const all = Array.from(okdb.getValues('users'));
|
|
64
|
+
await doSomethingAsync();
|
|
65
|
+
// safe to use `all` here
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
:::
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## MongoDB-style query
|
|
73
|
+
|
|
74
|
+
`query()` applies a [sift](https://github.com/crcn/sift.js) filter over a range scan. Sift supports the full MongoDB query operator syntax.
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
// Basic equality
|
|
78
|
+
const admins = okdb.query('users', { role: 'admin' });
|
|
79
|
+
|
|
80
|
+
// Comparison operators
|
|
81
|
+
const seniors = okdb.query('users', { age: { $gte: 65 } });
|
|
82
|
+
|
|
83
|
+
// $in / $nin
|
|
84
|
+
const staff = okdb.query('users', { role: { $in: ['admin', 'moderator'] } });
|
|
85
|
+
|
|
86
|
+
// Nested fields
|
|
87
|
+
const verified = okdb.query('users', { 'profile.verified': true });
|
|
88
|
+
|
|
89
|
+
// Logical operators
|
|
90
|
+
const results = okdb.query('users', {
|
|
91
|
+
$and: [{ role: 'member' }, { createdAt: { $gt: Date.now() - 7 * 86400_000 } }],
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Narrowing with an index
|
|
96
|
+
|
|
97
|
+
Without an index hint, `query()` scans every record. With one, it uses the index to iterate only matching entries:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
// Only scans records where role === 'admin'
|
|
101
|
+
const admins = okdb.query(
|
|
102
|
+
'users',
|
|
103
|
+
{ role: 'admin', age: { $gte: 30 } },
|
|
104
|
+
{
|
|
105
|
+
index: ['role'],
|
|
106
|
+
prefix: ['admin'],
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// With composite index: role + createdAt
|
|
111
|
+
const recent = okdb.query(
|
|
112
|
+
'users',
|
|
113
|
+
{ active: true },
|
|
114
|
+
{
|
|
115
|
+
index: ['role', 'createdAt'],
|
|
116
|
+
prefix: ['admin'],
|
|
117
|
+
reverse: true,
|
|
118
|
+
limit: 20,
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
:::tip
|
|
124
|
+
There is no query planner. If you pass `index`, OKDB uses it without cost analysis. Pick the most selective index for your query by hand.
|
|
125
|
+
:::
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Index scans
|
|
130
|
+
|
|
131
|
+
`byIndex` iterates entries in index order, returning `{ key, value, version, indexKey }`.
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
// All records in order of the 'score' field
|
|
135
|
+
for (const { key, value, indexKey } of okdb.byIndex('leaderboard', ['score'], { reverse: true, limit: 10 })) {
|
|
136
|
+
console.log(key, value.name, indexKey[0]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Exact prefix match: all articles by author 'alice'
|
|
140
|
+
for (const { key, value } of okdb.byIndex('articles', ['author'], {
|
|
141
|
+
prefix: ['alice'],
|
|
142
|
+
})) { ... }
|
|
143
|
+
|
|
144
|
+
// Range on composite index: articles by 'alice' published in the last week
|
|
145
|
+
const since = Date.now() - 7 * 86400_000;
|
|
146
|
+
for (const { key, value } of okdb.byIndex('articles', ['author', 'publishedAt'], {
|
|
147
|
+
start: ['alice', since],
|
|
148
|
+
end: ['alice', Infinity],
|
|
149
|
+
})) { ... }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Options
|
|
153
|
+
|
|
154
|
+
| Option | Type | Description |
|
|
155
|
+
| ------------------- | ------- | ------------------------------------------------- |
|
|
156
|
+
| `prefix` | `any[]` | Index entries must start with these values |
|
|
157
|
+
| `start` | `any[]` | Inclusive lower bound (full index key) |
|
|
158
|
+
| `end` | `any[]` | Inclusive upper bound |
|
|
159
|
+
| `reverse` | boolean | Scan in descending order |
|
|
160
|
+
| `limit` | number | Maximum entries to return |
|
|
161
|
+
| `offset` | number | Skip this many entries |
|
|
162
|
+
| `includeViolations` | boolean | For unique indexes: include all violating entries |
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Geo query
|
|
167
|
+
|
|
168
|
+
OKDB has a built-in geospatial index based on geohash. Register a geo index on a field that stores `{ lat, lon }` (or an `[lat, lon]` array):
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
await okdb.registerIndex('places', ['location'], { type: 'geo', precision: 7 });
|
|
172
|
+
|
|
173
|
+
// Store records with lat/lon
|
|
174
|
+
await okdb.put('places', 'eiffel', { name: 'Eiffel Tower', location: { lat: 48.8584, lon: 2.2945 } });
|
|
175
|
+
|
|
176
|
+
// Radius query — returns records within N metres of a point
|
|
177
|
+
const nearby = okdb.geoQuery('places', 'location', {
|
|
178
|
+
lat: 48.8566,
|
|
179
|
+
lon: 2.3522,
|
|
180
|
+
radius: 5000, // metres
|
|
181
|
+
});
|
|
182
|
+
for (const { key, value, distance } of nearby) {
|
|
183
|
+
console.log(value.name, Math.round(distance), 'm');
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Internally, geohash prefix expansion covers the radius at the registered precision. Precision 7 gives ~76m cell size — good for city-level queries. For sub-10m accuracy, use precision 9.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Range options reference
|
|
192
|
+
|
|
193
|
+
Most scan methods accept the same range options bag:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
{
|
|
197
|
+
start?: any; // inclusive start key / index key
|
|
198
|
+
end?: any; // inclusive end key / index key
|
|
199
|
+
limit?: number; // max entries returned
|
|
200
|
+
offset?: number; // entries to skip
|
|
201
|
+
reverse?: boolean; // descending order
|
|
202
|
+
prefix?: any[]; // index prefix (byIndex / query only)
|
|
203
|
+
}
|
|
204
|
+
```
|