@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/http-api.md
ADDED
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
# HTTP API
|
|
2
|
+
|
|
3
|
+
OKDB includes a built-in HTTP server with a REST API, sync endpoint, and admin UI. It can run as a standalone server **or** be integrated into an existing Express, Fastify, or raw Node.js server — your choice.
|
|
4
|
+
|
|
5
|
+
## Generic pipelines
|
|
6
|
+
|
|
7
|
+
The generic `pipelines` feature exposes env-scoped CRUD and inspection routes:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
GET /api/pipelines/templates
|
|
11
|
+
GET /api/pipelines/templates/:template
|
|
12
|
+
POST /api/pipelines/templates/:template/preview
|
|
13
|
+
GET /api/pipelines
|
|
14
|
+
GET /api/env/:env/pipelines
|
|
15
|
+
GET /api/env/:env/pipelines/:pipeline
|
|
16
|
+
POST /api/env/:env/pipelines
|
|
17
|
+
POST /api/env/:env/pipelines/templates/:template/create
|
|
18
|
+
POST /api/env/:env/pipelines/scaffold
|
|
19
|
+
POST /api/env/:env/pipelines/:pipeline/start
|
|
20
|
+
POST /api/env/:env/pipelines/:pipeline/stop
|
|
21
|
+
DELETE /api/env/:env/pipelines/:pipeline
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Pipeline create requests must reference engines that already exist.
|
|
25
|
+
`POST /api/env/:env/pipelines/scaffold` is the atomic convenience variant: it creates one or more env-owned engines and then persists the pipeline record, cleaning up already-created engines if later validation fails.
|
|
26
|
+
`GET /api/pipelines/templates` is the pipeline-only filtered view of the shared template registry; it returns starter plans whose `kind` is `pipeline`.
|
|
27
|
+
`POST /api/pipelines/templates/:template/preview` expands one of those starters into the concrete create payload it would execute.
|
|
28
|
+
`POST /api/env/:env/pipelines/templates/:template/create` executes that plan in the target environment.
|
|
29
|
+
`GET /api/pipelines` aggregates generic pipeline records across all opened environments.
|
|
30
|
+
Pipeline reads include derived aggregate health and member engine runtime state.
|
|
31
|
+
In the admin API explorer these routes are grouped under the `pipelines` tag.
|
|
32
|
+
|
|
33
|
+
Typical pipeline read responses include:
|
|
34
|
+
|
|
35
|
+
- pipeline `status` and derived `health`
|
|
36
|
+
- ordered member `engines`
|
|
37
|
+
- per-member `role`, `type`, `name`, `state`, `status`, `isRunning`
|
|
38
|
+
- ownership/runtime hints such as `owned`, `storeEnv`, `lag`, `progress`, `cursorKey`, and `error`
|
|
39
|
+
|
|
40
|
+
Embeddings-specific env/type pipeline routes are now layered on top of this same generic model when a matching generic pipeline record exists.
|
|
41
|
+
|
|
42
|
+
In practice that means:
|
|
43
|
+
|
|
44
|
+
- `POST /api/env/:env/type/:type/pipelines` creates the embeddings engines and the env-local generic pipeline record
|
|
45
|
+
- `GET /api/env/:env/type/:type/pipelines` prefers generic pipeline-backed summaries and only falls back to legacy engine grouping for older pipelines
|
|
46
|
+
- specialized lifecycle routes such as `.../start`, `.../stop`, and `DELETE .../:pipeline` delegate to the generic pipeline feature when possible
|
|
47
|
+
- shared embedder members remain preserved during embeddings pipeline stop/delete behavior
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Starting the server
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
okdb.http.listen(8080);
|
|
55
|
+
// or with a host:
|
|
56
|
+
okdb.http.listen(8080, '0.0.0.0');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The HTTP server is optional. You can use OKDB entirely in-process without it.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Authentication
|
|
64
|
+
|
|
65
|
+
### Bearer token
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
const okdb = new OKDB('./db', {
|
|
69
|
+
api: { tokens: ['my-secret-token'] },
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
curl http://localhost:8080/api/type/users \
|
|
75
|
+
-H "Authorization: Bearer my-secret-token"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Basic auth (admin UI)
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
admin: {
|
|
82
|
+
auth: {
|
|
83
|
+
user: 'admin',
|
|
84
|
+
pass: 'secret',
|
|
85
|
+
cookieSecret: 'change-me-in-production',
|
|
86
|
+
cookieTtlMs: 3_600_000,
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Operations metadata model
|
|
94
|
+
|
|
95
|
+
OKDB's HTTP layer is also the current **operations registry** for the project.
|
|
96
|
+
|
|
97
|
+
Routes can now carry canonical operation metadata that powers:
|
|
98
|
+
|
|
99
|
+
- `/api/docs`
|
|
100
|
+
- shell help and route listing
|
|
101
|
+
- MCP `tools/list` and `tools/call`
|
|
102
|
+
- future admin/docs consumers
|
|
103
|
+
|
|
104
|
+
### Canonical metadata fields
|
|
105
|
+
|
|
106
|
+
Representative fields include:
|
|
107
|
+
|
|
108
|
+
- `id` — stable operation identifier
|
|
109
|
+
- `summary`
|
|
110
|
+
- `description`
|
|
111
|
+
- `tags`
|
|
112
|
+
- `inputSchema`
|
|
113
|
+
- `outputSchema`
|
|
114
|
+
- `safety`
|
|
115
|
+
- `access`
|
|
116
|
+
- `http`
|
|
117
|
+
- `cli`
|
|
118
|
+
- `mcp`
|
|
119
|
+
|
|
120
|
+
### Example
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
http.add('GET', '/api/info', () => ({ result: okdb.info }), {
|
|
124
|
+
id: 'system_info',
|
|
125
|
+
summary: 'Database info',
|
|
126
|
+
tags: ['system'],
|
|
127
|
+
inputSchema: {
|
|
128
|
+
type: 'object',
|
|
129
|
+
properties: {},
|
|
130
|
+
additionalProperties: false,
|
|
131
|
+
},
|
|
132
|
+
outputSchema: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
additionalProperties: true,
|
|
135
|
+
},
|
|
136
|
+
safety: {
|
|
137
|
+
access: 'read',
|
|
138
|
+
destructive: false,
|
|
139
|
+
idempotent: true,
|
|
140
|
+
longRunning: false,
|
|
141
|
+
streaming: false,
|
|
142
|
+
},
|
|
143
|
+
access: {
|
|
144
|
+
audiences: ['http', 'shell', 'mcp'],
|
|
145
|
+
authRequired: true,
|
|
146
|
+
internalOnly: false,
|
|
147
|
+
},
|
|
148
|
+
http: {
|
|
149
|
+
bodyMode: 'none',
|
|
150
|
+
},
|
|
151
|
+
mcp: {
|
|
152
|
+
include: true,
|
|
153
|
+
tool: 'system_info',
|
|
154
|
+
readOnlyHint: true,
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Path/query/body projection rules
|
|
160
|
+
|
|
161
|
+
OKDB uses a canonical logical input model and projects it into HTTP as follows:
|
|
162
|
+
|
|
163
|
+
1. **Path params are inferred** from the route path (including optional env defaults)
|
|
164
|
+
2. **Query params are declared explicitly** via `http.querySchema`
|
|
165
|
+
3. **Remaining logical input fields** go to the body by default
|
|
166
|
+
4. **Explicit `http.bindings`** are only needed for ambiguous or nonstandard cases
|
|
167
|
+
|
|
168
|
+
### `http.bodyMode`
|
|
169
|
+
|
|
170
|
+
Supported body projection modes include:
|
|
171
|
+
|
|
172
|
+
- `none`
|
|
173
|
+
- `remaining-fields`
|
|
174
|
+
- `object`
|
|
175
|
+
- `payload-or-self`
|
|
176
|
+
- `array`
|
|
177
|
+
- `raw`
|
|
178
|
+
|
|
179
|
+
### Validation rules
|
|
180
|
+
|
|
181
|
+
Canonical operation metadata is validated for:
|
|
182
|
+
|
|
183
|
+
- missing bindings
|
|
184
|
+
- ambiguous bindings
|
|
185
|
+
- illegal bindings
|
|
186
|
+
- raw/MCP transport incompatibilities
|
|
187
|
+
|
|
188
|
+
During migration, strict validation applies to canonical routes while legacy routes still pass through until converted.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## `/api/docs`
|
|
193
|
+
|
|
194
|
+
`GET /api/docs` still returns the route registry shape used by existing consumers, but entries now also include normalized operation metadata where available.
|
|
195
|
+
|
|
196
|
+
Each entry contains at least:
|
|
197
|
+
|
|
198
|
+
- `method`
|
|
199
|
+
- `path`
|
|
200
|
+
- `defaults`
|
|
201
|
+
- `meta`
|
|
202
|
+
- `operation`
|
|
203
|
+
|
|
204
|
+
The legacy `meta` shape remains present during migration for compatibility.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## MCP generation
|
|
209
|
+
|
|
210
|
+
OKDB's MCP surface now derives tools primarily from route operation metadata.
|
|
211
|
+
|
|
212
|
+
Routes may opt into MCP with metadata like:
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
mcp: {
|
|
216
|
+
capability: 'queue',
|
|
217
|
+
action: 'queue_list_jobs',
|
|
218
|
+
readOnlyHint: true,
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Most routes are exposed through grouped capability tools such as `okdb_queue`, `okdb_function_run`, and `okdb_index`.
|
|
223
|
+
Those tools do **not** use dotted method names like `okdb_function_run.preview`.
|
|
224
|
+
Instead, the tool name stays fixed and the requested operation is supplied as an `action` argument.
|
|
225
|
+
|
|
226
|
+
Examples:
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"name": "okdb_function_run",
|
|
231
|
+
"arguments": { "action": "preview", "env": "default", "source": "(ctx) => ({ ok: true })" }
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"name": "okdb_index",
|
|
238
|
+
"arguments": {
|
|
239
|
+
"action": "create",
|
|
240
|
+
"env": "default",
|
|
241
|
+
"type": "places",
|
|
242
|
+
"fields": ["location"],
|
|
243
|
+
"indexType": "geo",
|
|
244
|
+
"precision": 7
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Convenience MCP aliases:
|
|
250
|
+
|
|
251
|
+
- `fields: [...]` is joined into the canonical `index` id using `~`
|
|
252
|
+
- `indexType: "geo"` maps to the underlying index type hint
|
|
253
|
+
- env-scoped MCP calls must always send an explicit `env`
|
|
254
|
+
|
|
255
|
+
The MCP layer excludes non-tool transports by default, including:
|
|
256
|
+
|
|
257
|
+
- SSE/event stream routes
|
|
258
|
+
- raw upload routes
|
|
259
|
+
- streaming download/export routes
|
|
260
|
+
- hidden/internal transport routes
|
|
261
|
+
|
|
262
|
+
Generated MCP calls route through `okdb.http.handle(...)` rather than duplicating feature logic.
|
|
263
|
+
|
|
264
|
+
For the grouped `okdb_pipeline` tool:
|
|
265
|
+
|
|
266
|
+
- embeddings env/type pipeline actions keep concise names such as `list`, `stats`, `query`, `start`, and `delete`
|
|
267
|
+
- generic pipeline registry actions use the `generic_*` prefix (`generic_list`, `generic_get`, `generic_create`, `generic_start`, `generic_stop`, `generic_delete`, `generic_scaffold`) so they do not collide with embeddings actions
|
|
268
|
+
- as an MCP convenience, `action: "list"` falls back to env-scoped `generic_list` when `type` is omitted; include `type` to get the specialized embeddings env/type listing
|
|
269
|
+
- template discovery/execution is also available as `template_list`, `template_get`, `template_preview`, and `template_create`
|
|
270
|
+
- those template actions are pipeline-only and correspond to `/api/pipelines/templates...`, not the broader shared engine registry
|
|
271
|
+
|
|
272
|
+
For the grouped `okdb_engine` tool:
|
|
273
|
+
|
|
274
|
+
- `action: "types"` lists registered engine kinds and any self-declared config schemas/examples
|
|
275
|
+
- `action: "templates" | "template_get" | "template_preview"` exposes the shared starter registry, including both direct-engine templates and pipeline templates
|
|
276
|
+
- `action: "template_create"` creates a direct env-scoped engine from a starter template
|
|
277
|
+
- `action: "list" | "get" | "create" | "patch" | "delete" | "restart" | "pause" | "resume" | "retry" | "reset_cursor" | "rebuild"` targets direct env-scoped engine admin routes
|
|
278
|
+
|
|
279
|
+
For the grouped `okdb_embeddings` tool:
|
|
280
|
+
|
|
281
|
+
- create actions remain available (`embedder_create`, `indexer_create`, `search_create`, `worker_create`)
|
|
282
|
+
- discovery actions are also available (`providers`, `models`, `models_by_provider`, `algorithms`, `probe_ollama_models`, `embedder_models`) so MCP clients can inspect provider schemas and model catalogs before creating engines or pipelines
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Engine management endpoints
|
|
287
|
+
|
|
288
|
+
The direct `engines` feature exposes env-scoped inspection and admin routes:
|
|
289
|
+
|
|
290
|
+
```text
|
|
291
|
+
GET /api/engines/types
|
|
292
|
+
GET /api/engines/templates
|
|
293
|
+
GET /api/engines/templates/:template
|
|
294
|
+
POST /api/engines/templates/:template/preview
|
|
295
|
+
POST /api/env/:env/engines/templates/:template/create
|
|
296
|
+
GET /api/env/:env/engines?type=<engine-type>
|
|
297
|
+
POST /api/env/:env/engines
|
|
298
|
+
GET /api/env/:env/engines/:type/:name
|
|
299
|
+
PATCH /api/env/:env/engines/:type/:name
|
|
300
|
+
DELETE /api/env/:env/engines/:type/:name
|
|
301
|
+
POST /api/env/:env/engines/:type/:name/restart
|
|
302
|
+
POST /api/env/:env/engines/:type/:name/pause
|
|
303
|
+
POST /api/env/:env/engines/:type/:name/resume
|
|
304
|
+
POST /api/env/:env/engines/:type/:name/retry
|
|
305
|
+
POST /api/env/:env/engines/:type/:name/reset-cursor
|
|
306
|
+
POST /api/env/:env/engines/:type/:name/rebuild
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
`GET /api/engines/types` returns the registered engine kinds plus any backend-supplied config schema, example config, patchability, creation notes, and matching starter `templateIds` / `recommendedTemplateIds`.
|
|
310
|
+
`GET /api/engines/templates` returns the full starter registry shared by direct engines and pipeline builders.
|
|
311
|
+
That means it includes both `kind: "engine"` and `kind: "pipeline"` entries, whereas `GET /api/pipelines/templates` exposes only the pipeline subset.
|
|
312
|
+
`POST /api/engines/templates/:template/preview` expands a starter template into the concrete create payload it would execute, without persisting anything.
|
|
313
|
+
`POST /api/env/:env/engines/templates/:template/create` only accepts templates whose plan kind is `engine`; pipeline templates must go through `/api/env/:env/pipelines/templates/:template/create`.
|
|
314
|
+
`GET /api/env/:env/engines` returns runtime summaries for engines stored in that environment. The optional `type` query parameter narrows results to one engine type.
|
|
315
|
+
|
|
316
|
+
MCP exposes these routes through `okdb_engine`, so clients can discover engine types and create/manage direct engines without going through a pipeline.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Contributor guidance for new routes
|
|
321
|
+
|
|
322
|
+
When adding a new route in any `*-http.js` file:
|
|
323
|
+
|
|
324
|
+
1. provide a stable `id`
|
|
325
|
+
2. add `summary`, `description`, and `tags`
|
|
326
|
+
3. define `inputSchema`
|
|
327
|
+
4. define `outputSchema` where practical
|
|
328
|
+
5. classify `safety` and `access`
|
|
329
|
+
6. set `http.bodyMode` and `http.querySchema` as needed
|
|
330
|
+
7. decide whether the route should participate in MCP via `mcp.include`
|
|
331
|
+
8. avoid exposing raw/SSE/stream routes to MCP unless you add a deliberate adapter
|
|
332
|
+
|
|
333
|
+
Feature authors should keep the route's owning feature responsible for its metadata. Do not create a second disconnected metadata source for MCP or CLI.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## CRUD endpoints
|
|
338
|
+
|
|
339
|
+
All routes are under `/api`. The `:env` prefix is `default` unless you specify another environment.
|
|
340
|
+
|
|
341
|
+
### Records
|
|
342
|
+
|
|
343
|
+
```http
|
|
344
|
+
GET /api/:env/type/:type/item/:key → single record
|
|
345
|
+
PUT /api/:env/type/:type/item/:key → upsert (body.value = value)
|
|
346
|
+
PATCH /api/:env/type/:type/item/:key → partial update (body.patch = patch doc)
|
|
347
|
+
DELETE /api/:env/type/:type/item/:key → remove
|
|
348
|
+
POST /api/:env/type/:type/query → query records
|
|
349
|
+
POST /api/:env/transaction → atomic batch writes
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# Get a record
|
|
354
|
+
curl http://localhost:8080/api/default/type/users/item/alice \
|
|
355
|
+
-H "Authorization: Bearer token"
|
|
356
|
+
|
|
357
|
+
# Upsert by key
|
|
358
|
+
curl -X PUT http://localhost:8080/api/default/type/users/item/alice \
|
|
359
|
+
-H "Authorization: Bearer token" \
|
|
360
|
+
-H "Content-Type: application/json" \
|
|
361
|
+
-d '{"value": {"name": "Alice", "role": "superadmin"}}'
|
|
362
|
+
|
|
363
|
+
# Patch an existing record
|
|
364
|
+
curl -X PATCH http://localhost:8080/api/default/type/users/item/alice \
|
|
365
|
+
-H "Authorization: Bearer token" \
|
|
366
|
+
-H "Content-Type: application/json" \
|
|
367
|
+
-d '{"patch":{"set":{"role":"admin"},"inc":{"loginCount":1},"append":{"tags":["vip"]},"pull":{"tags":["trial"]}},"ifVersion":7}'
|
|
368
|
+
|
|
369
|
+
# Delete
|
|
370
|
+
curl -X DELETE http://localhost:8080/api/default/type/users/item/alice \
|
|
371
|
+
-H "Authorization: Bearer token"
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Patch document format
|
|
375
|
+
|
|
376
|
+
`PATCH` uses a structured patch document.
|
|
377
|
+
|
|
378
|
+
- `set` — assign or replace fields/paths
|
|
379
|
+
- `unset` — remove fields/paths
|
|
380
|
+
- `inc` — increment numeric fields
|
|
381
|
+
- `merge` — deep-merge object subtrees
|
|
382
|
+
- `append` — append one or more values to arrays
|
|
383
|
+
- `pull` — remove matching values from arrays
|
|
384
|
+
|
|
385
|
+
```json
|
|
386
|
+
{
|
|
387
|
+
"patch": {
|
|
388
|
+
"set": { "status": "active" },
|
|
389
|
+
"inc": { "metrics.views": 1 },
|
|
390
|
+
"merge": { "profile": { "theme": "dark" } },
|
|
391
|
+
"append": { "tags": ["featured"] },
|
|
392
|
+
"pull": { "tags": ["draft"] }
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Notes:
|
|
398
|
+
|
|
399
|
+
- patch applies to existing object records only
|
|
400
|
+
- arrays are incrementally mutated via `append` and `pull`
|
|
401
|
+
- `ifVersion` enables compare-and-swap writes
|
|
402
|
+
- successful patch calls return `204 No Content`
|
|
403
|
+
|
|
404
|
+
### List records
|
|
405
|
+
|
|
406
|
+
```http
|
|
407
|
+
GET /api/:env/type/:type
|
|
408
|
+
?limit=50
|
|
409
|
+
&offset=0
|
|
410
|
+
&start=<key>
|
|
411
|
+
&end=<key>
|
|
412
|
+
&reverse=false
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
curl "http://localhost:8080/api/default/type/users?limit=10&reverse=true" \
|
|
417
|
+
-H "Authorization: Bearer token"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Change log endpoints
|
|
423
|
+
|
|
424
|
+
```http
|
|
425
|
+
GET /api/:env/changelog
|
|
426
|
+
?before=<clock> → changes up to this clock (inclusive)
|
|
427
|
+
?after=<clock> → changes from this clock onwards
|
|
428
|
+
?type=<typename> → filter by type
|
|
429
|
+
|
|
430
|
+
GET /api/:env/type/:type/changelog
|
|
431
|
+
?before=<clock>
|
|
432
|
+
?after=<clock>
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# Get changes since clock 100
|
|
437
|
+
curl "http://localhost:8080/api/default/changelog?after=100" \
|
|
438
|
+
-H "Authorization: Bearer token"
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## Schema endpoints
|
|
444
|
+
|
|
445
|
+
```http
|
|
446
|
+
GET /api/:env/types → list all registered types
|
|
447
|
+
POST /api/:env/types → register a type
|
|
448
|
+
DELETE /api/:env/type/:type → drop a type
|
|
449
|
+
|
|
450
|
+
POST /api/:env/type/:type/indexes → register an index
|
|
451
|
+
DELETE /api/:env/type/:type/index/:idx → drop an index
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## System info
|
|
457
|
+
|
|
458
|
+
```http
|
|
459
|
+
GET /api/info
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Returns node ID, version, clock, type stats, plugin list, and resolved LMDB options.
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Sync endpoint
|
|
467
|
+
|
|
468
|
+
```http
|
|
469
|
+
GET /api/sync/delta?from_clock=<N>
|
|
470
|
+
Authorization: Bearer <sync-token>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Used by peer nodes during reconciliation. Returns a JSON stream of change objects.
|
|
474
|
+
|
|
475
|
+
```http
|
|
476
|
+
POST /api/sync/join
|
|
477
|
+
Authorization: Bearer <sync-token>
|
|
478
|
+
Content-Type: application/json
|
|
479
|
+
|
|
480
|
+
{ "address": "http://peer.example.com:8080" }
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## File endpoints
|
|
486
|
+
|
|
487
|
+
```http
|
|
488
|
+
POST /api/files → upload file (multipart or raw)
|
|
489
|
+
GET /api/files/:id → download file (streams blob bytes)
|
|
490
|
+
GET /api/files/:id/meta → metadata only (no body stream)
|
|
491
|
+
DELETE /api/files/:id → remove file
|
|
492
|
+
GET /api/files → list file metadata
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## Custom middleware
|
|
498
|
+
|
|
499
|
+
Add your own middleware before route handlers:
|
|
500
|
+
|
|
501
|
+
```javascript
|
|
502
|
+
okdb.http.use(async (req, res, next) => {
|
|
503
|
+
console.log(`${req.method} ${req.url}`);
|
|
504
|
+
await next();
|
|
505
|
+
});
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Register custom routes:
|
|
509
|
+
|
|
510
|
+
```javascript
|
|
511
|
+
okdb.http.add('GET', '/api/custom/health', () => ({
|
|
512
|
+
result: { ok: true, clock: okdb.getClock() },
|
|
513
|
+
}));
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Integrating with an existing framework
|
|
519
|
+
|
|
520
|
+
OKDB's HTTP layer is **framework-agnostic**. `okdb.http.listen()` is entirely optional — if you already have an Express, Fastify, or raw Node.js server, you can hand requests to OKDB directly via `okdb.http.handle()`.
|
|
521
|
+
|
|
522
|
+
`handle(method, path, { body, query, headers }, context)` returns a promise that resolves to `{ status, headers, body }`. Wire that into your framework's response however you like.
|
|
523
|
+
|
|
524
|
+
### Express
|
|
525
|
+
|
|
526
|
+
```javascript
|
|
527
|
+
const express = require('express');
|
|
528
|
+
const OKDB = require('src/okdb');
|
|
529
|
+
|
|
530
|
+
const app = express();
|
|
531
|
+
const okdb = new OKDB('./mydb');
|
|
532
|
+
await okdb.open();
|
|
533
|
+
|
|
534
|
+
// Mount all /api/* and /admin/* routes on the existing Express server
|
|
535
|
+
app.use(express.json());
|
|
536
|
+
app.use(async (req, res, next) => {
|
|
537
|
+
const path = req.path;
|
|
538
|
+
if (!path.startsWith('/api') && !path.startsWith('/admin') && !path.startsWith('/docs')) {
|
|
539
|
+
return next();
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const response = await okdb.http.handle(
|
|
543
|
+
req.method,
|
|
544
|
+
path,
|
|
545
|
+
{
|
|
546
|
+
body: req.body,
|
|
547
|
+
query: req.query,
|
|
548
|
+
headers: req.headers,
|
|
549
|
+
},
|
|
550
|
+
{ req, res },
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
const { status = 200, headers = {}, body } = response;
|
|
554
|
+
res.status(status);
|
|
555
|
+
for (const [k, v] of Object.entries(headers)) res.set(k, v);
|
|
556
|
+
|
|
557
|
+
if (body == null) return res.end();
|
|
558
|
+
if (typeof body?.pipe === 'function') return body.pipe(res);
|
|
559
|
+
if (Buffer.isBuffer(body)) return res.end(body);
|
|
560
|
+
if (typeof body === 'object') return res.json(body);
|
|
561
|
+
res.send(String(body));
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
app.listen(3000);
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Fastify
|
|
568
|
+
|
|
569
|
+
```javascript
|
|
570
|
+
const fastify = require('fastify')({ logger: false });
|
|
571
|
+
const OKDB = require('src/okdb');
|
|
572
|
+
|
|
573
|
+
const okdb = new OKDB('./mydb');
|
|
574
|
+
await okdb.open();
|
|
575
|
+
|
|
576
|
+
fastify.addContentTypeParser('application/json', { parseAs: 'string' }, (req, body, done) => {
|
|
577
|
+
try {
|
|
578
|
+
done(null, JSON.parse(body));
|
|
579
|
+
} catch (e) {
|
|
580
|
+
done(e);
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
fastify.all('/api/*', async (request, reply) => {
|
|
585
|
+
const response = await okdb.http.handle(
|
|
586
|
+
request.method,
|
|
587
|
+
request.url.split('?')[0],
|
|
588
|
+
{
|
|
589
|
+
body: request.body,
|
|
590
|
+
query: request.query,
|
|
591
|
+
headers: request.headers,
|
|
592
|
+
},
|
|
593
|
+
{ req: request.raw, res: reply.raw },
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
const { status = 200, headers = {}, body } = response;
|
|
597
|
+
reply.status(status);
|
|
598
|
+
for (const [k, v] of Object.entries(headers)) reply.header(k, v);
|
|
599
|
+
|
|
600
|
+
if (body == null) return reply.send();
|
|
601
|
+
if (typeof body?.pipe === 'function') return reply.send(body);
|
|
602
|
+
return reply.send(body);
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
await fastify.listen({ port: 3000 });
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Raw Node.js `http`
|
|
609
|
+
|
|
610
|
+
```javascript
|
|
611
|
+
const http = require('http');
|
|
612
|
+
const OKDB = require('src/okdb');
|
|
613
|
+
|
|
614
|
+
const okdb = new OKDB('./mydb');
|
|
615
|
+
await okdb.open();
|
|
616
|
+
|
|
617
|
+
const server = http.createServer(async (req, res) => {
|
|
618
|
+
// Your own routes first
|
|
619
|
+
if (req.url === '/health') {
|
|
620
|
+
res.end('ok');
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Delegate everything else to OKDB
|
|
625
|
+
let body = null;
|
|
626
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
627
|
+
body = await new Promise((resolve, reject) => {
|
|
628
|
+
let data = '';
|
|
629
|
+
req.on('data', (c) => (data += c));
|
|
630
|
+
req.on('end', () => {
|
|
631
|
+
try {
|
|
632
|
+
resolve(data ? JSON.parse(data) : null);
|
|
633
|
+
} catch (e) {
|
|
634
|
+
reject(e);
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
req.on('error', reject);
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const url = new URL(req.url, 'http://localhost');
|
|
642
|
+
const response = await okdb.http.handle(
|
|
643
|
+
req.method,
|
|
644
|
+
url.pathname,
|
|
645
|
+
{
|
|
646
|
+
body,
|
|
647
|
+
query: Object.fromEntries(url.searchParams),
|
|
648
|
+
headers: req.headers,
|
|
649
|
+
},
|
|
650
|
+
{ req, res },
|
|
651
|
+
);
|
|
652
|
+
|
|
653
|
+
const { status = 200, headers = {}, body: resBody } = response;
|
|
654
|
+
res.statusCode = status;
|
|
655
|
+
for (const [k, v] of Object.entries(headers)) res.setHeader(k, v);
|
|
656
|
+
|
|
657
|
+
if (resBody == null) {
|
|
658
|
+
res.end();
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
if (typeof resBody?.pipe === 'function') {
|
|
662
|
+
resBody.pipe(res);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (Buffer.isBuffer(resBody)) {
|
|
666
|
+
res.end(resBody);
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
if (typeof resBody === 'object') {
|
|
670
|
+
res.setHeader('content-type', 'application/json');
|
|
671
|
+
res.end(JSON.stringify(resBody));
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
res.end(String(resBody));
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
server.listen(3000);
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
:::tip
|
|
681
|
+
When you bring your own server, don't call `okdb.http.listen()`. OKDB's routes and middleware are still fully functional — you're just providing the transport layer yourself.
|
|
682
|
+
:::
|
|
683
|
+
|
|
684
|
+
:::note
|
|
685
|
+
`okdb.http.handle()` still runs all registered middleware and guards. If you configure admin auth (`options.admin.auth`), the `/admin/*` guard still applies — the same cookie/Basic-Auth logic works regardless of which HTTP framework is in front.
|
|
686
|
+
:::
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
## Admin UI
|
|
691
|
+
|
|
692
|
+
When `admin.auth` is configured, the admin UI is available at:
|
|
693
|
+
|
|
694
|
+
```
|
|
695
|
+
http://localhost:8080/admin/index.html
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
It provides:
|
|
699
|
+
|
|
700
|
+
- Type and record browser
|
|
701
|
+
- Index management (create, drop, view status)
|
|
702
|
+
- Live changelog viewer
|
|
703
|
+
- Embeddings pipeline status
|
|
704
|
+
- Sync peer status
|
|
705
|
+
- System info
|