alinea 2.0.0-preview.13 → 2.0.0-preview.14

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 (323) hide show
  1. package/dist/.init/content/pages/welcome.json +1 -1
  2. package/dist/.mcp/later/dev.json +1 -1
  3. package/dist/.mcp/online/dev.json +1 -1
  4. package/dist/adapter/next/cms.js +6 -2
  5. package/dist/adapter/next/context.js +1 -4
  6. package/dist/adapter/next/handler.js +12 -1
  7. package/dist/backend/CommitEntries.d.ts +17 -0
  8. package/dist/backend/CommitEntries.js +39 -0
  9. package/dist/backend/Handler.d.ts +9 -0
  10. package/dist/backend/Handler.js +80 -20
  11. package/dist/backend/api/BasicAuth.js +5 -1
  12. package/dist/backend/api/CreateBackend.js +2 -2
  13. package/dist/backend/api/DatabaseApi.js +18 -5
  14. package/dist/backend/api/GithubApi.d.ts +13 -0
  15. package/dist/backend/api/GithubApi.js +170 -30
  16. package/dist/backend/api/database.js +2 -2
  17. package/dist/backend/util/Syncable.d.ts +6 -0
  18. package/dist/backend/util/Syncable.js +3 -1
  19. package/dist/bundled.d.ts +911 -151
  20. package/dist/chunks/{chunk-5H4D5JQL.js → chunk-2PP7WJUJ.js} +1 -11
  21. package/dist/chunks/{chunk-QHHMKJUO.js → chunk-7DDPSWRY.js} +465 -2
  22. package/dist/chunks/{chunk-HOETF6HN.js → chunk-PMGIIYDD.js} +1 -0
  23. package/dist/chunks/{chunk-3QFSGTGF.js → chunk-SCV3TEXM.js} +1 -1
  24. package/dist/chunks/{chunk-UPY2RUZF.js → chunk-TWBREZWC.js} +30 -0
  25. package/dist/cli/Generate.js +20 -7
  26. package/dist/cli/Mcp.js +1 -1
  27. package/dist/cli/Serve.js +1 -1
  28. package/dist/cli/bin.js +1 -1
  29. package/dist/cli/build/BuildEmitter.d.ts +5 -1
  30. package/dist/cli/build/BuildEmitter.js +8 -3
  31. package/dist/cli/generate/CompileConfig.js +10 -6
  32. package/dist/cli/generate/DevDB.d.ts +4 -1
  33. package/dist/cli/generate/DevDB.js +15 -7
  34. package/dist/cli/generate/GenerateDashboard.js +1 -0
  35. package/dist/cli/generate/MediaLocations.d.ts +18 -0
  36. package/dist/cli/generate/MediaLocations.js +69 -0
  37. package/dist/cli/serve/CreateLocalServer.js +1 -0
  38. package/dist/cli/serve/mcp/DevMcp.js +1 -1
  39. package/dist/cloud/CloudRemote.js +21 -7
  40. package/dist/cms.d.ts +4 -2
  41. package/dist/components/Alert.js +2 -2
  42. package/dist/components/AppShell.js +2 -2
  43. package/dist/components/AsyncList.d.ts +52 -0
  44. package/dist/components/AsyncList.js +69 -0
  45. package/dist/components/Breadcrumbs.js +6 -6
  46. package/dist/components/Button.js +4 -4
  47. package/dist/components/Calendar.js +18 -18
  48. package/dist/components/Checkbox.js +10 -10
  49. package/dist/components/CheckboxGroup.js +2 -2
  50. package/dist/components/Collapsible.js +5 -5
  51. package/dist/components/ColorSwatch.js +2 -2
  52. package/dist/components/ColorSwatchPicker.js +4 -4
  53. package/dist/components/ComboBox.d.ts +27 -9
  54. package/dist/components/ComboBox.js +40 -9
  55. package/dist/components/Command.js +13 -13
  56. package/dist/components/ContentCard.js +28 -28
  57. package/dist/components/ContentGrid.js +11 -11
  58. package/dist/components/DataList.js +1 -1
  59. package/dist/components/DateField.d.ts +4 -0
  60. package/dist/components/DateField.js +2 -2
  61. package/dist/components/DatePicker.js +2 -2
  62. package/dist/components/DateRangePicker.js +2 -2
  63. package/dist/components/Dialog.d.ts +14 -3
  64. package/dist/components/Dialog.js +38 -11
  65. package/dist/components/DropZone.js +6 -6
  66. package/dist/components/DropdownMenu.js +8 -8
  67. package/dist/components/Empty.js +4 -4
  68. package/dist/components/Field.d.ts +1 -1
  69. package/dist/components/Field.js +18 -12
  70. package/dist/components/Form.d.ts +23 -0
  71. package/dist/components/Form.js +64 -0
  72. package/dist/components/Link.d.ts +8 -1
  73. package/dist/components/List.js +27 -27
  74. package/dist/components/MediaPreview.js +5 -5
  75. package/dist/components/MultipleSelect.d.ts +13 -8
  76. package/dist/components/MultipleSelect.js +25 -25
  77. package/dist/components/NavRail.js +7 -7
  78. package/dist/components/NumberField.d.ts +5 -1
  79. package/dist/components/NumberField.js +6 -4
  80. package/dist/components/Page.js +6 -6
  81. package/dist/components/Popover.js +2 -2
  82. package/dist/components/PreviewFrame.js +8 -8
  83. package/dist/components/RadioGroup.js +10 -10
  84. package/dist/components/Resizable.js +1 -1
  85. package/dist/components/SearchField.js +8 -8
  86. package/dist/components/Select.d.ts +13 -10
  87. package/dist/components/Select.js +18 -32
  88. package/dist/components/Sheet.js +6 -6
  89. package/dist/components/Sidebar.js +5 -5
  90. package/dist/components/SortableList.js +12 -12
  91. package/dist/components/Spinner.js +4 -4
  92. package/dist/components/Stack.d.ts +20 -0
  93. package/dist/components/Stack.js +45 -0
  94. package/dist/components/Surface.js +1 -1
  95. package/dist/components/Switch.js +5 -5
  96. package/dist/components/Table.d.ts +11 -1
  97. package/dist/components/Table.js +81 -53
  98. package/dist/components/Tabs.js +6 -6
  99. package/dist/components/TagGroup.js +10 -10
  100. package/dist/components/TextField.d.ts +7 -1
  101. package/dist/components/TextField.js +20 -11
  102. package/dist/components/TimeField.d.ts +6 -1
  103. package/dist/components/TimeField.js +51 -26
  104. package/dist/components/Timestamp.js +1 -1
  105. package/dist/components/ToggleGroup.js +2 -2
  106. package/dist/components/Toolbar.js +3 -3
  107. package/dist/components/Tooltip.js +5 -4
  108. package/dist/components/Tree.js +27 -27
  109. package/dist/components/internal/DateControl.js +11 -11
  110. package/dist/components/internal/FormScope.d.ts +2 -0
  111. package/dist/components/internal/FormScope.js +8 -0
  112. package/dist/components/internal/ListBoxGroup.d.ts +12 -0
  113. package/dist/components/internal/ListBoxGroup.js +46 -0
  114. package/dist/components/internal/ListBoxOption.d.ts +2 -2
  115. package/dist/components/internal/ListBoxOption.js +5 -5
  116. package/dist/components/internal/Locale.js +2 -2
  117. package/dist/components/internal/PopoverSurface.js +5 -4
  118. package/dist/components/internal/SelectionCheckbox.js +5 -5
  119. package/dist/components/internal/Slot.js +1 -1
  120. package/dist/components/internal/ToggleButton.js +4 -4
  121. package/dist/components/internal/Trigger.js +2 -2
  122. package/dist/components/internal/useDragDrop.js +2 -2
  123. package/dist/components/types.d.ts +4 -0
  124. package/dist/components.d.ts +3 -0
  125. package/dist/components.js +3 -0
  126. package/dist/core/Client.js +12 -1
  127. package/dist/core/Config.d.ts +6 -0
  128. package/dist/core/Config.js +12 -0
  129. package/dist/core/DashboardEntry.d.ts +19 -0
  130. package/dist/core/DashboardEntry.js +0 -0
  131. package/dist/core/Document.d.ts +2 -2
  132. package/dist/core/Document.js +10 -3
  133. package/dist/core/EntryFields.d.ts +8 -2
  134. package/dist/core/Field.d.ts +5 -0
  135. package/dist/core/Filter.d.ts +19 -2
  136. package/dist/core/Filter.js +5 -0
  137. package/dist/core/Graph.d.ts +10 -2
  138. package/dist/core/Overview.d.ts +74 -5
  139. package/dist/core/Overview.js +1 -0
  140. package/dist/core/Root.js +1 -1
  141. package/dist/core/Scope.d.ts +5 -0
  142. package/dist/core/Scope.js +22 -5
  143. package/dist/core/Type.d.ts +25 -6
  144. package/dist/core/Type.js +25 -7
  145. package/dist/core/db/LocalStore.d.ts +7 -0
  146. package/dist/core/field/CreateField.d.ts +1 -2
  147. package/dist/core/source/Source.d.ts +2 -0
  148. package/dist/core/source/Source.js +11 -0
  149. package/dist/core/util/Async.d.ts +2 -0
  150. package/dist/core/util/Async.js +12 -1
  151. package/dist/core/util/Checks.js +1 -1
  152. package/dist/core/util/Slugs.js +4 -3
  153. package/dist/dashboard/App.css +13 -11
  154. package/dist/dashboard/App.d.ts +1 -0
  155. package/dist/dashboard/App.js +22 -6
  156. package/dist/dashboard/Href.d.ts +37 -0
  157. package/dist/dashboard/Href.js +46 -0
  158. package/dist/dashboard/app/ActivityStatus.js +34 -12
  159. package/dist/dashboard/app/AuthView.js +2 -2
  160. package/dist/dashboard/app/BlockSettings.d.ts +9 -0
  161. package/dist/dashboard/app/BlockSettings.js +16 -0
  162. package/dist/dashboard/app/BlockSheet.js +3 -3
  163. package/dist/dashboard/app/BlockSheetStoryFrame.js +2 -2
  164. package/dist/dashboard/app/CompactField.js +15 -15
  165. package/dist/dashboard/app/CroppedImage.js +2 -2
  166. package/dist/dashboard/app/DashboardLayout.d.ts +1 -1
  167. package/dist/dashboard/app/DashboardLayout.js +12 -0
  168. package/dist/dashboard/app/EntryActions.d.ts +11 -0
  169. package/dist/dashboard/app/EntryActions.js +30 -0
  170. package/dist/dashboard/app/EntryFields.d.ts +15 -2
  171. package/dist/dashboard/app/EntryFields.js +26 -5
  172. package/dist/dashboard/app/EntryHeader.js +17 -7
  173. package/dist/dashboard/app/EntryReferences.js +2 -2
  174. package/dist/dashboard/app/EntrySidebar.js +25 -23
  175. package/dist/dashboard/app/EntrySidebarPreview.js +2 -2
  176. package/dist/dashboard/app/EntryValidationModal.js +3 -3
  177. package/dist/dashboard/app/Explorer.js +84 -45
  178. package/dist/dashboard/app/ExplorerBatchActions.js +4 -4
  179. package/dist/dashboard/app/ExplorerControls.js +5 -5
  180. package/dist/dashboard/app/ExplorerList.js +2 -2
  181. package/dist/dashboard/app/ExplorerModal.js +3 -3
  182. package/dist/dashboard/app/ExplorerOverviewHeader.d.ts +6 -0
  183. package/dist/dashboard/app/ExplorerOverviewHeader.js +28 -0
  184. package/dist/dashboard/app/ExplorerTable.js +7 -7
  185. package/dist/dashboard/app/ExplorerTabs.d.ts +12 -0
  186. package/dist/dashboard/app/ExplorerTabs.js +42 -0
  187. package/dist/dashboard/app/ImageEditor.js +31 -31
  188. package/dist/dashboard/app/LinkPicker.js +3 -3
  189. package/dist/dashboard/app/LocaleMenu.js +9 -9
  190. package/dist/dashboard/app/MediaPreviewCell.js +5 -5
  191. package/dist/dashboard/app/OverviewCell.js +12 -10
  192. package/dist/dashboard/app/RemoveDialog.js +5 -0
  193. package/dist/dashboard/app/SearchBar.js +4 -4
  194. package/dist/dashboard/app/SettingsTab.d.ts +6 -0
  195. package/dist/dashboard/app/SettingsTab.js +27 -0
  196. package/dist/dashboard/app/SidebarTree.js +19 -19
  197. package/dist/dashboard/app/WorkspaceMenu.js +6 -6
  198. package/dist/dashboard/app/WorkspaceRoots.js +102 -98
  199. package/dist/dashboard/app/editor/FileEditor.js +18 -18
  200. package/dist/dashboard/app/pages/EntryPage.js +42 -39
  201. package/dist/dashboard/app/pages/RootPage.js +3 -3
  202. package/dist/dashboard/app/pages/SplashPage.js +94 -79
  203. package/dist/dashboard/app/pages/UsersPage.js +9 -9
  204. package/dist/dashboard/app/ui/DashboardModal.js +14 -14
  205. package/dist/dashboard/atoms/activity.d.ts +1 -0
  206. package/dist/dashboard/atoms/activity.js +8 -5
  207. package/dist/dashboard/atoms/config.d.ts +2 -0
  208. package/dist/dashboard/atoms/dashboard.d.ts +11 -0
  209. package/dist/dashboard/atoms/dashboard.js +8 -0
  210. package/dist/dashboard/atoms/editor.d.ts +7 -1
  211. package/dist/dashboard/atoms/editor.js +14 -2
  212. package/dist/dashboard/atoms/explorer.d.ts +15 -0
  213. package/dist/dashboard/atoms/explorer.js +43 -14
  214. package/dist/dashboard/atoms/graph.d.ts +5 -0
  215. package/dist/dashboard/atoms/graph.js +26 -1
  216. package/dist/dashboard/atoms/nav.d.ts +16 -10
  217. package/dist/dashboard/atoms/nav.js +96 -36
  218. package/dist/dashboard/atoms/overview.d.ts +26 -4
  219. package/dist/dashboard/atoms/overview.js +41 -12
  220. package/dist/dashboard/atoms/root.js +7 -1
  221. package/dist/dashboard/boot/ActivityEvent.d.ts +1 -1
  222. package/dist/dashboard/boot/Boot.js +6 -0
  223. package/dist/dashboard/boot/DashboardWorker.d.ts +6 -0
  224. package/dist/dashboard/boot/DashboardWorker.js +89 -8
  225. package/dist/dashboard/boot/LoadWorker.js +3 -0
  226. package/dist/dashboard/boot/SyncEvent.d.ts +7 -0
  227. package/dist/dashboard/boot/SyncEvent.js +14 -0
  228. package/dist/dashboard/boot/WorkerDB.d.ts +1 -0
  229. package/dist/dashboard/boot/WorkerDB.js +3 -0
  230. package/dist/dashboard/cms/EntryTable.d.ts +4 -3
  231. package/dist/dashboard/cms/EntryTable.js +2 -2
  232. package/dist/dashboard/cms/ViewProps.d.ts +3 -2
  233. package/dist/dashboard/cms/hooks.d.ts +34 -18
  234. package/dist/dashboard/cms/hooks.js +43 -18
  235. package/dist/dashboard/contexts.d.ts +3 -2
  236. package/dist/dashboard/contexts.js +3 -2
  237. package/dist/dashboard/hook/UseEntryEditor.d.ts +1 -1
  238. package/dist/dashboard/hook/UseEntryEditor.js +7 -3
  239. package/dist/dashboard/icons.d.ts +1 -0
  240. package/dist/dashboard/icons.js +15 -0
  241. package/dist/database/BrowserEntryStore.js +35 -13
  242. package/dist/database/DatabaseTables.js +1 -1
  243. package/dist/database/EntryDatabase.d.ts +10 -1
  244. package/dist/database/EntryDatabase.js +31 -10
  245. package/dist/database/EntryStore.js +1 -11
  246. package/dist/database/entry/EntryTable.d.ts +5 -3
  247. package/dist/database/entry/EntryTable.js +25 -8
  248. package/dist/database/query/Condition.d.ts +4 -1
  249. package/dist/database/query/Condition.js +16 -5
  250. package/dist/database/query/EntryQuery.js +59 -7
  251. package/dist/database/query/Relation.d.ts +13 -1
  252. package/dist/database/query/Relation.js +19 -1
  253. package/dist/database/query/Search.d.ts +7 -1
  254. package/dist/database/query/Search.js +54 -9
  255. package/dist/database/sync/EntrySyncer.d.ts +2 -0
  256. package/dist/database/sync/EntrySyncer.js +4 -2
  257. package/dist/database/sync/Ingest.d.ts +2 -1
  258. package/dist/database/sync/Ingest.js +20 -6
  259. package/dist/field/code/CodeField.view.js +12 -12
  260. package/dist/field/link/EntryLink.d.ts +4 -5
  261. package/dist/field/link/FileLink.d.ts +2 -2
  262. package/dist/field/link/ImageLink.d.ts +2 -5
  263. package/dist/field/link/ImageLink.js +0 -1
  264. package/dist/field/link/LinkField.view.js +18 -15
  265. package/dist/field/list/ListField.view.js +50 -35
  266. package/dist/field/metadata/MetadataField.view.js +14 -14
  267. package/dist/field/richtext/RichTextBlock.js +39 -35
  268. package/dist/field/richtext/RichTextExtensions.js +23 -23
  269. package/dist/field/richtext/RichTextField.view.js +6 -6
  270. package/dist/field/richtext/RichTextInsertMenu.js +5 -5
  271. package/dist/field/richtext/RichTextToolbar.js +26 -1
  272. package/dist/field/richtext/Toolbar.d.ts +9 -1
  273. package/dist/field/richtext/Toolbar.js +12 -2
  274. package/dist/field/select/SelectField.view.js +1 -0
  275. package/dist/index.css +174 -23
  276. package/dist/index.d.ts +1 -0
  277. package/dist/index.js +3 -1
  278. package/dist/next.d.ts +2 -0
  279. package/dist/next.edge.d.ts +2 -0
  280. package/dist/picker/entry/EntryPicker.d.ts +3 -1
  281. package/dist/picker/entry/EntryPicker.js +15 -1
  282. package/dist/preview/react.js +3 -0
  283. package/dist/query.d.ts +26 -14
  284. package/dist/query.js +4 -0
  285. package/dist/types.d.ts +8 -5
  286. package/dist/ui/Stack.d.ts +4 -2
  287. package/docs/ai-setup.md +3 -3
  288. package/docs/cli.md +4 -2
  289. package/docs/components/combo-box.md +105 -16
  290. package/docs/components/date-field.md +1 -1
  291. package/docs/components/dialog.md +51 -0
  292. package/docs/components/form.md +67 -0
  293. package/docs/components/link.md +10 -0
  294. package/docs/components/multiple-select.md +9 -17
  295. package/docs/components/number-field.md +5 -1
  296. package/docs/components/select.md +9 -20
  297. package/docs/components/stack.md +42 -0
  298. package/docs/components/table.md +83 -0
  299. package/docs/components/text-field.md +9 -1
  300. package/docs/components/time-field.md +5 -1
  301. package/docs/components.md +39 -1
  302. package/docs/configuration.md +3 -1
  303. package/docs/custom-fields.md +135 -7
  304. package/docs/deploy/self-host.md +2 -0
  305. package/docs/deploy.md +7 -4
  306. package/docs/fields/image.md +0 -1
  307. package/docs/fields/list.md +19 -0
  308. package/docs/fields/object.md +5 -3
  309. package/docs/fields/rich-text.md +31 -0
  310. package/docs/index.md +8 -6
  311. package/docs/instant-publishing.md +23 -2
  312. package/docs/overviews.md +128 -4
  313. package/docs/query/filtering.md +2 -0
  314. package/docs/query/related.md +58 -9
  315. package/docs/query.md +52 -1
  316. package/docs/quickstart.md +5 -5
  317. package/docs/schema/document.md +2 -0
  318. package/docs/schema/type.md +3 -1
  319. package/docs/upgrading.md +100 -19
  320. package/llms-full.txt +1022 -125
  321. package/package.json +1 -1
  322. package/readme.md +2 -2
  323. package/dist/chunks/{chunk-4ZA6KZHS.js → chunk-6FQ5IMNA.js} +3 -3
@@ -148,10 +148,16 @@ function resolveOverviewOptions(config, overview, types, sort, options = {}) {
148
148
  filters: Object.entries(overview?.filters ?? {}).map(
149
149
  ([key, filter]) => filterState(key, filter)
150
150
  ),
151
+ tabs: Object.entries(overview?.tabs ?? {}).map(([key, tab]) => ({
152
+ key,
153
+ label: tab.label,
154
+ filter: tab.filter
155
+ })),
151
156
  sort,
152
157
  layout: overview?.layout,
153
158
  thumbnail: overview?.thumbnail ? selection(overview.thumbnail, typeNames) : void 0,
154
159
  actions: overview?.actions ?? [],
160
+ header: overview?.header,
155
161
  types: listed
156
162
  };
157
163
  }
@@ -181,17 +187,31 @@ function columnSorts(columns) {
181
187
  ] : []
182
188
  );
183
189
  }
184
- function filterState(key, filter) {
185
- return {
190
+ function filterOptions(options) {
191
+ return Object.entries(options).map(([key, option]) => ({
186
192
  key,
187
- label: filter.label,
188
- multiple: filter.multiple ?? false,
189
- options: Object.entries(filter.options).map(([key2, option]) => ({
190
- key: key2,
191
- label: option.label,
192
- filter: option.filter
193
- }))
194
- };
193
+ label: option.label,
194
+ filter: option.filter
195
+ }));
196
+ }
197
+ function filterState(key, filter) {
198
+ const base = { key, label: filter.label, multiple: filter.multiple ?? false };
199
+ const { options } = filter;
200
+ if (typeof options === "function")
201
+ return { ...base, options: [], load: options };
202
+ return { ...base, options: filterOptions(options) };
203
+ }
204
+ function hasFilterLoaders(overview) {
205
+ return overview.filters.some((filter) => filter.load);
206
+ }
207
+ async function loadFilterOptions(overview, context) {
208
+ if (!hasFilterLoaders(overview)) return overview;
209
+ const filters = await Promise.all(
210
+ overview.filters.map(
211
+ async ({ load, ...filter }) => load ? { ...filter, options: filterOptions(await load(context)) } : filter
212
+ )
213
+ );
214
+ return { ...overview, filters };
195
215
  }
196
216
  function customColumn(key, column, typeNames) {
197
217
  const select = column.select === void 0 ? void 0 : selection(column.select, typeNames);
@@ -209,6 +229,7 @@ function customColumn(key, column, typeNames) {
209
229
  };
210
230
  }
211
231
  function isSortable(value) {
232
+ if (isRecord(value) && "edge" in value) return value.count === true;
212
233
  if (!Overview.isPlainExpr(value)) return false;
213
234
  if (!hasField(value)) return true;
214
235
  const field = value;
@@ -219,7 +240,7 @@ function columnSortBy(column, select) {
219
240
  if (column.sortBy) return Overview.sortExpr(column.sortBy);
220
241
  if (!select) return void 0;
221
242
  if (select.all !== void 0)
222
- return isSortable(select.all) ? select.all : void 0;
243
+ return isSortable(select.all) ? Overview.sortExpr(select.all) : void 0;
223
244
  const cases = Object.entries(select.byType ?? {});
224
245
  if (!cases.every(([, value]) => isSortable(value))) return void 0;
225
246
  return Overview.sortExpr(Object.fromEntries(cases));
@@ -321,8 +342,12 @@ function pickedFilters(overview, selection2) {
321
342
  }
322
343
  return picked;
323
344
  }
324
- function overviewFilter(overview, selection2) {
345
+ function pickedTab(overview, tab) {
346
+ return overview.tabs.find((option) => option.key === tab) ?? overview.tabs[0];
347
+ }
348
+ function overviewFilter(overview, selection2, tab) {
325
349
  const picked = pickedFilters(overview, selection2);
350
+ const tabFilter = pickedTab(overview, tab)?.filter;
326
351
  const conditions = overview.filters.flatMap((filter) => {
327
352
  const options = filter.options.filter(
328
353
  (option) => picked[filter.key]?.includes(option.key)
@@ -331,6 +356,7 @@ function overviewFilter(overview, selection2) {
331
356
  if (options.length === 1) return [options[0].filter];
332
357
  return [{ or: options.map((option) => option.filter) }];
333
358
  });
359
+ if (tabFilter) conditions.unshift(tabFilter);
334
360
  if (conditions.length === 0) return void 0;
335
361
  if (conditions.length === 1) return conditions[0];
336
362
  return { and: conditions };
@@ -467,8 +493,10 @@ export {
467
493
  columnField,
468
494
  columnLinkIds,
469
495
  columnProjection,
496
+ hasFilterLoaders,
470
497
  linkedEntryId,
471
498
  loadColumnValues,
499
+ loadFilterOptions,
472
500
  loadOverviewParent,
473
501
  openEntryAtom,
474
502
  overviewEntry,
@@ -480,6 +508,7 @@ export {
480
508
  parentTypes,
481
509
  pickedFilters,
482
510
  pickedSort,
511
+ pickedTab,
483
512
  resolveOverview,
484
513
  resolveOverviewOptions,
485
514
  sortedColumn,
@@ -28,7 +28,12 @@ import {
28
28
  treeEntryAtoms
29
29
  } from "./entry.js";
30
30
  import { shaAtom } from "./graph.js";
31
- import { overviewSortAtom, pageAtom, routeAtom } from "./nav.js";
31
+ import {
32
+ overviewSortAtom,
33
+ overviewTabAtom,
34
+ pageAtom,
35
+ routeAtom
36
+ } from "./nav.js";
32
37
  import { policyAtom } from "./user.js";
33
38
  import {
34
39
  dashboardEntryDragItem,
@@ -409,6 +414,7 @@ var RootAtoms = class {
409
414
  {
410
415
  enableNavigation: true,
411
416
  sortState: overviewSortAtom(this.workspace, this.key, parentId),
417
+ tabState: overviewTabAtom(this.workspace, this.key, parentId),
412
418
  rootData: this.data,
413
419
  // The filters picked in this list, kept when the editor comes back to
414
420
  // it, like its sort, but not applied to the lists of other entries
@@ -1,4 +1,4 @@
1
- export type ActivityType = 'mutation' | 'upload';
1
+ export type ActivityType = 'mutation' | 'upload' | 'sync';
2
2
  export type ActivityStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'blocked' | 'discarded' | 'cancelled';
3
3
  export interface Activity {
4
4
  id: string;
@@ -10,6 +10,7 @@ import { App } from "../App.js";
10
10
  import { ActivityEvent } from "./ActivityEvent.js";
11
11
  import { DashboardWorker } from "./DashboardWorker.js";
12
12
  import { loadWorker } from "./LoadWorker.js";
13
+ import { SyncEvent } from "./SyncEvent.js";
13
14
  import { WorkerDB } from "./WorkerDB.js";
14
15
  import { jsx } from "react/jsx-runtime";
15
16
  async function boot(gen) {
@@ -24,6 +25,9 @@ async function boot(gen) {
24
25
  into.id = "root";
25
26
  if (element.parentElement === document.head) document.body.append(into);
26
27
  else element.parentElement.replaceChild(into, element);
28
+ const html = document.documentElement;
29
+ if (!html.hasAttribute("data-alinea-theme"))
30
+ html.setAttribute("data-alinea-theme", "");
27
31
  const root = createRoot(into);
28
32
  let lastRevision;
29
33
  for await (const batch of gen) {
@@ -75,6 +79,8 @@ function listen(source) {
75
79
  events.dispatchEvent(new IndexEvent(data.data));
76
80
  } else if (data.type === ActivityEvent.type) {
77
81
  events.dispatchEvent(new ActivityEvent(data.activities));
82
+ } else if (data.type === SyncEvent.type) {
83
+ events.dispatchEvent(new SyncEvent(data.progress));
78
84
  }
79
85
  });
80
86
  return events;
@@ -11,6 +11,12 @@ export declare class DashboardWorker extends EventTarget {
11
11
  constructor(source?: Source);
12
12
  get db(): EntryStore | Promise<EntryStore>;
13
13
  sync(): Promise<string>;
14
+ /**
15
+ * Resolve once the dashboard can show content. Stored content shows right
16
+ * away and catches up with the remote as an activity; an empty store, or
17
+ * one whose cached content failed, waits for its first sync.
18
+ */
19
+ ready(): Promise<void>;
14
20
  sha(): Promise<string>;
15
21
  queue(id: string, mutations: Array<Mutation>): Promise<string>;
16
22
  retryActivity(): Promise<void>;
@@ -5,6 +5,7 @@ import "../../chunks/chunk-CQ52GEHY.js";
5
5
 
6
6
  // src/dashboard/boot/DashboardWorker.ts
7
7
  import { Entry } from "alinea/core/Entry";
8
+ import { createId } from "alinea/core/Id";
8
9
  import { getScope } from "alinea/core/Scope";
9
10
  import { trigger } from "alinea/core/Trigger";
10
11
  import { IndexEvent } from "alinea/core/db/IndexEvent";
@@ -17,9 +18,11 @@ import { EntryStore } from "alinea/database/EntryStore";
17
18
  import {
18
19
  ActivityEvent
19
20
  } from "./ActivityEvent.js";
21
+ import { SyncEvent } from "./SyncEvent.js";
20
22
  var remote = pLimit(1);
21
23
  var cacheName = "alinea-entry-database";
22
24
  var syncInterval = 12e4;
25
+ var progressInterval = 100;
23
26
  var activityHistoryLimit = 100;
24
27
  var DashboardWorker = class extends EventTarget {
25
28
  #source;
@@ -57,6 +60,57 @@ var DashboardWorker = class extends EventTarget {
57
60
  throw error;
58
61
  }
59
62
  }
63
+ /**
64
+ * Resolve once the dashboard can show content. Stored content shows right
65
+ * away and catches up with the remote as an activity; an empty store, or
66
+ * one whose cached content failed, waits for its first sync.
67
+ */
68
+ async ready() {
69
+ const loaded = await this.#nextLoad;
70
+ if (!loaded.stored) return void await this.sync();
71
+ loaded.caughtUp ??= this.#catchUp();
72
+ }
73
+ #catchUp() {
74
+ const activity = {
75
+ id: createId(),
76
+ type: "sync",
77
+ status: "running",
78
+ operations: [{ op: "sync" }],
79
+ startedAt: Date.now()
80
+ };
81
+ this.#activities.unshift(activity);
82
+ return this.#syncActivities([activity]);
83
+ }
84
+ async #syncActivities(activities) {
85
+ for (const activity of activities) {
86
+ activity.status = "running";
87
+ activity.finishedAt = void 0;
88
+ activity.error = void 0;
89
+ }
90
+ this.#emitActivity();
91
+ try {
92
+ await this.sync();
93
+ } catch (error) {
94
+ for (const activity of activities)
95
+ if (activity.status === "running") this.#failActivity(activity, error);
96
+ this.#startSyncing();
97
+ }
98
+ }
99
+ /** Content that synced is caught up: settle the catch-up activities. */
100
+ #settleSyncs() {
101
+ const syncs = this.#activities.filter(
102
+ (activity) => activity.type === "sync" && (activity.status === "running" || activity.status === "failed")
103
+ );
104
+ if (syncs.length === 0) return;
105
+ const finishedAt = Date.now();
106
+ for (const activity of syncs) {
107
+ activity.status = "succeeded";
108
+ activity.finishedAt = finishedAt;
109
+ activity.error = void 0;
110
+ }
111
+ this.#trimActivities();
112
+ this.#emitActivity();
113
+ }
60
114
  async #syncLoaded(load) {
61
115
  const loaded = await load;
62
116
  const { db, client } = loaded;
@@ -127,6 +181,10 @@ Remote updates: ${remote2}`
127
181
  });
128
182
  }
129
183
  async retryActivity() {
184
+ const syncs = this.#activities.filter(
185
+ (activity) => activity.type === "sync" && activity.status === "failed"
186
+ );
187
+ if (syncs.length > 0) await this.#syncActivities(syncs);
130
188
  if (this.#blocked) await this.#retryMutations();
131
189
  }
132
190
  async #retryMutations() {
@@ -191,13 +249,16 @@ Remote updates: ${remote2}`
191
249
  await this.#syncWithClient(db, client);
192
250
  this.#completeMutation(item);
193
251
  } catch (error) {
194
- this.#blocked = true;
195
- this.#failActivity(item.activity, error);
252
+ let revision;
196
253
  try {
197
- await this.#syncWithClient(db, client);
198
- item.sha = void 0;
254
+ revision = await this.#syncWithClient(db, client);
199
255
  } catch {
200
256
  }
257
+ if (revision && revision === item.sha)
258
+ return this.#completeMutation(item);
259
+ this.#blocked = true;
260
+ this.#failActivity(item.activity, error);
261
+ if (revision) item.sha = void 0;
201
262
  }
202
263
  });
203
264
  }
@@ -228,7 +289,21 @@ Remote updates: ${remote2}`
228
289
  this.dispatchEvent(new ActivityEvent(this.activities()));
229
290
  }
230
291
  async #syncWithClient(db, client) {
231
- return db.syncWith(client, { validate: false });
292
+ let reported = 0;
293
+ const onProgress = (progress) => {
294
+ const now = Date.now();
295
+ const done = progress.loaded >= progress.total;
296
+ if (!done && now - reported < progressInterval) return;
297
+ reported = now;
298
+ this.dispatchEvent(new SyncEvent(progress));
299
+ };
300
+ try {
301
+ const revision = await db.syncWith(client, { validate: false, onProgress });
302
+ this.#settleSyncs();
303
+ return revision;
304
+ } finally {
305
+ if (reported) this.dispatchEvent(new SyncEvent());
306
+ }
232
307
  }
233
308
  #failActivity(activity, error) {
234
309
  activity.status = "failed";
@@ -241,7 +316,7 @@ Remote updates: ${remote2}`
241
316
  for (let index = this.#activities.length - 1; excess > 0; index--) {
242
317
  if (index < 0) break;
243
318
  const activity = this.#activities[index];
244
- if (activity.status === "pending" || activity.status === "running" || activity.status === "blocked" || activity.type === "mutation" && activity.status === "failed")
319
+ if (activity.status === "pending" || activity.status === "running" || activity.status === "blocked" || activity.status === "failed")
245
320
  continue;
246
321
  this.#activities.splice(index, 1);
247
322
  excess -= 1;
@@ -291,12 +366,18 @@ Remote updates: ${remote2}`
291
366
  db = await this.#open(config, revision, true);
292
367
  cacheFailure = await this.#syncLocalIndex(db);
293
368
  }
294
- if (hadPrevious && (await db.source.getTree()).isEmpty)
369
+ const empty = (await db.source.getTree()).isEmpty;
370
+ if (hadPrevious && empty)
295
371
  await this.#syncWithClient(db, client).catch(() => {
296
372
  });
297
373
  this.#localDB = db;
298
374
  this.#localClient = client;
299
- nextLoad.resolve({ db, client, cacheFailure });
375
+ nextLoad.resolve({
376
+ db,
377
+ client,
378
+ cacheFailure,
379
+ stored: !cacheFailure && !empty
380
+ });
300
381
  const unsubscribe = db.onChange((change) => {
301
382
  this.dispatchEvent(
302
383
  new IndexEvent({
@@ -7,6 +7,7 @@ import "../../chunks/chunk-CQ52GEHY.js";
7
7
  import { IndexEvent } from "alinea/core/db/IndexEvent";
8
8
  import { ActivityEvent } from "./ActivityEvent.js";
9
9
  import { DashboardWorker } from "./DashboardWorker.js";
10
+ import { SyncEvent } from "./SyncEvent.js";
10
11
  async function loadWorker(gen) {
11
12
  const worker = new DashboardWorker();
12
13
  function forward(target) {
@@ -16,10 +17,12 @@ async function loadWorker(gen) {
16
17
  } catch {
17
18
  worker.removeEventListener(IndexEvent.type, listen);
18
19
  worker.removeEventListener(ActivityEvent.type, listen);
20
+ worker.removeEventListener(SyncEvent.type, listen);
19
21
  }
20
22
  };
21
23
  worker.addEventListener(IndexEvent.type, listen);
22
24
  worker.addEventListener(ActivityEvent.type, listen);
25
+ worker.addEventListener(SyncEvent.type, listen);
23
26
  }
24
27
  if ("onconnect" in globalThis) {
25
28
  addEventListener("connect", (event) => {
@@ -0,0 +1,7 @@
1
+ import type { SyncProgress } from 'alinea/core/db/LocalStore';
2
+ /** Progress of a sync from the remote, without progress once it finished. */
3
+ export declare class SyncEvent extends Event {
4
+ progress?: SyncProgress | undefined;
5
+ static readonly type = "sync";
6
+ constructor(progress?: SyncProgress | undefined);
7
+ }
@@ -0,0 +1,14 @@
1
+ import "../../chunks/chunk-CQ52GEHY.js";
2
+
3
+ // src/dashboard/boot/SyncEvent.ts
4
+ var SyncEvent = class _SyncEvent extends Event {
5
+ constructor(progress) {
6
+ super(_SyncEvent.type);
7
+ this.progress = progress;
8
+ }
9
+ progress;
10
+ static type = "sync";
11
+ };
12
+ export {
13
+ SyncEvent
14
+ };
@@ -16,6 +16,7 @@ export declare class WorkerDB extends WriteableGraph {
16
16
  sha: string;
17
17
  }>;
18
18
  resolve<Query extends GraphQuery>(query: Query): Promise<AnyQueryResult<Query>>;
19
+ ready(): Promise<void>;
19
20
  sync(): Promise<string>;
20
21
  get sha(): Promise<string>;
21
22
  referencesTo(query: EntryReferenceQuery): Promise<EntryReferenceResult>;
@@ -25,6 +25,9 @@ var WorkerDB = class extends WriteableGraph {
25
25
  const body = scope.stringify(query);
26
26
  return this.#worker.resolve(body);
27
27
  }
28
+ ready() {
29
+ return this.#worker.ready();
30
+ }
28
31
  sync() {
29
32
  return this.#worker.sync();
30
33
  }
@@ -1,4 +1,4 @@
1
- import type { EntryFields } from 'alinea/core/EntryFields';
1
+ import type { EntryFilterFields } from 'alinea/core/EntryFields';
2
2
  import type { OpenFilter } from 'alinea/core/Filter';
3
3
  import type { OrderBy } from 'alinea/core/OrderBy';
4
4
  import type { OverviewColumn, OverviewOptions } from 'alinea/core/Overview';
@@ -11,9 +11,10 @@ export interface EntryTableProps {
11
11
  type?: Type | Array<Type>;
12
12
  /**
13
13
  * Only list entries matching this filter, like the `filter` of a query,
14
- * eg. `{brand: {has: {_entry: entryId}}}`
14
+ * eg. `{brand: {has: {_entry: entryId}}}` or
15
+ * `{_referenced: Query.referencedBy({type: Product})}`
15
16
  */
16
- filter?: OpenFilter<EntryFields>;
17
+ filter?: OpenFilter<EntryFilterFields>;
17
18
  /** Only list entries of this workspace */
18
19
  workspace?: string;
19
20
  /** Only list entries of this root */
@@ -66,9 +66,9 @@ import {
66
66
  var EntryTable_default = {
67
67
  "EntryTable-loading": "alinea-EntryTable-loading",
68
68
  "EntryTableLoading": "alinea-EntryTable-loading",
69
- "EntryTable": "alinea-EntryTable",
70
69
  "EntryTable-table": "alinea-EntryTable-table",
71
- "EntryTableTable": "alinea-EntryTable-table"
70
+ "EntryTableTable": "alinea-EntryTable-table",
71
+ "EntryTable": "alinea-EntryTable"
72
72
  };
73
73
 
74
74
  // src/dashboard/cms/EntryTable.tsx
@@ -24,8 +24,9 @@ export interface SectionViewProps {
24
24
  section: Section;
25
25
  }
26
26
  /**
27
- * Props of the component a type points to with `view`. It replaces the
28
- * default entry editor for entries of that type.
27
+ * Props of the component a type points to with `view`. It replaces the form
28
+ * of entries of that type below the entry header, the field hooks edit the
29
+ * fields of the entry.
29
30
  */
30
31
  export interface TypeViewProps {
31
32
  /** The type of the entry being shown */
@@ -2,13 +2,15 @@
2
2
  * The hooks of custom field and dashboard views, exported from `alinea/cms`.
3
3
  * Their types do not expose the internal state of the dashboard.
4
4
  */
5
+ import type { DashboardEntry } from 'alinea/core/DashboardEntry';
5
6
  import type { WriteableGraph } from 'alinea/core/db/WriteableGraph';
6
- import type { Entry as EntryRecord } from 'alinea/core/Entry';
7
+ import type { Entry } from 'alinea/core/Entry';
7
8
  import type { Field } from 'alinea/core/Field';
8
9
  import type { PreviewMetadata } from 'alinea/core/Preview';
9
10
  import type { Policy } from 'alinea/core/Role';
10
11
  import type { User } from 'alinea/core/User';
11
12
  import { type Dispatch, type SetStateAction } from 'react';
13
+ import type { DashboardLocation } from '../Href.js';
12
14
  /**
13
15
  * Returns the permissions of the signed-in user. Check access with
14
16
  * `policy.get({workspace, root, id, ...})`, which returns flags such as
@@ -32,8 +34,24 @@ export declare function usePreviewMetadata(): PreviewMetadata | undefined;
32
34
  /**
33
35
  * Returns the stored value of a field in the entry, list row or object being
34
36
  * edited. Use it in a view that only reads the value.
37
+ *
38
+ * The field-based hooks (`useFieldValue`, `useField`, `useFieldSetter`, ...)
39
+ * also read the fields around a custom field: pass a field of the same row,
40
+ * of a parent row or of the entry, and it resolves in the nearest scope that
41
+ * holds it. Import the type from your schema or pass the field through the
42
+ * options of your field.
43
+ *
44
+ * A view shared by types that each define their own field can pass its key
45
+ * instead, which reads the field of the same row, untyped.
46
+ *
47
+ * @example
48
+ * // In the view of a field inside a list row of `BlogPost`
49
+ * const title = useFieldValue(BlogPost.title) // a field of the entry
50
+ * const price = useFieldValue(options.price) // a field passed as option
51
+ * const path = useFieldValue('path') // the path field of this type
35
52
  */
36
53
  export declare function useFieldValue<StoredValue, QueryValue, Mutator, Options>(field: Field<StoredValue, QueryValue, Mutator, Options>): StoredValue;
54
+ export declare function useFieldValue(key: string): unknown;
37
55
  /**
38
56
  * Returns the stored value of a field and a setter, like `useState`. The
39
57
  * setter also accepts an updater function that receives the current value.
@@ -66,39 +84,37 @@ export declare function useFieldError<StoredValue, QueryValue, Mutator, Options>
66
84
  /**
67
85
  * Returns the stored value of another field in the same entry, list row or
68
86
  * object, by its key.
87
+ *
88
+ * @deprecated Use `useFieldValue`: pass the field, which is typed and also
89
+ * reads fields of a parent row or the entry (`useFieldValue(BlogPost.title)`),
90
+ * or its key (`useFieldValue('title')`).
69
91
  */
70
92
  export declare function useSiblingFieldValue(key: string): unknown;
71
93
  /**
72
- * Returns the selected entry version as a plain Entry object.
94
+ * Returns the entry being edited, in the selected locale and version.
95
+ * `entry.data` holds the field values as saved: use `useFieldValue(field)`
96
+ * for the live value while the editor changes it.
73
97
  *
74
- * Returns null outside an entry scope, or when the current entry cannot be
75
- * resolved. The returned value follows locale/status selection and does not
76
- * expose internal atoms.
98
+ * Returns null outside an entry, eg. in a root view.
77
99
  */
78
- export declare function useEntry(): EntryRecord<Record<string, unknown>> | null;
100
+ export declare function useEntry(): DashboardEntry | null;
101
+ /** @internal */
102
+ export declare function dashboardEntry(entry: Entry): DashboardEntry;
79
103
  /**
80
104
  * Returns the current locale of the dashboard: the locale of the entry being
81
105
  * edited, or the selected locale of the current root. `null` for content
82
106
  * without translations or outside the dashboard layout.
83
107
  */
84
108
  export declare function useLocale(): string | null;
85
- /** A place in the dashboard to navigate to */
86
- export interface DashboardLocation {
87
- /** Name of the workspace */
88
- workspace: string;
89
- /** Name of the root */
90
- root: string;
91
- /** Id of the entry to open, leave out to open the root */
92
- entryId?: string;
93
- /** Locale to open, for roots with translations */
94
- locale?: string | null;
95
- }
96
109
  /**
97
110
  * Returns a function that navigates the dashboard to an entry or root. The
98
111
  * user is asked to confirm first when the current entry has unsaved changes.
112
+ * An entry can be opened by its id alone, its workspace and root are looked
113
+ * up.
99
114
  *
100
115
  * @example
101
116
  * const navigate = useNavigate()
102
- * navigate({workspace: entry.workspace, root: entry.root, entryId: entry.id})
117
+ * navigate({entryId: post.id, locale: 'en'})
118
+ * navigate({workspace: 'main', root: 'pages'})
103
119
  */
104
120
  export declare function useNavigate(): (location: DashboardLocation) => void;
@@ -9,7 +9,8 @@ import "../../chunks/chunk-CQ52GEHY.js";
9
9
  import { assert } from "alinea/core/util/Assert";
10
10
  import {
11
11
  useCallback,
12
- useContext
12
+ useContext,
13
+ useMemo
13
14
  } from "react";
14
15
  import { graphAtom } from "../atoms/core.js";
15
16
  import { routeAtom } from "../atoms/nav.js";
@@ -19,8 +20,7 @@ import {
19
20
  dashboardContext,
20
21
  entryContext,
21
22
  useEditor,
22
- useFieldInfo,
23
- useFieldNode
23
+ useFieldInfo
24
24
  } from "../contexts.js";
25
25
  function usePolicy() {
26
26
  return useAtomValueRaw(policyAtom);
@@ -35,8 +35,13 @@ function usePreviewMetadata() {
35
35
  return useAtomValueRaw(previewMetadataAtom);
36
36
  }
37
37
  function useFieldValue(field) {
38
- const node = useFieldNode(field);
39
- return useAtomValueRaw(node.value);
38
+ const editor = useEditor();
39
+ const info = typeof field === "string" ? editor.field(field) : editor.get(field);
40
+ assert(
41
+ info,
42
+ `Field not found: ${typeof field === "string" ? field : "field"}`
43
+ );
44
+ return useAtomValueRaw(info.value);
40
45
  }
41
46
  function useField(field) {
42
47
  const info = useFieldInfo(field);
@@ -61,14 +66,26 @@ function useFieldError(field) {
61
66
  return useAtomValueRaw(info.error);
62
67
  }
63
68
  function useSiblingFieldValue(key) {
64
- const editor = useEditor();
65
- const info = editor.field(key);
66
- assert(info, `Field not found: ${key}`);
67
- return useAtomValueRaw(info.value);
69
+ return useFieldValue(key);
68
70
  }
69
71
  function useEntry() {
70
- const scope = useContext(entryContext);
71
- return scope?.selectedEntry ?? null;
72
+ const selected = useContext(entryContext)?.selectedEntry;
73
+ return useMemo(() => selected ? dashboardEntry(selected) : null, [selected]);
74
+ }
75
+ function dashboardEntry(entry) {
76
+ return {
77
+ id: entry.id,
78
+ type: entry.type,
79
+ title: entry.title,
80
+ path: entry.path,
81
+ url: entry.url,
82
+ locale: entry.locale,
83
+ status: entry.status,
84
+ workspace: entry.workspace,
85
+ root: entry.root,
86
+ parentId: entry.parentId,
87
+ data: entry.data
88
+ };
72
89
  }
73
90
  function useLocale() {
74
91
  const entry = useContext(entryContext);
@@ -76,20 +93,28 @@ function useLocale() {
76
93
  if (entry) return entry.localeData.requestedLocale;
77
94
  return dashboard?.page.locale ?? null;
78
95
  }
96
+ function dashboardRoute(location) {
97
+ const locale = location.locale ?? void 0;
98
+ if (location.entryId && !location.workspace && !location.root)
99
+ return { page: "edit", entry: location.entryId, locale, view: location.view };
100
+ return {
101
+ page: "entry",
102
+ workspace: location.workspace,
103
+ root: location.root,
104
+ entry: location.entryId,
105
+ locale,
106
+ view: location.view
107
+ };
108
+ }
79
109
  function useNavigate() {
80
110
  const setRoute = useSetAtom(routeAtom);
81
111
  return useCallback(
82
- (location) => setRoute({
83
- page: "entry",
84
- workspace: location.workspace,
85
- root: location.root,
86
- entry: location.entryId,
87
- locale: location.locale ?? void 0
88
- }),
112
+ (location) => setRoute(dashboardRoute(location)),
89
113
  [setRoute]
90
114
  );
91
115
  }
92
116
  export {
117
+ dashboardEntry,
93
118
  useEntry,
94
119
  useField,
95
120
  useFieldError,
@@ -49,10 +49,11 @@ export declare const editorContext: import("react").Context<EditorModel | null>;
49
49
  */
50
50
  export declare function useEditor(): EditorModel;
51
51
  /**
52
- * Returns the editor metadata for a field in the active editor scope.
52
+ * Returns the editor metadata for a field in the active editor scope, or in
53
+ * the scope of a parent row or the entry when the field belongs there.
53
54
  */
54
55
  export declare function useFieldInfo(field: Field): import("./atoms/editor.js").EditorField;
55
56
  /**
56
- * Returns the reactive node backing a field in the active editor.
57
+ * Returns the reactive node backing a field in the editor it belongs to.
57
58
  */
58
59
  export declare function useFieldNode<Value>(field: Field): ReactiveNode<Value>;