@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.
Files changed (260) hide show
  1. package/LICENSE +57 -0
  2. package/README.md +344 -0
  3. package/banner.jpg +0 -0
  4. package/bin/okdb.js +2 -0
  5. package/docs/OKDB-ARCHITECTURE.md +1036 -0
  6. package/docs/auth-and-sync.md +558 -0
  7. package/docs/auth-permissions.md +143 -0
  8. package/docs/change-log.md +169 -0
  9. package/docs/data-model.md +174 -0
  10. package/docs/embeddings.md +338 -0
  11. package/docs/files.md +131 -0
  12. package/docs/fts.md +139 -0
  13. package/docs/functions.md +514 -0
  14. package/docs/getting-started.md +233 -0
  15. package/docs/http-api.md +705 -0
  16. package/docs/index.md +115 -0
  17. package/docs/indexes.md +207 -0
  18. package/docs/logging.md +116 -0
  19. package/docs/manifest.json +38 -0
  20. package/docs/migration.md +154 -0
  21. package/docs/pipelines.md +598 -0
  22. package/docs/plugins.md +144 -0
  23. package/docs/querying.md +204 -0
  24. package/docs/queue.md +637 -0
  25. package/docs/sync.md +156 -0
  26. package/docs/transactions.md +140 -0
  27. package/docs/ttl.md +375 -0
  28. package/okdb.js +1 -0
  29. package/package.json +26 -0
  30. package/public/admin-app.js +1 -0
  31. package/public/android-chrome-192x192.png +0 -0
  32. package/public/android-chrome-512x512.png +0 -0
  33. package/public/apple-touch-icon.png +0 -0
  34. package/public/components/admin-route-host.ok.js +1 -0
  35. package/public/components/env-picker.ok.js +1 -0
  36. package/public/components/field-path-input.ok.js +1 -0
  37. package/public/components/field.html +6 -0
  38. package/public/components/geo-map.ok.js +1 -0
  39. package/public/components/ok-cron-input.ok.js +1 -0
  40. package/public/components/ok-dropzone.ok.js +1 -0
  41. package/public/components/ok-js-input.ok.js +1 -0
  42. package/public/components/ok-json-input.ok.js +1 -0
  43. package/public/components/ok-text-monaco-input.ok.js +1 -0
  44. package/public/components/theme-toggle.ok.js +1 -0
  45. package/public/favicon-16x16.png +0 -0
  46. package/public/favicon-32x32.png +0 -0
  47. package/public/favicon.ico +0 -0
  48. package/public/images/logo.png +0 -0
  49. package/public/images/logo.svg +333 -0
  50. package/public/index.html +6 -0
  51. package/public/layouts/_default.ok.html +1 -0
  52. package/public/layouts/okdb-cube.ok.html +1 -0
  53. package/public/login-app.js +1 -0
  54. package/public/login.html +1 -0
  55. package/public/modules/ok.js +1 -0
  56. package/public/sections/api/index.ok.html +1 -0
  57. package/public/sections/api/parts/api-endpoint.ok.js +1 -0
  58. package/public/sections/auth/index.ok.html +1 -0
  59. package/public/sections/auth/modals/create-token-modal.ok.js +1 -0
  60. package/public/sections/auth/modals/edit-token-modal.ok.js +1 -0
  61. package/public/sections/auth/modals/perm-info-popover.ok.js +1 -0
  62. package/public/sections/auth/parts/token-detail.ok.js +1 -0
  63. package/public/sections/auth/parts/token-list.ok.js +1 -0
  64. package/public/sections/db/index.ok.html +1 -0
  65. package/public/sections/db/modals/add-item-modal.ok.js +1 -0
  66. package/public/sections/db/modals/create-env-modal.ok.js +1 -0
  67. package/public/sections/db/modals/create-fts-modal.ok.js +1 -0
  68. package/public/sections/db/modals/create-index-modal.ok.js +1 -0
  69. package/public/sections/db/modals/create-pipeline-modal.ok.js +1 -0
  70. package/public/sections/db/modals/demo-env-modal.ok.js +1 -0
  71. package/public/sections/db/modals/remove-env-modal.ok.js +1 -0
  72. package/public/sections/db/modals/schema-edit-modal.ok.js +1 -0
  73. package/public/sections/db/parts/db-overview.ok.js +1 -0
  74. package/public/sections/db/parts/db-pipelines-panel.ok.js +1 -0
  75. package/public/sections/db/parts/edit-row.ok.js +1 -0
  76. package/public/sections/db/parts/tm-timeline.ok.js +1 -0
  77. package/public/sections/db/parts/type-changelog.ok.js +1 -0
  78. package/public/sections/db/parts/type-list.ok.js +1 -0
  79. package/public/sections/db/parts/type-pipelines-tab.ok.js +1 -0
  80. package/public/sections/db/parts/type-schema-tab.ok.js +1 -0
  81. package/public/sections/db/parts/type-viewer.ok.js +1 -0
  82. package/public/sections/db/parts/type-violations-tab.ok.js +1 -0
  83. package/public/sections/docs/index.ok.html +1 -0
  84. package/public/sections/embeddings/index.ok.html +1 -0
  85. package/public/sections/embeddings/modals/register-model-modal.ok.js +1 -0
  86. package/public/sections/embeddings/parts/embed-create-panel.ok.js +1 -0
  87. package/public/sections/embeddings/parts/embed-embedder-panel.ok.js +1 -0
  88. package/public/sections/embeddings/parts/embed-engine-declaration-editor.ok.js +1 -0
  89. package/public/sections/embeddings/parts/embed-engine-list.ok.js +1 -0
  90. package/public/sections/embeddings/parts/embed-indexer-panel.ok.js +1 -0
  91. package/public/sections/embeddings/parts/embed-lifecycle-bar.ok.js +1 -0
  92. package/public/sections/embeddings/parts/embed-model-catalog.ok.js +1 -0
  93. package/public/sections/embeddings/parts/embed-overview.ok.js +1 -0
  94. package/public/sections/embeddings/parts/embed-search-panel.ok.js +1 -0
  95. package/public/sections/embeddings/parts/embed-worker-panel.ok.js +1 -0
  96. package/public/sections/embeddings/parts/embeddings-engine-panel.ok.js +1 -0
  97. package/public/sections/embeddings/parts/engines-overview.ok.js +1 -0
  98. package/public/sections/embeddings/parts/pipeline-create-panel.ok.js +1 -0
  99. package/public/sections/engines/engine-panel-shared-style.js +1 -0
  100. package/public/sections/engines/engine-ui-utils.js +1 -0
  101. package/public/sections/engines/index.ok.html +1 -0
  102. package/public/sections/engines/modals/engine-modal.ok.js +1 -0
  103. package/public/sections/engines/parts/engine-declaration-editor.ok.js +1 -0
  104. package/public/sections/engines/parts/engine-lifecycle-actions.ok.js +1 -0
  105. package/public/sections/engines/parts/engine-panel-shell.ok.js +1 -0
  106. package/public/sections/engines/parts/engine-resource-card.ok.js +1 -0
  107. package/public/sections/engines/parts/engine-row-item.ok.js +1 -0
  108. package/public/sections/engines/parts/generic-engine-panel.ok.js +1 -0
  109. package/public/sections/files/index.ok.html +1 -0
  110. package/public/sections/files/parts/files-blob-status.ok.js +1 -0
  111. package/public/sections/files/parts/files-collection-list.ok.js +1 -0
  112. package/public/sections/files/parts/files-collection-panel.ok.js +1 -0
  113. package/public/sections/files/parts/files-file-list.ok.js +1 -0
  114. package/public/sections/files/parts/files-overview.ok.js +1 -0
  115. package/public/sections/files/parts/files-path-browser.ok.js +1 -0
  116. package/public/sections/files/parts/files-upload-panel.ok.js +1 -0
  117. package/public/sections/functions/index.ok.html +1 -0
  118. package/public/sections/functions/modals/function-modal.ok.js +1 -0
  119. package/public/sections/functions/parts/function-detail.ok.js +1 -0
  120. package/public/sections/functions/parts/function-logs.ok.js +1 -0
  121. package/public/sections/functions/parts/function-runner.ok.js +1 -0
  122. package/public/sections/functions/parts/functions-list.ok.js +1 -0
  123. package/public/sections/license/index.ok.html +1 -0
  124. package/public/sections/license/parts/license-panel.ok.js +1 -0
  125. package/public/sections/processors/index.ok.html +1 -0
  126. package/public/sections/queue/index.ok.html +1 -0
  127. package/public/sections/queue/modals/create-bucket-modal.ok.js +1 -0
  128. package/public/sections/queue/modals/edit-bucket-modal.ok.js +1 -0
  129. package/public/sections/queue/modals/edit-job-modal.ok.js +1 -0
  130. package/public/sections/queue/modals/enqueue-job-modal.ok.js +1 -0
  131. package/public/sections/queue/modals/job-type-modal.ok.js +1 -0
  132. package/public/sections/queue/parts/ok-job-form.ok.js +1 -0
  133. package/public/sections/queue/parts/queue-buckets.ok.js +1 -0
  134. package/public/sections/queue/parts/queue-job-types.ok.js +1 -0
  135. package/public/sections/queue/parts/queue-jobs.ok.js +1 -0
  136. package/public/sections/queue/parts/queue-types.ok.js +1 -0
  137. package/public/sections/queue/parts/queue-workers.ok.js +1 -0
  138. package/public/sections/sync/index.ok.html +5 -0
  139. package/public/sections/sync/parts/sync-node-detail.ok.js +1 -0
  140. package/public/sections/sync/parts/sync-retention.ok.js +1 -0
  141. package/public/sections/sync/parts/sync-topology.ok.js +1 -0
  142. package/public/sections/system/index.ok.html +1 -0
  143. package/public/sections/system/modals/data-ops-modal.ok.js +1 -0
  144. package/public/sections/system/parts/system-api-panel.ok.js +1 -0
  145. package/public/sections/system/parts/system-auth-panel.ok.js +1 -0
  146. package/public/sections/system/parts/system-log-history.ok.js +1 -0
  147. package/public/sections/system/parts/system-log.ok.js +1 -0
  148. package/public/sections/system/parts/system-status.ok.js +1 -0
  149. package/public/sections/system/parts/system-sync-panel.ok.js +1 -0
  150. package/public/sections/views/index.ok.html +1 -0
  151. package/public/sections/views/modals/create-view-modal.ok.js +1 -0
  152. package/public/sections/views/parts/view-detail.ok.js +1 -0
  153. package/public/sections/views/parts/views-list.ok.js +1 -0
  154. package/public/sections/views/parts/views-overview.ok.js +1 -0
  155. package/public/setup-app.js +1 -0
  156. package/public/setup.html +1 -0
  157. package/public/site.webmanifest +1 -0
  158. package/public/stores/auth-store.js +1 -0
  159. package/public/stores/events-store.js +1 -0
  160. package/public/stores/functions-store.js +1 -0
  161. package/public/stores/okdb-store.js +1 -0
  162. package/public/stores/theme-store.js +1 -0
  163. package/public/styles.css +1 -0
  164. package/public/test-cron-input.html +10 -0
  165. package/public/test-json-input.html +101 -0
  166. package/public/util/permissions.js +1 -0
  167. package/public/util/sift-schema.js +1 -0
  168. package/public/vendor/okjs/ok.esm.min.js +2 -0
  169. package/public/vendor/okjs/toolkit/behavior/async.ok.js +1 -0
  170. package/public/vendor/okjs/toolkit/components/ok-chart.ok.js +1 -0
  171. package/public/vendor/okjs/toolkit/components/ok-doc-viewer.ok.js +1 -0
  172. package/public/vendor/okjs/toolkit/components/ok-marked.ok.js +1 -0
  173. package/public/vendor/okjs/toolkit/components/ok-monaco.ok.js +1 -0
  174. package/public/vendor/okjs/toolkit/core/ok-layer-service.ok.js +1 -0
  175. package/public/vendor/okjs/toolkit/core/ok-layer.ok.js +1 -0
  176. package/public/vendor/okjs/toolkit/core/ok-overlay.ok.js +1 -0
  177. package/public/vendor/okjs/toolkit/core/ok-sandbox.ok.js +1 -0
  178. package/public/vendor/okjs/toolkit/core/transition.ok.js +1 -0
  179. package/public/vendor/okjs/toolkit/core/virtualized.ok.js +1 -0
  180. package/public/vendor/okjs/toolkit/devtools/ok-console-service.ok.js +1 -0
  181. package/public/vendor/okjs/toolkit/devtools/ok-console.ok.js +1 -0
  182. package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor-service.ok.js +1 -0
  183. package/public/vendor/okjs/toolkit/devtools/ok-fps-monitor.ok.js +1 -0
  184. package/public/vendor/okjs/toolkit/devtools/ok-inspector-service.ok.js +1 -0
  185. package/public/vendor/okjs/toolkit/devtools/ok-inspector.ok.js +1 -0
  186. package/public/vendor/okjs/toolkit/devtools/ok-js-tree.ok.js +1 -0
  187. package/public/vendor/okjs/toolkit/devtools/ok-timeline-service.ok.js +1 -0
  188. package/public/vendor/okjs/toolkit/devtools/ok-timeline.ok.js +1 -0
  189. package/public/vendor/okjs/toolkit/docs/doc-viewer.ok.js +1 -0
  190. package/public/vendor/okjs/toolkit/editor/ok-live-component.ok.js +1 -0
  191. package/public/vendor/okjs/toolkit/editor/ok-live-example.ok.js +1 -0
  192. package/public/vendor/okjs/toolkit/editor/ok-live-shell.ok.js +1 -0
  193. package/public/vendor/okjs/toolkit/elements/ok-dropdown.ok.js +1 -0
  194. package/public/vendor/okjs/toolkit/elements/ok-icon.ok.js +1 -0
  195. package/public/vendor/okjs/toolkit/elements/ok-select.ok.js +1 -0
  196. package/public/vendor/okjs/toolkit/elements/ok-table.ok.js +1 -0
  197. package/public/vendor/okjs/toolkit/errors/ok-crash-boundary.ok.js +1 -0
  198. package/public/vendor/okjs/toolkit/errors/ok-crash-info.ok.js +1 -0
  199. package/public/vendor/okjs/toolkit/i18n/i18n-editor-examples.ok.js +1 -0
  200. package/public/vendor/okjs/toolkit/i18n/i18n-editor.ok.js +1 -0
  201. package/public/vendor/okjs/toolkit/i18n/i18n-key-editor-tips.ok.js +1 -0
  202. package/public/vendor/okjs/toolkit/i18n/i18n-key-editor.ok.js +1 -0
  203. package/public/vendor/okjs/toolkit/i18n/i18n-service.ok.js +1 -0
  204. package/public/vendor/okjs/toolkit/i18n/ok-i18n.js +1 -0
  205. package/public/vendor/okjs/toolkit/interaction/ok-contextmenu.ok.js +1 -0
  206. package/public/vendor/okjs/toolkit/interaction/ok-dismiss-service.ok.js +1 -0
  207. package/public/vendor/okjs/toolkit/interaction/ok-draggable.ok.js +1 -0
  208. package/public/vendor/okjs/toolkit/interaction/ok-flyover-panel.ok.js +1 -0
  209. package/public/vendor/okjs/toolkit/interaction/ok-flyover.ok.js +1 -0
  210. package/public/vendor/okjs/toolkit/interaction/ok-highlight-service.ok.js +1 -0
  211. package/public/vendor/okjs/toolkit/interaction/ok-highlight.ok.js +1 -0
  212. package/public/vendor/okjs/toolkit/interaction/ok-hotkeys-service.ok.js +1 -0
  213. package/public/vendor/okjs/toolkit/interaction/ok-picker-service.ok.js +1 -0
  214. package/public/vendor/okjs/toolkit/interaction/ok-popout-service.ok.js +1 -0
  215. package/public/vendor/okjs/toolkit/interaction/ok-popout.ok.js +1 -0
  216. package/public/vendor/okjs/toolkit/interaction/ok-portal-service.ok.js +1 -0
  217. package/public/vendor/okjs/toolkit/interaction/ok-submenu.ok.js +1 -0
  218. package/public/vendor/okjs/toolkit/layout/ok-resizer.ok.js +1 -0
  219. package/public/vendor/okjs/toolkit/manifest.js +1 -0
  220. package/public/vendor/okjs/toolkit/modals/ok-modal-service.ok.js +1 -0
  221. package/public/vendor/okjs/toolkit/modals/ok-modal.ok.js +1 -0
  222. package/public/vendor/okjs/toolkit/modals/ok-toast-service.ok.js +1 -0
  223. package/public/vendor/okjs/toolkit/modals/ok-window.ok.js +1 -0
  224. package/public/vendor/okjs/toolkit/navigation/hash-router.ok.js +1 -0
  225. package/public/vendor/okjs/toolkit/navigation/history-router.ok.js +1 -0
  226. package/public/vendor/okjs/toolkit/navigation/router.ok.js +1 -0
  227. package/public/vendor/okjs/toolkit/sync/reactive-sync-service.ok.js +1 -0
  228. package/public/vendor/okjs/toolkit/sync/reactive-sync.js +1 -0
  229. package/public/vendor/okjs/toolkit/theming/blocks/ok-design-button.css.js +1 -0
  230. package/public/vendor/okjs/toolkit/theming/blocks/ok-design-input.css.js +1 -0
  231. package/public/vendor/okjs/toolkit/theming/ok-design-style.js +1 -0
  232. package/public/vendor/okjs/toolkit/theming/ok-design-vars.js +1 -0
  233. package/public/vendor/okjs/toolkit/theming/ok-design.ok.js +1 -0
  234. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-input.ok.js +1 -0
  235. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-service.ok.js +1 -0
  236. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-style.js +1 -0
  237. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-utils.js +1 -0
  238. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-variable.ok.js +1 -0
  239. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor-vm.js +1 -0
  240. package/public/vendor/okjs/toolkit/theming/ok-theme-editor/ok-theme-editor.ok.js +1 -0
  241. package/public/vendor/okjs/toolkit/theming/ok-theme.ok.js +1 -0
  242. package/public/view-models/type-query-vm.js +1 -0
  243. package/types/environment.d.ts +130 -0
  244. package/types/errors.d.ts +98 -0
  245. package/types/features/admin.d.ts +4 -0
  246. package/types/features/api.d.ts +18 -0
  247. package/types/features/auth.d.ts +31 -0
  248. package/types/features/embeddings.d.ts +39 -0
  249. package/types/features/engines.d.ts +23 -0
  250. package/types/features/files.d.ts +29 -0
  251. package/types/features/fts.d.ts +25 -0
  252. package/types/features/functions.d.ts +23 -0
  253. package/types/features/mcp.d.ts +17 -0
  254. package/types/features/pipelines.d.ts +19 -0
  255. package/types/features/queue.d.ts +189 -0
  256. package/types/features/sync.d.ts +34 -0
  257. package/types/features/time-machine.d.ts +32 -0
  258. package/types/features/views.d.ts +16 -0
  259. package/types/index.d.ts +153 -0
  260. 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
+ :::