@adecore/database 0.0.1 → 0.16.0-beta.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 (400) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -1
  3. package/dist/DatabaseProvider.d.ts +13 -0
  4. package/dist/DatabaseProvider.js +17 -0
  5. package/dist/actions.d.ts +40 -0
  6. package/dist/actions.js +1 -0
  7. package/dist/client/client.d.ts +5 -0
  8. package/dist/client/client.js +245 -0
  9. package/dist/client/index.d.ts +2 -0
  10. package/dist/client/index.js +2 -0
  11. package/dist/client/types.d.ts +97 -0
  12. package/dist/client/types.js +13 -0
  13. package/dist/client-context.d.ts +16 -0
  14. package/dist/client-context.js +17 -0
  15. package/dist/connections/ConnectionForm.d.ts +10 -0
  16. package/dist/connections/ConnectionForm.js +145 -0
  17. package/dist/connections/ConnectionManager.d.ts +12 -0
  18. package/dist/connections/ConnectionManager.js +93 -0
  19. package/dist/connections/EngineIcon.d.ts +9 -0
  20. package/dist/connections/EngineIcon.js +7 -0
  21. package/dist/connections/connection-config.d.ts +16 -0
  22. package/dist/connections/connection-config.js +107 -0
  23. package/dist/connections/docker.d.ts +9 -0
  24. package/dist/connections/docker.js +38 -0
  25. package/dist/connections/engine-icons.d.ts +3 -0
  26. package/dist/connections/engine-icons.js +3 -0
  27. package/dist/connections/use-docker-containers.d.ts +17 -0
  28. package/dist/connections/use-docker-containers.js +26 -0
  29. package/dist/console/DestructiveDialog.d.ts +9 -0
  30. package/dist/console/DestructiveDialog.js +9 -0
  31. package/dist/console/HistoryPanel.d.ts +10 -0
  32. package/dist/console/HistoryPanel.js +15 -0
  33. package/dist/console/QueryConsole.d.ts +14 -0
  34. package/dist/console/QueryConsole.js +261 -0
  35. package/dist/console/SchemaPicker.d.ts +11 -0
  36. package/dist/console/SchemaPicker.js +8 -0
  37. package/dist/console/SqlEditor.d.ts +12 -0
  38. package/dist/console/SqlEditor.js +61 -0
  39. package/dist/console/StatementResultView.d.ts +18 -0
  40. package/dist/console/StatementResultView.js +32 -0
  41. package/dist/console/TransactionControls.d.ts +13 -0
  42. package/dist/console/TransactionControls.js +12 -0
  43. package/dist/console/destructive.d.ts +7 -0
  44. package/dist/console/destructive.js +43 -0
  45. package/dist/console/editing.d.ts +12 -0
  46. package/dist/console/editing.js +60 -0
  47. package/dist/console/history.d.ts +13 -0
  48. package/dist/console/history.js +43 -0
  49. package/dist/console/labels.d.ts +1 -0
  50. package/dist/console/labels.js +6 -0
  51. package/dist/console/outcome.d.ts +6 -0
  52. package/dist/console/outcome.js +11 -0
  53. package/dist/console/schemas.d.ts +2 -0
  54. package/dist/console/schemas.js +5 -0
  55. package/dist/console/shortcuts.d.ts +2 -0
  56. package/dist/console/shortcuts.js +3 -0
  57. package/dist/console/useConsoleHistory.d.ts +7 -0
  58. package/dist/console/useConsoleHistory.js +22 -0
  59. package/dist/ddl/alter-mysql.d.ts +4 -0
  60. package/dist/ddl/alter-mysql.js +79 -0
  61. package/dist/ddl/alter-sqlite.d.ts +4 -0
  62. package/dist/ddl/alter-sqlite.js +80 -0
  63. package/dist/ddl/alter.d.ts +4 -0
  64. package/dist/ddl/alter.js +24 -0
  65. package/dist/ddl/column.d.ts +9 -0
  66. package/dist/ddl/column.js +62 -0
  67. package/dist/ddl/create.d.ts +12 -0
  68. package/dist/ddl/create.js +74 -0
  69. package/dist/ddl/dialect.d.ts +12 -0
  70. package/dist/ddl/dialect.js +34 -0
  71. package/dist/ddl/diff.d.ts +34 -0
  72. package/dist/ddl/diff.js +111 -0
  73. package/dist/ddl/draft.d.ts +46 -0
  74. package/dist/ddl/draft.js +70 -0
  75. package/dist/ddl/index.d.ts +10 -0
  76. package/dist/ddl/index.js +10 -0
  77. package/dist/ddl/parse.d.ts +17 -0
  78. package/dist/ddl/parse.js +131 -0
  79. package/dist/ddl/statements.d.ts +6 -0
  80. package/dist/ddl/statements.js +12 -0
  81. package/dist/ddl/types.d.ts +6 -0
  82. package/dist/ddl/types.js +52 -0
  83. package/dist/ddl/validate.d.ts +7 -0
  84. package/dist/ddl/validate.js +38 -0
  85. package/dist/designer/ColumnsEditor.d.ts +2 -0
  86. package/dist/designer/ColumnsEditor.js +24 -0
  87. package/dist/designer/DesignerView.d.ts +25 -0
  88. package/dist/designer/DesignerView.js +33 -0
  89. package/dist/designer/ForeignKeysEditor.d.ts +7 -0
  90. package/dist/designer/ForeignKeysEditor.js +24 -0
  91. package/dist/designer/IndexesEditor.d.ts +2 -0
  92. package/dist/designer/IndexesEditor.js +13 -0
  93. package/dist/designer/NamePicker.d.ts +11 -0
  94. package/dist/designer/NamePicker.js +13 -0
  95. package/dist/designer/OptionsEditor.d.ts +2 -0
  96. package/dist/designer/OptionsEditor.js +17 -0
  97. package/dist/designer/SqlPreview.d.ts +12 -0
  98. package/dist/designer/SqlPreview.js +17 -0
  99. package/dist/designer/TableDesigner.d.ts +10 -0
  100. package/dist/designer/TableDesigner.js +103 -0
  101. package/dist/designer/edit.d.ts +17 -0
  102. package/dist/designer/edit.js +115 -0
  103. package/dist/designer/editor-props.d.ts +10 -0
  104. package/dist/designer/editor-props.js +1 -0
  105. package/dist/designer/plan.d.ts +9 -0
  106. package/dist/designer/plan.js +13 -0
  107. package/dist/designer/recover.d.ts +2 -0
  108. package/dist/designer/recover.js +18 -0
  109. package/dist/designer/useReferenceColumns.d.ts +3 -0
  110. package/dist/designer/useReferenceColumns.js +36 -0
  111. package/dist/explorer/DatabaseExplorer.d.ts +13 -0
  112. package/dist/explorer/DatabaseExplorer.js +264 -0
  113. package/dist/explorer/RowMenu.d.ts +11 -0
  114. package/dist/explorer/RowMenu.js +89 -0
  115. package/dist/explorer/TableDialog.d.ts +15 -0
  116. package/dist/explorer/TableDialog.js +50 -0
  117. package/dist/explorer/expansion.d.ts +7 -0
  118. package/dist/explorer/expansion.js +31 -0
  119. package/dist/explorer/table-statements.d.ts +5 -0
  120. package/dist/explorer/table-statements.js +12 -0
  121. package/dist/explorer/tree.d.ts +125 -0
  122. package/dist/explorer/tree.js +295 -0
  123. package/dist/explorer/use-explorer-loads.d.ts +12 -0
  124. package/dist/explorer/use-explorer-loads.js +109 -0
  125. package/dist/explorer/use-stored-expansion.d.ts +9 -0
  126. package/dist/explorer/use-stored-expansion.js +47 -0
  127. package/dist/grid/CellEditor.d.ts +9 -0
  128. package/dist/grid/CellEditor.js +29 -0
  129. package/dist/grid/CopyAsMenu.d.ts +7 -0
  130. package/dist/grid/CopyAsMenu.js +10 -0
  131. package/dist/grid/DataGrid.d.ts +36 -0
  132. package/dist/grid/DataGrid.js +512 -0
  133. package/dist/grid/EnumPicker.d.ts +17 -0
  134. package/dist/grid/EnumPicker.js +53 -0
  135. package/dist/grid/GridHeaderCell.d.ts +36 -0
  136. package/dist/grid/GridHeaderCell.js +69 -0
  137. package/dist/grid/RecordView.d.ts +20 -0
  138. package/dist/grid/RecordView.js +126 -0
  139. package/dist/grid/ValueDock.d.ts +11 -0
  140. package/dist/grid/ValueDock.js +28 -0
  141. package/dist/grid/aggregates.d.ts +22 -0
  142. package/dist/grid/aggregates.js +62 -0
  143. package/dist/grid/cell-range.d.ts +14 -0
  144. package/dist/grid/cell-range.js +11 -0
  145. package/dist/grid/column-layout.d.ts +18 -0
  146. package/dist/grid/column-layout.js +49 -0
  147. package/dist/grid/column-selection.d.ts +11 -0
  148. package/dist/grid/column-selection.js +28 -0
  149. package/dist/grid/column-view.d.ts +10 -0
  150. package/dist/grid/column-view.js +23 -0
  151. package/dist/grid/copy-formats.d.ts +15 -0
  152. package/dist/grid/copy-formats.js +80 -0
  153. package/dist/grid/display.d.ts +20 -0
  154. package/dist/grid/display.js +81 -0
  155. package/dist/grid/edit-value.d.ts +5 -0
  156. package/dist/grid/edit-value.js +55 -0
  157. package/dist/grid/enum-type.d.ts +7 -0
  158. package/dist/grid/enum-type.js +52 -0
  159. package/dist/grid/focused-value.d.ts +4 -0
  160. package/dist/grid/focused-value.js +19 -0
  161. package/dist/grid/layout.d.ts +22 -0
  162. package/dist/grid/layout.js +74 -0
  163. package/dist/grid/navigation.d.ts +15 -0
  164. package/dist/grid/navigation.js +52 -0
  165. package/dist/grid/row-selection.d.ts +9 -0
  166. package/dist/grid/row-selection.js +24 -0
  167. package/dist/grid/sort.d.ts +7 -0
  168. package/dist/grid/sort.js +7 -0
  169. package/dist/grid/types.d.ts +30 -0
  170. package/dist/grid/types.js +9 -0
  171. package/dist/host/helper-path.d.ts +7 -0
  172. package/dist/host/helper-path.js +15 -0
  173. package/dist/host/host.d.ts +2 -0
  174. package/dist/host/host.js +343 -0
  175. package/dist/host/index.d.ts +5 -0
  176. package/dist/host/index.js +4 -0
  177. package/dist/host/spawn.d.ts +7 -0
  178. package/dist/host/spawn.js +98 -0
  179. package/dist/host/types.d.ts +19 -0
  180. package/dist/host/types.js +1 -0
  181. package/dist/host/validate.d.ts +10 -0
  182. package/dist/host/validate.js +339 -0
  183. package/dist/index.d.ts +14 -0
  184. package/dist/index.js +13 -0
  185. package/dist/locales/en.json +577 -0
  186. package/dist/locales/nl.json +577 -0
  187. package/dist/locales.d.ts +4 -0
  188. package/dist/locales.js +14 -0
  189. package/dist/protocol/connection.d.ts +56 -0
  190. package/dist/protocol/connection.js +1 -0
  191. package/dist/protocol/errors.d.ts +7 -0
  192. package/dist/protocol/errors.js +1 -0
  193. package/dist/protocol/index.d.ts +5 -0
  194. package/dist/protocol/index.js +3 -0
  195. package/dist/protocol/messages.d.ts +250 -0
  196. package/dist/protocol/messages.js +2 -0
  197. package/dist/protocol/schema.d.ts +53 -0
  198. package/dist/protocol/schema.js +1 -0
  199. package/dist/protocol/values.d.ts +21 -0
  200. package/dist/protocol/values.js +15 -0
  201. package/dist/sql-split.d.ts +15 -0
  202. package/dist/sql-split.js +201 -0
  203. package/dist/sql.d.ts +29 -0
  204. package/dist/sql.js +104 -0
  205. package/dist/structure/StructureView.d.ts +14 -0
  206. package/dist/structure/StructureView.js +99 -0
  207. package/dist/structure/structure-text.d.ts +2 -0
  208. package/dist/structure/structure-text.js +2 -0
  209. package/dist/table/CommandField.d.ts +14 -0
  210. package/dist/table/CommandField.js +157 -0
  211. package/dist/table/ImportDialog.d.ts +27 -0
  212. package/dist/table/ImportDialog.js +28 -0
  213. package/dist/table/TableStatusBar.d.ts +19 -0
  214. package/dist/table/TableStatusBar.js +22 -0
  215. package/dist/table/TableToolbar.d.ts +43 -0
  216. package/dist/table/TableToolbar.js +16 -0
  217. package/dist/table/TableView.d.ts +13 -0
  218. package/dist/table/TableView.js +508 -0
  219. package/dist/table/command-field.d.ts +57 -0
  220. package/dist/table/command-field.js +203 -0
  221. package/dist/table/grid-rows.d.ts +23 -0
  222. package/dist/table/grid-rows.js +55 -0
  223. package/dist/table/import-mapping.d.ts +7 -0
  224. package/dist/table/import-mapping.js +28 -0
  225. package/dist/table/layout-store.d.ts +13 -0
  226. package/dist/table/layout-store.js +43 -0
  227. package/dist/table/paging.d.ts +12 -0
  228. package/dist/table/paging.js +20 -0
  229. package/dist/table/pending.d.ts +32 -0
  230. package/dist/table/pending.js +94 -0
  231. package/dist/table/references.d.ts +12 -0
  232. package/dist/table/references.js +21 -0
  233. package/dist/table/useLoaded.d.ts +7 -0
  234. package/dist/table/useLoaded.js +36 -0
  235. package/dist/table/useStoredLayout.d.ts +8 -0
  236. package/dist/table/useStoredLayout.js +39 -0
  237. package/dist/table/useTableTransfer.d.ts +51 -0
  238. package/dist/table/useTableTransfer.js +125 -0
  239. package/dist/testing/fake.d.ts +21 -0
  240. package/dist/testing/fake.js +372 -0
  241. package/dist/testing/index.d.ts +1 -0
  242. package/dist/testing/index.js +1 -0
  243. package/dist/use-popup-press.d.ts +1 -0
  244. package/dist/use-popup-press.js +24 -0
  245. package/dist/use-schema-change.d.ts +1 -0
  246. package/dist/use-schema-change.js +13 -0
  247. package/dist/use-stable-callback.d.ts +1 -0
  248. package/dist/use-stable-callback.js +9 -0
  249. package/dist/value/ValuePanel.d.ts +14 -0
  250. package/dist/value/ValuePanel.js +103 -0
  251. package/dist/value/draft.d.ts +33 -0
  252. package/dist/value/draft.js +44 -0
  253. package/dist/value/hex.d.ts +14 -0
  254. package/dist/value/hex.js +46 -0
  255. package/dist/value/json.d.ts +9 -0
  256. package/dist/value/json.js +71 -0
  257. package/dist/value/views.d.ts +22 -0
  258. package/dist/value/views.js +54 -0
  259. package/dist/workbench/DatabaseWorkbench.d.ts +9 -0
  260. package/dist/workbench/DatabaseWorkbench.js +179 -0
  261. package/dist/workbench/DesignerTab.d.ts +10 -0
  262. package/dist/workbench/DesignerTab.js +22 -0
  263. package/dist/workbench/TableTab.d.ts +10 -0
  264. package/dist/workbench/TableTab.js +8 -0
  265. package/dist/workbench/tabs.d.ts +42 -0
  266. package/dist/workbench/tabs.js +139 -0
  267. package/package.json +79 -3
  268. package/src/DatabaseProvider.tsx +37 -0
  269. package/src/actions.ts +34 -0
  270. package/src/client/client.ts +324 -0
  271. package/src/client/index.ts +18 -0
  272. package/src/client/types.ts +161 -0
  273. package/src/client-context.ts +35 -0
  274. package/src/connections/ConnectionForm.tsx +474 -0
  275. package/src/connections/ConnectionManager.tsx +224 -0
  276. package/src/connections/EngineIcon.tsx +18 -0
  277. package/src/connections/connection-config.ts +143 -0
  278. package/src/connections/docker.ts +50 -0
  279. package/src/connections/engine-icons.ts +5 -0
  280. package/src/connections/use-docker-containers.ts +41 -0
  281. package/src/console/DestructiveDialog.tsx +40 -0
  282. package/src/console/HistoryPanel.tsx +67 -0
  283. package/src/console/QueryConsole.tsx +439 -0
  284. package/src/console/SchemaPicker.tsx +32 -0
  285. package/src/console/SqlEditor.tsx +95 -0
  286. package/src/console/StatementResultView.tsx +176 -0
  287. package/src/console/TransactionControls.tsx +53 -0
  288. package/src/console/destructive.ts +60 -0
  289. package/src/console/editing.ts +77 -0
  290. package/src/console/history.ts +62 -0
  291. package/src/console/labels.ts +7 -0
  292. package/src/console/outcome.ts +14 -0
  293. package/src/console/schemas.ts +7 -0
  294. package/src/console/shortcuts.ts +4 -0
  295. package/src/console/useConsoleHistory.ts +39 -0
  296. package/src/ddl/alter-mysql.ts +90 -0
  297. package/src/ddl/alter-sqlite.ts +93 -0
  298. package/src/ddl/alter.ts +29 -0
  299. package/src/ddl/column.ts +74 -0
  300. package/src/ddl/create.ts +92 -0
  301. package/src/ddl/dialect.ts +53 -0
  302. package/src/ddl/diff.ts +164 -0
  303. package/src/ddl/draft.ts +136 -0
  304. package/src/ddl/index.ts +10 -0
  305. package/src/ddl/parse.ts +161 -0
  306. package/src/ddl/statements.ts +20 -0
  307. package/src/ddl/types.ts +60 -0
  308. package/src/ddl/validate.ts +47 -0
  309. package/src/designer/ColumnsEditor.tsx +204 -0
  310. package/src/designer/DesignerView.tsx +184 -0
  311. package/src/designer/ForeignKeysEditor.tsx +132 -0
  312. package/src/designer/IndexesEditor.tsx +63 -0
  313. package/src/designer/NamePicker.tsx +44 -0
  314. package/src/designer/OptionsEditor.tsx +101 -0
  315. package/src/designer/SqlPreview.tsx +56 -0
  316. package/src/designer/TableDesigner.tsx +186 -0
  317. package/src/designer/edit.ts +137 -0
  318. package/src/designer/editor-props.ts +13 -0
  319. package/src/designer/plan.ts +25 -0
  320. package/src/designer/recover.ts +20 -0
  321. package/src/designer/useReferenceColumns.ts +54 -0
  322. package/src/explorer/DatabaseExplorer.tsx +450 -0
  323. package/src/explorer/RowMenu.tsx +134 -0
  324. package/src/explorer/TableDialog.tsx +80 -0
  325. package/src/explorer/expansion.ts +47 -0
  326. package/src/explorer/table-statements.ts +18 -0
  327. package/src/explorer/tree.ts +453 -0
  328. package/src/explorer/use-explorer-loads.ts +157 -0
  329. package/src/explorer/use-stored-expansion.ts +66 -0
  330. package/src/grid/CellEditor.tsx +53 -0
  331. package/src/grid/CopyAsMenu.tsx +33 -0
  332. package/src/grid/DataGrid.tsx +871 -0
  333. package/src/grid/EnumPicker.tsx +108 -0
  334. package/src/grid/GridHeaderCell.tsx +243 -0
  335. package/src/grid/RecordView.tsx +293 -0
  336. package/src/grid/ValueDock.tsx +52 -0
  337. package/src/grid/aggregates.ts +94 -0
  338. package/src/grid/cell-range.ts +26 -0
  339. package/src/grid/column-layout.ts +71 -0
  340. package/src/grid/column-selection.ts +42 -0
  341. package/src/grid/column-view.ts +35 -0
  342. package/src/grid/copy-formats.ts +108 -0
  343. package/src/grid/display.ts +109 -0
  344. package/src/grid/edit-value.ts +60 -0
  345. package/src/grid/enum-type.ts +62 -0
  346. package/src/grid/focused-value.ts +23 -0
  347. package/src/grid/layout.ts +91 -0
  348. package/src/grid/navigation.ts +74 -0
  349. package/src/grid/row-selection.ts +35 -0
  350. package/src/grid/sort.ts +12 -0
  351. package/src/grid/types.ts +59 -0
  352. package/src/host/helper-path.ts +41 -0
  353. package/src/host/host.ts +456 -0
  354. package/src/host/index.ts +5 -0
  355. package/src/host/spawn.ts +124 -0
  356. package/src/host/types.ts +46 -0
  357. package/src/host/validate.ts +402 -0
  358. package/src/index.ts +37 -0
  359. package/src/locales/en.json +577 -0
  360. package/src/locales/nl.json +577 -0
  361. package/src/locales.ts +18 -0
  362. package/src/protocol/connection.ts +86 -0
  363. package/src/protocol/errors.ts +38 -0
  364. package/src/protocol/index.ts +33 -0
  365. package/src/protocol/messages.ts +168 -0
  366. package/src/protocol/schema.ts +76 -0
  367. package/src/protocol/values.ts +52 -0
  368. package/src/sql-split.ts +220 -0
  369. package/src/sql.ts +152 -0
  370. package/src/structure/StructureView.tsx +269 -0
  371. package/src/structure/structure-text.ts +4 -0
  372. package/src/table/CommandField.tsx +318 -0
  373. package/src/table/ImportDialog.tsx +168 -0
  374. package/src/table/TableStatusBar.tsx +91 -0
  375. package/src/table/TableToolbar.tsx +217 -0
  376. package/src/table/TableView.tsx +880 -0
  377. package/src/table/command-field.ts +285 -0
  378. package/src/table/grid-rows.ts +80 -0
  379. package/src/table/import-mapping.ts +37 -0
  380. package/src/table/layout-store.ts +62 -0
  381. package/src/table/paging.ts +33 -0
  382. package/src/table/pending.ts +143 -0
  383. package/src/table/references.ts +38 -0
  384. package/src/table/useLoaded.ts +58 -0
  385. package/src/table/useStoredLayout.ts +53 -0
  386. package/src/table/useTableTransfer.ts +187 -0
  387. package/src/testing/fake.ts +533 -0
  388. package/src/testing/index.ts +1 -0
  389. package/src/use-popup-press.ts +27 -0
  390. package/src/use-schema-change.ts +19 -0
  391. package/src/use-stable-callback.ts +12 -0
  392. package/src/value/ValuePanel.tsx +254 -0
  393. package/src/value/draft.ts +72 -0
  394. package/src/value/hex.ts +62 -0
  395. package/src/value/json.ts +74 -0
  396. package/src/value/views.ts +68 -0
  397. package/src/workbench/DatabaseWorkbench.tsx +348 -0
  398. package/src/workbench/DesignerTab.tsx +37 -0
  399. package/src/workbench/TableTab.tsx +27 -0
  400. package/src/workbench/tabs.ts +184 -0
@@ -0,0 +1,81 @@
1
+ import { formatBytes, formatNumeral } from '@adecore/ui/format';
2
+ /* A cell never draws more than this, however long the text: the DOM stays small and the cell is one line anyway. */
3
+ export const DISPLAY_LIMIT = 200;
4
+ /* How many bytes of a binary value the cell spells out. */
5
+ export const BINARY_PREVIEW_BYTES = 8;
6
+ const NUMERIC_KINDS = new Set(['integer', 'decimal', 'float']);
7
+ /* Whether the cells of a column of this kind sit against the end of their cell, as numbers do. */
8
+ export const isNumericKind = (kind) => NUMERIC_KINDS.has(kind);
9
+ const ELLIPSIS = '…';
10
+ const isObject = (cell) => cell !== null && typeof cell === 'object';
11
+ /* Whether a cell is only the start of its value, so editing it needs the whole value first. */
12
+ export const isPreview = (cell) => {
13
+ if (!isObject(cell)) {
14
+ return false;
15
+ }
16
+ if (cell.kind === 'longText') {
17
+ return true;
18
+ }
19
+ return cell.kind === 'binary' && cell.hex.length < cell.length * 2;
20
+ };
21
+ /* A numeral in the notation asked for; text that is no numeral stays as it is. */
22
+ export const numeralText = (numeral, notation) => {
23
+ if (notation === 'database') {
24
+ return String(numeral);
25
+ }
26
+ const formatted = formatNumeral(numeral);
27
+ return formatted === String(numeral).trim() ? String(numeral) : formatted;
28
+ };
29
+ const cut = (text) => (text.length > DISPLAY_LIMIT ? `${text.slice(0, DISPLAY_LIMIT)}${ELLIPSIS}` : text);
30
+ export const cellView = (cell, kind, notation = 'database') => {
31
+ const numeric = isNumericKind(kind);
32
+ const align = numeric ? 'end' : 'start';
33
+ if (cell === null) {
34
+ return { text: 'NULL', tone: 'null', align };
35
+ }
36
+ if (typeof cell === 'boolean') {
37
+ return { text: cell ? 'true' : 'false', tone: 'value', align };
38
+ }
39
+ if (typeof cell === 'number') {
40
+ return { text: numeric ? numeralText(cell, notation) : String(cell), tone: 'value', align };
41
+ }
42
+ if (typeof cell === 'string') {
43
+ return { text: cut(numeric ? numeralText(cell, notation) : cell), tone: 'value', align };
44
+ }
45
+ switch (cell.kind) {
46
+ case 'default':
47
+ return { text: 'DEFAULT', tone: 'default', align };
48
+ case 'longText':
49
+ return { text: `${cut(cell.preview)}${cell.preview.length <= DISPLAY_LIMIT ? ELLIPSIS : ''}`, tone: 'value', align: 'start' };
50
+ case 'binary': {
51
+ const shown = cell.hex.slice(0, BINARY_PREVIEW_BYTES * 2);
52
+ const truncated = shown.length < cell.length * 2;
53
+ return { text: `0x${shown}${truncated ? ELLIPSIS : ''}`, tone: 'value', align: 'start', suffix: formatBytes(cell.length) };
54
+ }
55
+ }
56
+ };
57
+ /* The text a copy puts on the clipboard: the value as the cell has it, a preview as far as it goes. */
58
+ export const copyTextOf = (cell) => {
59
+ if (cell === null) {
60
+ return 'NULL';
61
+ }
62
+ if (typeof cell !== 'object') {
63
+ return String(cell);
64
+ }
65
+ switch (cell.kind) {
66
+ case 'default':
67
+ return 'DEFAULT';
68
+ case 'longText':
69
+ return cell.preview;
70
+ case 'binary':
71
+ return `0x${cell.hex}`;
72
+ }
73
+ };
74
+ /* An edit as a cell, so the grid draws a pending value the way it draws a loaded one. */
75
+ export const shownOfEdit = (value) => {
76
+ if (value !== null && typeof value === 'object' && value.kind === 'binary') {
77
+ const binary = value;
78
+ return { kind: 'binary', hex: binary.hex, length: binary.hex.length / 2 };
79
+ }
80
+ return value;
81
+ };
@@ -0,0 +1,5 @@
1
+ import type { Cell, EditValue, Value, ValueKind } from '../protocol/index.ts';
2
+ export declare const draftOf: (value: Cell | Value | {
3
+ readonly kind: 'default';
4
+ }) => string;
5
+ export declare const parseDraft: (text: string, kind: ValueKind) => EditValue;
@@ -0,0 +1,55 @@
1
+ /* An empty field means NULL where an empty string cannot be a value of the column. */
2
+ const EMPTY_IS_NULL = new Set(['integer', 'decimal', 'float', 'boolean', 'date', 'time', 'datetime', 'binary']);
3
+ const INTEGER = /^[+-]?\d+$/;
4
+ const HEX = /^0x([0-9a-f]*)$/i;
5
+ /* The text an editor starts with for a value that is whole (a preview has to be loaded first). */
6
+ export const draftOf = (value) => {
7
+ if (value === null) {
8
+ return '';
9
+ }
10
+ if (typeof value !== 'object') {
11
+ return String(value);
12
+ }
13
+ if (value.kind === 'binary') {
14
+ return `0x${value.hex}`;
15
+ }
16
+ if (value.kind === 'longText') {
17
+ return value.preview;
18
+ }
19
+ return '';
20
+ };
21
+ /* What a person typed, as the value to send. A number the text spells exactly stays a number; anything else goes as text and the server decides. */
22
+ export const parseDraft = (text, kind) => {
23
+ const trimmed = text.trim();
24
+ if (trimmed === '' && EMPTY_IS_NULL.has(kind)) {
25
+ return null;
26
+ }
27
+ switch (kind) {
28
+ case 'integer': {
29
+ const number = Number(trimmed);
30
+ return INTEGER.test(trimmed) && Number.isSafeInteger(number) ? number : trimmed;
31
+ }
32
+ case 'float': {
33
+ const number = Number(trimmed);
34
+ return Number.isFinite(number) ? number : trimmed;
35
+ }
36
+ case 'boolean': {
37
+ const lower = trimmed.toLowerCase();
38
+ if (lower === 'true' || lower === '1') {
39
+ return true;
40
+ }
41
+ return lower === 'false' || lower === '0' ? false : trimmed;
42
+ }
43
+ case 'binary': {
44
+ const match = HEX.exec(trimmed);
45
+ return match !== null && match[1].length % 2 === 0 ? { kind: 'binary', hex: match[1].toLowerCase() } : trimmed;
46
+ }
47
+ case 'decimal':
48
+ case 'date':
49
+ case 'time':
50
+ case 'datetime':
51
+ return trimmed;
52
+ default:
53
+ return text;
54
+ }
55
+ };
@@ -0,0 +1,7 @@
1
+ export interface EnumType {
2
+ readonly kind: 'enum' | 'set';
3
+ readonly values: readonly string[];
4
+ }
5
+ export declare const parseEnumType: (type: string) => EnumType | null;
6
+ export declare const membersOf: (value: string) => string[];
7
+ export declare const joinMembers: (type: EnumType, members: ReadonlySet<string>) => string;
@@ -0,0 +1,52 @@
1
+ const DECLARATION = /^(enum|set)\s*\(/i;
2
+ /*
3
+ * The values of a MySQL `enum('a','b')` or `set('a','b')` column type, or `null` for any other type
4
+ * or a list that does not parse. A quote inside a value is written doubled (`'it''s'`).
5
+ */
6
+ export const parseEnumType = (type) => {
7
+ const head = DECLARATION.exec(type.trim());
8
+ if (head === null) {
9
+ return null;
10
+ }
11
+ const source = type.trim().slice(head[0].length);
12
+ const values = [];
13
+ let position = 0;
14
+ while (position < source.length) {
15
+ if (source[position] !== "'") {
16
+ return null;
17
+ }
18
+ position++;
19
+ let value = '';
20
+ for (;;) {
21
+ if (position >= source.length) {
22
+ return null;
23
+ }
24
+ if (source[position] === "'") {
25
+ if (source[position + 1] === "'") {
26
+ value += "'";
27
+ position += 2;
28
+ continue;
29
+ }
30
+ position++;
31
+ break;
32
+ }
33
+ value += source[position];
34
+ position++;
35
+ }
36
+ values.push(value);
37
+ const next = source[position];
38
+ if (next === ')') {
39
+ return source.slice(position + 1).trim() === '' ? tidy(head[1], values) : null;
40
+ }
41
+ if (next !== ',') {
42
+ return null;
43
+ }
44
+ position++;
45
+ }
46
+ return null;
47
+ };
48
+ const tidy = (kind, values) => values.length === 0 ? null : { kind: kind.toLowerCase() === 'set' ? 'set' : 'enum', values };
49
+ /* The members a SET value holds: the text split on commas, empty for the empty set. */
50
+ export const membersOf = (value) => (value === '' ? [] : value.split(','));
51
+ /* A SET value in the order of the column's values, which is the order the server writes it in. */
52
+ export const joinMembers = (type, members) => type.values.filter((value) => members.has(value)).join(',');
@@ -0,0 +1,4 @@
1
+ import { type Value } from '../protocol/index.ts';
2
+ import type { Shown } from './display.ts';
3
+ export declare const wholeValueOf: (cell: Shown) => Value | undefined;
4
+ export declare const previewValueOf: (cell: Shown) => Value;
@@ -0,0 +1,19 @@
1
+ import { valueOfCell } from '../protocol/index.js';
2
+ /* The whole value of a cell, or `undefined` when it is only a preview (or a pending DEFAULT, which holds no value). */
3
+ export const wholeValueOf = (cell) => cell !== null && typeof cell === 'object' && cell.kind === 'default' ? undefined : valueOfCell(cell);
4
+ /* What a cell holds as far as it goes: the whole value, or the preview of a long text or a binary value. */
5
+ export const previewValueOf = (cell) => {
6
+ const whole = wholeValueOf(cell);
7
+ if (whole !== undefined) {
8
+ return whole;
9
+ }
10
+ if (cell !== null && typeof cell === 'object') {
11
+ if (cell.kind === 'longText') {
12
+ return cell.preview;
13
+ }
14
+ if (cell.kind === 'binary') {
15
+ return { kind: 'binary', hex: cell.hex };
16
+ }
17
+ }
18
+ return null;
19
+ };
@@ -0,0 +1,22 @@
1
+ export declare const ROW_HEIGHT = 28;
2
+ export declare const HEADER_HEIGHT = 32;
3
+ export declare const MIN_COLUMN_WIDTH = 64;
4
+ export declare const MAX_COLUMN_WIDTH = 320;
5
+ export declare const MAX_RESIZED_WIDTH = 1200;
6
+ export declare const MAX_FIT_WIDTH = 640;
7
+ export declare const OVERSCAN_ROWS = 6;
8
+ export declare const DOUBLE_CLICK_MS = 350;
9
+ export declare const FALLBACK_VIEWPORT_HEIGHT = 600;
10
+ export interface VisibleRange {
11
+ readonly start: number;
12
+ readonly end: number;
13
+ }
14
+ export declare const visibleRange: (top: number, height: number, rowHeight: number, count: number, overscan: number) => VisibleRange;
15
+ export declare const scrollToReveal: (start: number, size: number, scroll: number, viewport: number, leading: number) => number;
16
+ export declare const columnOffsets: (widths: readonly number[]) => number[];
17
+ export declare const gutterWidth: (rowCount: number) => number;
18
+ export declare const clampColumnWidth: (width: number) => number;
19
+ export declare const estimateColumnWidth: (header: string, samples: readonly string[], keyed: boolean) => number;
20
+ export declare const fitColumnWidth: (header: string, texts: readonly string[], keyed: boolean) => number;
21
+ export declare const isDoubleClick: (previous: number | null, now: number) => boolean;
22
+ export declare const growWidths: (previous: readonly number[], next: readonly number[]) => number[];
@@ -0,0 +1,74 @@
1
+ /* The measures of the grid, in whole pixels. Row and header heights are steps of the 4px spacing scale. */
2
+ export const ROW_HEIGHT = 28;
3
+ export const HEADER_HEIGHT = 32;
4
+ export const MIN_COLUMN_WIDTH = 64;
5
+ export const MAX_COLUMN_WIDTH = 320;
6
+ /* How far a drag may widen a column; the estimate stops at `MAX_COLUMN_WIDTH`, a person may go further. */
7
+ export const MAX_RESIZED_WIDTH = 1200;
8
+ /* How wide fitting a column to its content may make it. */
9
+ export const MAX_FIT_WIDTH = 640;
10
+ export const OVERSCAN_ROWS = 6;
11
+ /* Two presses on a resize handle this close are a double click. */
12
+ export const DOUBLE_CLICK_MS = 350;
13
+ /* What a viewport is taken to be until it is measured, so a first paint already holds rows. */
14
+ export const FALLBACK_VIEWPORT_HEIGHT = 600;
15
+ /* A glyph of the 13px mono face is 7.8px wide; a whole pixel on the safe side. */
16
+ const CHARACTER_WIDTH = 8;
17
+ const CELL_PADDING = 24;
18
+ const KEY_ICON_ROOM = 18;
19
+ const GUTTER_MIN_WIDTH = 40;
20
+ const SAMPLE_ROWS = 50;
21
+ /* The arrow and the position number a sorted header carries after its name. */
22
+ const SORT_ROOM = 24;
23
+ /* The rows that touch a viewport of `height` pixels starting `top` pixels into the rows, plus `overscan` rows on both sides. */
24
+ export const visibleRange = (top, height, rowHeight, count, overscan) => {
25
+ if (count <= 0 || height <= 0) {
26
+ return { start: 0, end: 0 };
27
+ }
28
+ const first = Math.floor(Math.max(0, top) / rowHeight);
29
+ const last = Math.ceil(Math.max(0, top + height) / rowHeight);
30
+ return { start: Math.max(0, Math.min(first, count) - overscan), end: Math.min(count, last + overscan) };
31
+ };
32
+ /*
33
+ * Where to scroll so that an item at `start` that is `size` long is in view. `leading` is the part of
34
+ * the viewport a sticky header or gutter covers. Returns `scroll` itself when the item is already visible.
35
+ */
36
+ export const scrollToReveal = (start, size, scroll, viewport, leading) => {
37
+ if (start < scroll + leading) {
38
+ return Math.max(0, start - leading);
39
+ }
40
+ if (start + size > scroll + viewport) {
41
+ return Math.max(0, start + size - viewport);
42
+ }
43
+ return scroll;
44
+ };
45
+ /* The left edge of every column, counted from the first one. */
46
+ export const columnOffsets = (widths) => {
47
+ let offset = 0;
48
+ return widths.map((width) => {
49
+ const left = offset;
50
+ offset += width;
51
+ return left;
52
+ });
53
+ };
54
+ /* Wide enough for the largest row number, never narrower than `GUTTER_MIN_WIDTH`. */
55
+ export const gutterWidth = (rowCount) => Math.max(GUTTER_MIN_WIDTH, String(Math.max(rowCount, 1)).length * CHARACTER_WIDTH + CELL_PADDING);
56
+ export const clampColumnWidth = (width) => Math.max(MIN_COLUMN_WIDTH, Math.min(Math.ceil(width), MAX_COLUMN_WIDTH));
57
+ /* From the longest text among the header and the first rows. `keyed` makes room for the key icon in front of the name. */
58
+ export const estimateColumnWidth = (header, samples, keyed) => {
59
+ const body = samples.slice(0, SAMPLE_ROWS).reduce((longest, text) => Math.max(longest, text.length), 0);
60
+ const named = header.length * CHARACTER_WIDTH + (keyed ? KEY_ICON_ROOM : 0) + SORT_ROOM;
61
+ return clampColumnWidth(Math.max(body * CHARACTER_WIDTH, named) + CELL_PADDING);
62
+ };
63
+ /* Wide enough for the header and every text of the column, up to `MAX_FIT_WIDTH`. */
64
+ export const fitColumnWidth = (header, texts, keyed) => {
65
+ const body = texts.reduce((longest, text) => Math.max(longest, text.length), 0) * CHARACTER_WIDTH;
66
+ const named = header.length * CHARACTER_WIDTH + (keyed ? KEY_ICON_ROOM : 0) + SORT_ROOM;
67
+ return Math.max(MIN_COLUMN_WIDTH, Math.min(Math.ceil(Math.max(body, named) + CELL_PADDING), MAX_FIT_WIDTH));
68
+ };
69
+ export const isDoubleClick = (previous, now) => previous !== null && now - previous <= DOUBLE_CLICK_MS;
70
+ /*
71
+ * The estimated widths of a new page, never narrower than they were. A page with longer content widens
72
+ * a column; a page with shorter content leaves it, so a sort does not make columns jump.
73
+ */
74
+ export const growWidths = (previous, next) => next.map((width, index) => Math.max(width, previous[index] ?? 0));
@@ -0,0 +1,15 @@
1
+ export interface CellPosition {
2
+ readonly row: number;
3
+ readonly column: number;
4
+ }
5
+ export interface GridSize {
6
+ readonly rows: number;
7
+ readonly columns: number;
8
+ readonly page: number;
9
+ }
10
+ export interface NavigationKey {
11
+ readonly key: string;
12
+ readonly shiftKey: boolean;
13
+ readonly mod: boolean;
14
+ }
15
+ export declare const moveFocus: (from: CellPosition | null, input: NavigationKey, size: GridSize) => CellPosition | null;
@@ -0,0 +1,52 @@
1
+ /* Keys that, with no cell focused yet, only put the focus on the first one. */
2
+ const ENTERING_KEYS = new Set(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageUp', 'PageDown', 'Tab']);
3
+ const clamp = (value, max) => Math.max(0, Math.min(value, max - 1));
4
+ /*
5
+ * Where a navigation key takes the focus, or `null` when the key moves nothing and the browser should
6
+ * keep it: that is also how Tab leaves the grid at its first and last cell.
7
+ */
8
+ export const moveFocus = (from, input, size) => {
9
+ if (size.rows === 0 || size.columns === 0) {
10
+ return null;
11
+ }
12
+ if (from === null && ENTERING_KEYS.has(input.key)) {
13
+ return { row: 0, column: 0 };
14
+ }
15
+ const lastRow = size.rows - 1;
16
+ const lastColumn = size.columns - 1;
17
+ const start = from ?? { row: 0, column: 0 };
18
+ const row = clamp(start.row, size.rows);
19
+ const column = clamp(start.column, size.columns);
20
+ switch (input.key) {
21
+ case 'ArrowUp':
22
+ return { row: clamp(row - 1, size.rows), column };
23
+ case 'ArrowDown':
24
+ return { row: clamp(row + 1, size.rows), column };
25
+ case 'ArrowLeft':
26
+ return { row, column: clamp(column - 1, size.columns) };
27
+ case 'ArrowRight':
28
+ return { row, column: clamp(column + 1, size.columns) };
29
+ case 'PageUp':
30
+ return { row: clamp(row - size.page, size.rows), column };
31
+ case 'PageDown':
32
+ return { row: clamp(row + size.page, size.rows), column };
33
+ case 'Home':
34
+ return { row: input.mod ? 0 : row, column: 0 };
35
+ case 'End':
36
+ return { row: input.mod ? lastRow : row, column: lastColumn };
37
+ case 'Tab': {
38
+ if (input.shiftKey) {
39
+ if (column > 0) {
40
+ return { row, column: column - 1 };
41
+ }
42
+ return row > 0 ? { row: row - 1, column: lastColumn } : null;
43
+ }
44
+ if (column < lastColumn) {
45
+ return { row, column: column + 1 };
46
+ }
47
+ return row < lastRow ? { row: row + 1, column: 0 } : null;
48
+ }
49
+ default:
50
+ return null;
51
+ }
52
+ };
@@ -0,0 +1,9 @@
1
+ export interface RowSelection {
2
+ readonly selected: ReadonlySet<string>;
3
+ readonly anchor: number;
4
+ }
5
+ export interface RowClick {
6
+ readonly shiftKey: boolean;
7
+ readonly mod: boolean;
8
+ }
9
+ export declare const selectRow: (keys: readonly string[], current: ReadonlySet<string>, anchor: number, index: number, click: RowClick) => RowSelection;
@@ -0,0 +1,24 @@
1
+ /*
2
+ * The selection after a click on the gutter of `index`: a plain click selects that row alone, Mod
3
+ * toggles it, and Shift selects everything from the anchor to it.
4
+ */
5
+ export const selectRow = (keys, current, anchor, index, click) => {
6
+ const key = keys[index];
7
+ if (key === undefined) {
8
+ return { selected: current, anchor };
9
+ }
10
+ if (click.shiftKey && anchor >= 0 && anchor < keys.length) {
11
+ const from = Math.min(anchor, index);
12
+ const to = Math.max(anchor, index);
13
+ const range = keys.slice(from, to + 1);
14
+ return { selected: new Set(click.mod ? [...current, ...range] : range), anchor };
15
+ }
16
+ if (click.mod) {
17
+ const next = new Set(current);
18
+ if (!next.delete(key)) {
19
+ next.add(key);
20
+ }
21
+ return { selected: next, anchor: index };
22
+ }
23
+ return { selected: new Set([key]), anchor: index };
24
+ };
@@ -0,0 +1,7 @@
1
+ import type { ColumnSort, SortDirection } from '../sql.ts';
2
+ export type GridSort = ColumnSort;
3
+ export declare const sortOnly: (column: string, direction: SortDirection) => GridSort[];
4
+ export declare const sortStateOf: (sorts: readonly GridSort[], column: string) => {
5
+ direction: SortDirection;
6
+ position: number;
7
+ } | null;
@@ -0,0 +1,7 @@
1
+ /* The column as the only sort, in a direction a menu picked. */
2
+ export const sortOnly = (column, direction) => [{ column, direction }];
3
+ /* The sort of a column and its place among the sorts counted from one, or `null` when it is not sorted. */
4
+ export const sortStateOf = (sorts, column) => {
5
+ const index = sorts.findIndex((sort) => sort.column === column);
6
+ return index < 0 ? null : { direction: sorts[index].direction, position: index + 1 };
7
+ };
@@ -0,0 +1,30 @@
1
+ import type { ColumnInfo, ResultColumn } from '../protocol/index.ts';
2
+ import type { Shown } from './display.ts';
3
+ export interface GridColumn extends ResultColumn {
4
+ readonly primaryKey?: boolean;
5
+ readonly nullable?: boolean;
6
+ readonly readOnly?: boolean;
7
+ readonly defaultValue?: string | null;
8
+ readonly autoIncrement?: boolean;
9
+ }
10
+ export type GridRowState = 'inserted' | 'deleted';
11
+ export interface GridRow {
12
+ readonly key: string;
13
+ readonly number: number | null;
14
+ readonly cells: readonly Shown[];
15
+ readonly state?: GridRowState;
16
+ readonly edited?: ReadonlySet<number>;
17
+ readonly locked?: boolean;
18
+ }
19
+ export declare const gridColumnOf: (column: ResultColumn, info: ColumnInfo | undefined, primaryKey: readonly string[]) => GridColumn;
20
+ export interface FocusedCell {
21
+ readonly rowKey: string;
22
+ readonly column: number;
23
+ }
24
+ export interface GridMenuContext {
25
+ readonly rowKeys: readonly string[];
26
+ readonly cell: FocusedCell | null;
27
+ }
28
+ export interface ColumnRequest {
29
+ readonly column: number;
30
+ }
@@ -0,0 +1,9 @@
1
+ /* Builds the column of a table from the result column and the structure's column of the same name. */
2
+ export const gridColumnOf = (column, info, primaryKey) => ({
3
+ ...column,
4
+ primaryKey: primaryKey.includes(column.name),
5
+ nullable: info?.nullable,
6
+ readOnly: info?.generated === true,
7
+ defaultValue: info?.defaultValue,
8
+ autoIncrement: info?.autoIncrement
9
+ });
@@ -0,0 +1,7 @@
1
+ export interface HelperPathOptions {
2
+ readonly platform?: string;
3
+ readonly arch?: string;
4
+ readonly resolve?: (specifier: string) => string;
5
+ readonly exists?: (path: string) => boolean;
6
+ }
7
+ export declare const helperPath: ({ platform, arch, resolve, exists }?: HelperPathOptions) => string | null;
@@ -0,0 +1,15 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import { dirname, join, sep } from 'node:path';
4
+ export const helperPath = ({ platform = process.platform, arch = process.arch, resolve = (specifier) => createRequire(import.meta.url).resolve(specifier), exists = existsSync } = {}) => {
5
+ let manifest;
6
+ try {
7
+ manifest = resolve(`@adecore/database-${platform}-${arch}/package.json`);
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ const binary = join(dirname(manifest), 'bin', platform === 'win32' ? 'adecore-database.exe' : 'adecore-database');
13
+ const unpacked = binary.replace(`.asar${sep}`, `.asar.unpacked${sep}`);
14
+ return exists(unpacked) ? unpacked : null;
15
+ };
@@ -0,0 +1,2 @@
1
+ import type { DatabaseHost, DatabaseHostOptions } from './types.ts';
2
+ export declare const createDatabaseHost: (options: DatabaseHostOptions) => DatabaseHost;