@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
@@ -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
+ ```
@@ -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
+ ```