alinea 2.0.0-preview.12 → 2.0.0-preview.13

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 (264) 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 +16 -8
  5. package/dist/adapter/next/dashboardUrl.d.ts +6 -0
  6. package/dist/adapter/next/dashboardUrl.js +13 -0
  7. package/dist/adapter/next/syncCheck.d.ts +15 -2
  8. package/dist/adapter/next/syncCheck.js +26 -9
  9. package/dist/backend/Handler.js +5 -1
  10. package/dist/backend/api/BlobStore.d.ts +21 -0
  11. package/dist/backend/api/BlobStore.js +63 -0
  12. package/dist/backend/api/CreateBackend.js +10 -8
  13. package/dist/backend/api/DatabaseApi.d.ts +4 -1
  14. package/dist/backend/api/DatabaseApi.js +88 -4
  15. package/dist/backend/api/GithubApi.js +47 -24
  16. package/dist/backend/api/database.js +6 -6
  17. package/dist/bundled.d.ts +676 -280
  18. package/dist/chunks/{bun-sqlite-5SHXN3AT.js → bun-sqlite-RI6BYU5S.js} +3 -3
  19. package/dist/chunks/{chunk-OHGAVV4G.js → chunk-3QFSGTGF.js} +2 -3
  20. package/dist/chunks/{chunk-QJGGYF6E.js → chunk-4ZA6KZHS.js} +5 -5
  21. package/dist/chunks/{chunk-ASYKC6IE.js → chunk-5H4D5JQL.js} +1 -1
  22. package/dist/chunks/{chunk-ETWOY4AL.js → chunk-A2I6MCCS.js} +1 -1
  23. package/dist/chunks/{chunk-W5AXN7GH.js → chunk-CYVOGRSD.js} +1 -2
  24. package/dist/chunks/{chunk-TIJTT5ZI.js → chunk-G43W7AME.js} +1 -0
  25. package/dist/chunks/{chunk-RE523BQ7.js → chunk-HOETF6HN.js} +5829 -5830
  26. package/dist/chunks/{chunk-AIU6CMVT.js → chunk-PTYZMV5G.js} +1 -1
  27. package/dist/chunks/{chunk-JOF663EG.js → chunk-QHHMKJUO.js} +1 -1
  28. package/dist/chunks/{chunk-66YZ47TY.js → chunk-RAR44T5O.js} +1 -1
  29. package/dist/chunks/{chunk-QSN6RH6X.js → chunk-VA6NC3MI.js} +1 -1
  30. package/dist/chunks/{node-sqlite-XVNTNMCY.js → node-sqlite-C7VJ2NSN.js} +3 -3
  31. package/dist/cli/Mcp.js +1 -1
  32. package/dist/cli/Serve.js +1 -1
  33. package/dist/cli/bin.js +2 -3
  34. package/dist/cli/serve/mcp/DevMcp.js +1 -1
  35. package/dist/cli/serve/mcp/McpTools.js +29 -1
  36. package/dist/cloud/CloudRemote.js +1 -1
  37. package/dist/components/Alert.js +2 -2
  38. package/dist/components/AppShell.js +2 -2
  39. package/dist/components/Badge.d.ts +3 -1
  40. package/dist/components/Badge.js +5 -3
  41. package/dist/components/Breadcrumbs.js +7 -7
  42. package/dist/components/Button.d.ts +6 -1
  43. package/dist/components/Button.js +16 -7
  44. package/dist/components/Calendar.js +20 -20
  45. package/dist/components/Checkbox.js +7 -7
  46. package/dist/components/CheckboxGroup.js +4 -4
  47. package/dist/components/Code.js +2 -2
  48. package/dist/components/Collapsible.js +3 -3
  49. package/dist/components/ColorSwatch.js +2 -2
  50. package/dist/components/ColorSwatchPicker.js +2 -2
  51. package/dist/components/ComboBox.js +7 -7
  52. package/dist/components/Command.js +14 -13
  53. package/dist/components/ContentCard.d.ts +3 -1
  54. package/dist/components/ContentCard.js +46 -24
  55. package/dist/components/ContentGrid.js +17 -17
  56. package/dist/components/DataList.js +2 -2
  57. package/dist/components/DateField.js +2 -2
  58. package/dist/components/DatePicker.js +2 -2
  59. package/dist/components/DateRangePicker.js +2 -2
  60. package/dist/components/Dialog.js +7 -7
  61. package/dist/components/DropZone.js +6 -6
  62. package/dist/components/DropdownMenu.js +9 -9
  63. package/dist/components/Empty.js +5 -5
  64. package/dist/components/Field.js +8 -8
  65. package/dist/components/List.js +27 -27
  66. package/dist/components/MediaPreview.js +5 -5
  67. package/dist/components/MultipleSelect.js +22 -22
  68. package/dist/components/NavRail.js +4 -4
  69. package/dist/components/NumberField.js +4 -4
  70. package/dist/components/Page.js +3 -3
  71. package/dist/components/Popover.js +2 -2
  72. package/dist/components/PreviewFrame.js +9 -9
  73. package/dist/components/RadioGroup.js +9 -9
  74. package/dist/components/Resizable.js +4 -4
  75. package/dist/components/SearchField.d.ts +6 -1
  76. package/dist/components/SearchField.js +5 -3
  77. package/dist/components/Select.js +13 -13
  78. package/dist/components/Sheet.d.ts +50 -0
  79. package/dist/components/Sheet.js +202 -0
  80. package/dist/components/Sidebar.js +4 -4
  81. package/dist/components/SortableList.d.ts +34 -30
  82. package/dist/components/SortableList.js +161 -264
  83. package/dist/components/Spinner.js +2 -2
  84. package/dist/components/Surface.js +2 -2
  85. package/dist/components/Switch.js +8 -8
  86. package/dist/components/Table.d.ts +3 -1
  87. package/dist/components/Table.js +57 -46
  88. package/dist/components/Tabs.js +5 -5
  89. package/dist/components/TagGroup.js +8 -8
  90. package/dist/components/TextField.js +10 -10
  91. package/dist/components/TimeField.js +6 -6
  92. package/dist/components/Timestamp.js +1 -1
  93. package/dist/components/ToggleGroup.js +2 -2
  94. package/dist/components/Toolbar.js +2 -2
  95. package/dist/components/Tooltip.js +5 -5
  96. package/dist/components/Tree.js +24 -24
  97. package/dist/components/internal/DateControl.js +12 -12
  98. package/dist/components/internal/ListBoxOption.js +6 -6
  99. package/dist/components/internal/Locale.js +2 -2
  100. package/dist/components/internal/PopoverSurface.js +4 -4
  101. package/dist/components/internal/SelectionCheckbox.js +5 -5
  102. package/dist/components/internal/Slot.js +1 -1
  103. package/dist/components/internal/ToggleButton.js +3 -3
  104. package/dist/components/internal/Trigger.js +2 -2
  105. package/dist/components/internal/sortableDrag.d.ts +19 -0
  106. package/dist/components/internal/sortableDrag.js +175 -0
  107. package/dist/components/internal/useDragDrop.js +2 -2
  108. package/dist/components.d.ts +1 -0
  109. package/dist/components.js +1 -0
  110. package/dist/core/Config.d.ts +6 -1
  111. package/dist/core/Document.d.ts +9 -1
  112. package/dist/core/Document.js +31 -6
  113. package/dist/core/Overview.d.ts +2 -4
  114. package/dist/core/TextDoc.d.ts +4 -0
  115. package/dist/core/Validation.d.ts +0 -1
  116. package/dist/core/Validation.js +0 -6
  117. package/dist/core/field/RichTextField.js +23 -4
  118. package/dist/core/media/MediaTypes.js +1 -1
  119. package/dist/core/source/GithubSource.d.ts +4 -0
  120. package/dist/core/source/GithubSource.js +127 -25
  121. package/dist/core/source/GithubUsage.d.ts +21 -0
  122. package/dist/core/source/GithubUsage.js +47 -0
  123. package/dist/dashboard/App.d.ts +2 -2
  124. package/dist/dashboard/App.js +5 -3
  125. package/dist/dashboard/ViewKeys.d.ts +1 -0
  126. package/dist/dashboard/ViewKeys.js +1 -0
  127. package/dist/dashboard/app/ActivityStatus.js +7 -7
  128. package/dist/dashboard/app/AuthView.js +5 -5
  129. package/dist/dashboard/app/BlockSheet.d.ts +50 -0
  130. package/dist/dashboard/app/BlockSheet.js +207 -0
  131. package/dist/dashboard/app/BlockSheetStoryFrame.d.ts +6 -0
  132. package/dist/dashboard/app/BlockSheetStoryFrame.js +29 -0
  133. package/dist/dashboard/app/CompactField.js +16 -16
  134. package/dist/dashboard/app/DashboardLayout.js +3 -1
  135. package/dist/dashboard/app/EntryFields.js +2 -2
  136. package/dist/dashboard/app/EntryHeader.js +33 -34
  137. package/dist/dashboard/app/EntryReferences.js +7 -7
  138. package/dist/dashboard/app/EntrySidebar.js +15 -15
  139. package/dist/dashboard/app/EntrySidebarPreview.js +3 -3
  140. package/dist/dashboard/app/EntryStatusIcon.d.ts +23 -0
  141. package/dist/dashboard/app/EntryStatusIcon.js +58 -0
  142. package/dist/dashboard/app/EntryValidationModal.d.ts +6 -5
  143. package/dist/dashboard/app/EntryValidationModal.js +20 -20
  144. package/dist/dashboard/app/Explorer.d.ts +3 -1
  145. package/dist/dashboard/app/Explorer.js +48 -44
  146. package/dist/dashboard/app/ExplorerBatchActions.d.ts +3 -1
  147. package/dist/dashboard/app/ExplorerBatchActions.js +68 -43
  148. package/dist/dashboard/app/ExplorerCards.js +7 -1
  149. package/dist/dashboard/app/ExplorerControls.js +6 -6
  150. package/dist/dashboard/app/ExplorerList.js +5 -5
  151. package/dist/dashboard/app/ExplorerModal.js +2 -2
  152. package/dist/dashboard/app/ExplorerTable.js +11 -8
  153. package/dist/dashboard/app/ImageEditor.js +28 -28
  154. package/dist/dashboard/app/ImagePicker.js +3 -13
  155. package/dist/dashboard/app/LinkPicker.js +28 -26
  156. package/dist/dashboard/app/LocaleMenu.js +4 -4
  157. package/dist/dashboard/app/MediaPreviewCell.js +1 -1
  158. package/dist/dashboard/app/MoveConfirmDialog.d.ts +5 -0
  159. package/dist/dashboard/app/MoveConfirmDialog.js +79 -0
  160. package/dist/dashboard/app/OverviewCell.js +8 -13
  161. package/dist/dashboard/app/PendingUploadsView.js +3 -3
  162. package/dist/dashboard/app/ReadOnlyBadge.d.ts +1 -1
  163. package/dist/dashboard/app/RemoveDialog.d.ts +17 -0
  164. package/dist/dashboard/app/{DeleteDialog.js → RemoveDialog.js} +67 -27
  165. package/dist/dashboard/app/RemoveRedirect.d.ts +7 -0
  166. package/dist/dashboard/app/RemoveRedirect.js +123 -0
  167. package/dist/dashboard/app/SearchBar.d.ts +9 -0
  168. package/dist/dashboard/app/SearchBar.js +31 -0
  169. package/dist/dashboard/app/SidebarTree.js +27 -72
  170. package/dist/dashboard/app/WorkspaceMenu.js +7 -7
  171. package/dist/dashboard/app/WorkspaceRoots.js +12 -12
  172. package/dist/dashboard/app/editor/FileEditor.js +14 -14
  173. package/dist/dashboard/app/modals/CreateEntry.js +3 -3
  174. package/dist/dashboard/app/pages/EntryPage.d.ts +2 -1
  175. package/dist/dashboard/app/pages/EntryPage.js +34 -15
  176. package/dist/dashboard/app/pages/SplashPage.js +37 -37
  177. package/dist/dashboard/app/pages/UsersPage.js +12 -12
  178. package/dist/dashboard/app/ui/DashboardModal.js +15 -14
  179. package/dist/dashboard/atoms/dashboard.js +1 -1
  180. package/dist/dashboard/atoms/entry.js +1 -14
  181. package/dist/dashboard/atoms/entryTable.js +1 -0
  182. package/dist/dashboard/atoms/explorer.d.ts +4 -0
  183. package/dist/dashboard/atoms/explorer.js +19 -7
  184. package/dist/dashboard/atoms/graph.js +1 -1
  185. package/dist/dashboard/atoms/link.js +5 -2
  186. package/dist/dashboard/atoms/move.d.ts +5 -0
  187. package/dist/dashboard/atoms/move.js +29 -3
  188. package/dist/dashboard/atoms/moveConfirmation.d.ts +34 -0
  189. package/dist/dashboard/atoms/moveConfirmation.js +95 -0
  190. package/dist/dashboard/atoms/nav.d.ts +9 -5
  191. package/dist/dashboard/atoms/nav.js +120 -45
  192. package/dist/dashboard/atoms/overview.d.ts +6 -5
  193. package/dist/dashboard/atoms/overview.js +2 -16
  194. package/dist/dashboard/atoms/remove.d.ts +112 -0
  195. package/dist/dashboard/atoms/remove.js +268 -0
  196. package/dist/dashboard/atoms/root.d.ts +2 -2
  197. package/dist/dashboard/atoms/root.js +41 -26
  198. package/dist/dashboard/atoms/user.js +1 -1
  199. package/dist/dashboard/atoms/utils.js +1 -1
  200. package/dist/dashboard/boot/Boot.js +25 -17
  201. package/dist/dashboard/boot/DashboardWorker.d.ts +1 -0
  202. package/dist/dashboard/boot/DashboardWorker.js +10 -46
  203. package/dist/dashboard/boot/LoadWorker.js +17 -10
  204. package/dist/dashboard/cms/EntryTable.js +8 -5
  205. package/dist/database/BrowserEntryStore.d.ts +12 -62
  206. package/dist/database/BrowserEntryStore.js +97 -196
  207. package/dist/database/DatabaseTables.js +2 -2
  208. package/dist/database/EntryDatabase.js +21 -1
  209. package/dist/database/EntryTransaction.js +0 -35
  210. package/dist/database/EntryUrlAliases.d.ts +4 -0
  211. package/dist/database/EntryUrlAliases.js +16 -10
  212. package/dist/database/driver/RuntimeDatabase.js +3 -3
  213. package/dist/database/driver/WasmDatabase.d.ts +5 -18
  214. package/dist/database/driver/WasmDatabase.js +15 -16
  215. package/dist/database/entry/EntryTable.js +2 -2
  216. package/dist/database/query/EntryQuery.js +1 -1
  217. package/dist/database/query/Relation.js +1 -1
  218. package/dist/database/query/Search.js +2 -2
  219. package/dist/field/code/CodeField.view.js +16 -16
  220. package/dist/field/link/EntryLink.d.ts +4 -4
  221. package/dist/field/link/FileLink.d.ts +4 -4
  222. package/dist/field/link/ImageLink.d.ts +4 -4
  223. package/dist/field/link/Link.d.ts +1 -1
  224. package/dist/field/link/LinkField.d.ts +5 -0
  225. package/dist/field/link/LinkField.view.js +244 -370
  226. package/dist/field/link/UrlLink.d.ts +4 -4
  227. package/dist/field/list/ListField.d.ts +2 -0
  228. package/dist/field/list/ListField.view.d.ts +15 -0
  229. package/dist/field/list/ListField.view.js +343 -301
  230. package/dist/field/metadata/MetadataField.d.ts +17 -7
  231. package/dist/field/metadata/MetadataField.js +14 -3
  232. package/dist/field/metadata/MetadataField.view.d.ts +1 -0
  233. package/dist/field/metadata/MetadataField.view.js +25 -21
  234. package/dist/field/richtext/RichTextBlock.d.ts +3 -1
  235. package/dist/field/richtext/RichTextBlock.js +177 -74
  236. package/dist/field/richtext/RichTextBlockHost.js +1 -1
  237. package/dist/field/richtext/RichTextExtensions.js +31 -31
  238. package/dist/field/richtext/RichTextField.view.js +14 -8
  239. package/dist/field/richtext/RichTextInsertMenu.js +43 -27
  240. package/dist/field/views.js +2 -0
  241. package/dist/index.css +490 -309
  242. package/dist/picker/url/UrlPicker.js +1 -0
  243. package/docs/components/badge.md +1 -0
  244. package/docs/components/button.md +1 -0
  245. package/docs/components/content-card.md +1 -0
  246. package/docs/components/search-field.md +1 -0
  247. package/docs/components/sortable-list.md +5 -20
  248. package/docs/components/table.md +1 -0
  249. package/docs/configuration.md +1 -1
  250. package/docs/deploy/self-host.md +1 -1
  251. package/docs/deploy.md +5 -4
  252. package/docs/fields.md +1 -1
  253. package/docs/index.md +1 -1
  254. package/docs/instant-publishing.md +7 -22
  255. package/docs/overviews.md +3 -4
  256. package/docs/upgrading.md +3 -2
  257. package/llms-full.txt +31 -55
  258. package/package.json +2 -3
  259. package/dist/core/db/EntryValidationError.d.ts +0 -13
  260. package/dist/core/db/EntryValidationError.js +0 -23
  261. package/dist/dashboard/app/DeleteDialog.d.ts +0 -11
  262. package/dist/dashboard/atoms/delete.d.ts +0 -68
  263. package/dist/dashboard/atoms/delete.js +0 -143
  264. package/dist/chunks/{chunk-MOWR65LM.js → chunk-PYDOMKJZ.js} +71 -71
@@ -11,6 +11,7 @@ import "../chunks/chunk-2PIFHEYR.js";
11
11
  import "../chunks/chunk-K62JP6HR.js";
12
12
  import "../chunks/chunk-ATF42T2B.js";
13
13
  import {
14
+ getTable,
14
15
  sql
15
16
  } from "../chunks/chunk-ETBQTP2S.js";
16
17
  import "../chunks/chunk-CQ52GEHY.js";
@@ -171,6 +172,7 @@ var EntryDatabase = class _EntryDatabase extends Graph {
171
172
  tree: revision === ReadonlyTree.EMPTY.sha ? ReadonlyTree.EMPTY : null
172
173
  });
173
174
  await syncFieldIndexes(db, config);
175
+ await analyze(db);
174
176
  }
175
177
  /**
176
178
  * Synchronize a source through this database's single prepared syncer,
@@ -194,6 +196,7 @@ var EntryDatabase = class _EntryDatabase extends Graph {
194
196
  recordsTree: this.#recordsTree
195
197
  });
196
198
  this.#tree = tree;
199
+ if (changed.length > 0) await this.#optimize();
197
200
  return changed;
198
201
  });
199
202
  const change = { revision: tree.sha, changedEntryIds };
@@ -222,7 +225,7 @@ var EntryDatabase = class _EntryDatabase extends Graph {
222
225
  const { tree } = await this.#readTreeState();
223
226
  if (!tree)
224
227
  throw new Error("Cannot reindex a database without a source tree");
225
- return this.#db.transaction(
228
+ const reindexed = await this.#db.transaction(
226
229
  async (tx) => {
227
230
  await tx.run(sql`drop table if exists temp.${blobs}`);
228
231
  await tx.run(sql`create temp table ${blobs} as
@@ -273,6 +276,8 @@ var EntryDatabase = class _EntryDatabase extends Graph {
273
276
  },
274
277
  { async: true }
275
278
  );
279
+ await this.#optimize();
280
+ return reindexed;
276
281
  });
277
282
  this.#tree = result.tree;
278
283
  this.#vocabulary = new SearchVocabulary();
@@ -386,6 +391,9 @@ var EntryDatabase = class _EntryDatabase extends Graph {
386
391
  [Symbol.asyncDispose]() {
387
392
  return this.close();
388
393
  }
394
+ async #optimize() {
395
+ if (!this.#transactional) await analyze(this.#db);
396
+ }
389
397
  getRevision() {
390
398
  return this.#queue.run(() => this.#getRevision(this.#db));
391
399
  }
@@ -527,6 +535,18 @@ var EntryDatabase = class _EntryDatabase extends Graph {
527
535
  });
528
536
  }
529
537
  };
538
+ async function analyze(db) {
539
+ try {
540
+ await db.run(sql`pragma analysis_limit = 400`);
541
+ const entries = getTable(EntryIndexTable).name;
542
+ const stats = await db.get(
543
+ sql`select 1 from sqlite_master where name = 'sqlite_stat1'`
544
+ );
545
+ const analyzed = stats && await db.get(sql`select 1 from sqlite_stat1 where tbl = ${entries}`);
546
+ await db.run(analyzed ? sql`pragma optimize = 0x10002` : sql`analyze`);
547
+ } catch {
548
+ }
549
+ }
530
550
  export {
531
551
  EntryDatabase
532
552
  };
@@ -27,8 +27,6 @@ import {
27
27
  commitChanges
28
28
  } from "alinea/core/db/CommitRequest";
29
29
  import { EntryUrlConflictError } from "alinea/core/db/EntryUrlConflictError";
30
- import { EntryValidationError } from "alinea/core/db/EntryValidationError";
31
- import { policyFieldOptions, validateEntry } from "alinea/core/Validation";
32
30
  import { dataWithUrlAlias } from "./EntryUrlAliases.js";
33
31
  var { aliases, createdAt, createdBy, updatedAt, updatedBy, ...EntrySelection } = Entry;
34
32
  var SiblingSelection = {
@@ -305,18 +303,6 @@ var EntryTransaction = class {
305
303
  (entry) => entry.locale === locale && entry.active
306
304
  );
307
305
  if (current) this.#assertUpdate(current, { path, ...data });
308
- if (status === "published" && !fromSeed)
309
- this.#assertValid(
310
- id,
311
- type,
312
- { ...data, title, path },
313
- {
314
- workspace,
315
- root,
316
- locale,
317
- parents: parent ? [...parent.parents, parent.id] : []
318
- }
319
- );
320
306
  if (status === "published")
321
307
  data = await this.#publishedData(
322
308
  { id, type, path, parentId, workspace, root, locale, data },
@@ -370,7 +356,6 @@ var EntryTransaction = class {
370
356
  const filePath = entryVersionFile(childrenDir, entry.versionStatus);
371
357
  if (entry.versionStatus === "published") {
372
358
  this.#policy.assert(Permission.Publish, entry);
373
- this.#assertValid(id, entry.type, { ...data, path }, entry);
374
359
  if (filePath !== entry.filePath) await this.#rename(id, locale, path);
375
360
  data = await this.#publishedData(
376
361
  {
@@ -418,7 +403,6 @@ var EntryTransaction = class {
418
403
  locale
419
404
  }
420
405
  );
421
- this.#assertValid(id, entry.type, { ...entry.data, path }, entry);
422
406
  const childrenDir = paths.join(entry.parentDir, path);
423
407
  const data = await this.#publishedData(
424
408
  {
@@ -822,25 +806,6 @@ var EntryTransaction = class {
822
806
  this.#policy.assert(Permission.Update, { ...entry, field: path });
823
807
  }
824
808
  }
825
- /** Published versions must pass field validation, drafts may not yet */
826
- #assertValid(id, typeName, data, resource) {
827
- const config = this.#workingDatabase.config;
828
- const type = config.schema[typeName];
829
- assert(type, `Type not found: ${typeName}`);
830
- const errors = validateEntry(type, Type.withInitialValue(type, data), {
831
- fieldOptions: policyFieldOptions(config, this.#policy, {
832
- workspace: resource.workspace,
833
- root: resource.root,
834
- locale: resource.locale,
835
- parents: resource.parents,
836
- type: typeName,
837
- id
838
- })
839
- });
840
- if (errors.length === 0) return;
841
- const title = typeof data.title === "string" ? data.title : void 0;
842
- throw new EntryValidationError({ entryId: id, title, errors });
843
- }
844
809
  /**
845
810
  * Carry over the previous URL as an alias, share translated fields and
846
811
  * guard URL uniqueness for an entry that is about to be published.
@@ -1,2 +1,6 @@
1
1
  import { Type } from 'alinea/core/Type';
2
+ /** Entries of the type keep URL aliases in their metadata */
3
+ export declare function hasUrlAliases(type: Type): boolean;
2
4
  export declare function dataWithUrlAlias(type: Type, data: Record<string, unknown>, previousUrl: string, currentUrl: string): Record<string, unknown>;
5
+ /** Adds the urls that are not an alias yet to the aliases in the metadata */
6
+ export declare function dataWithUrlAliases(data: Record<string, unknown>, urls: Array<string>): Record<string, unknown>;
@@ -29,15 +29,19 @@ function dataWithUrlAlias(type, data, previousUrl, currentUrl) {
29
29
  const aliasUrls = aliasUrlsFromData(data);
30
30
  if (aliasUrls.includes(previousUrl)) return data;
31
31
  const nextData = aliasUrls.includes(currentUrl) ? withoutUrlAlias(data, currentUrl) : data;
32
- const metadata = isRecord(nextData.metadata) ? nextData.metadata : {};
33
- const aliases = Array.isArray(metadata.aliases) ? metadata.aliases : [];
34
- return {
35
- ...nextData,
36
- metadata: {
37
- ...metadata,
38
- aliases: aliases.concat(createUrlAliasRow(previousUrl, aliases))
39
- }
40
- };
32
+ return dataWithUrlAliases(nextData, [previousUrl]);
33
+ }
34
+ function dataWithUrlAliases(data, urls) {
35
+ const existing = aliasUrlsFromData(data);
36
+ const added = new Set(urls.filter((url) => url && !existing.includes(url)));
37
+ if (added.size === 0) return data;
38
+ const metadata = isRecord(data.metadata) ? data.metadata : {};
39
+ const current = Array.isArray(metadata.aliases) ? metadata.aliases : [];
40
+ const aliases = Array.from(added).reduce(
41
+ (rows, url) => rows.concat(createUrlAliasRow(url, rows)),
42
+ current
43
+ );
44
+ return { ...data, metadata: { ...metadata, aliases } };
41
45
  }
42
46
  function withoutUrlAlias(data, url) {
43
47
  const metadata = data.metadata;
@@ -65,5 +69,7 @@ function isOrderedUrlAliasRow(value) {
65
69
  return typeof id === "string" && typeof index === "string" && isValidOrderKey(index) && value[ListRow.type] === "alias" && typeof value.url === "string";
66
70
  }
67
71
  export {
68
- dataWithUrlAlias
72
+ dataWithUrlAlias,
73
+ dataWithUrlAliases,
74
+ hasUrlAliases
69
75
  };
@@ -14,13 +14,13 @@ async function openNative(path, options) {
14
14
  if (typeof Bun !== "undefined") {
15
15
  const [{ Database: BunDatabase }, { connect: connect2 }] = await Promise.all([
16
16
  import("bun:sqlite"),
17
- import("../../chunks/bun-sqlite-5SHXN3AT.js")
17
+ import("../../chunks/bun-sqlite-RI6BYU5S.js")
18
18
  ]);
19
19
  return connect2(new BunDatabase(path, { create: true }), options);
20
20
  }
21
21
  const [{ DatabaseSync }, { connect }] = await Promise.all([
22
22
  import("node:sqlite"),
23
- import("../../chunks/node-sqlite-XVNTNMCY.js")
23
+ import("../../chunks/node-sqlite-C7VJ2NSN.js")
24
24
  ]);
25
25
  const client = new DatabaseSync(path);
26
26
  return connect(client, options);
@@ -54,7 +54,7 @@ function loadOverlayVfs() {
54
54
  async function overlayDatabase(path, options) {
55
55
  const [{ DatabaseSync }, { connect }, { pathToFileURL }] = await Promise.all([
56
56
  import("node:sqlite"),
57
- import("../../chunks/node-sqlite-XVNTNMCY.js"),
57
+ import("../../chunks/node-sqlite-C7VJ2NSN.js"),
58
58
  import("node:url")
59
59
  ]);
60
60
  const file = pathToFileURL(path).href;
@@ -1,4 +1,4 @@
1
- import type { Storage } from '@alinea/sqlite-wasm/Database.js';
1
+ import type { Database as WasmSqlite } from '@alinea/sqlite-wasm/Database.js';
2
2
  import type { DatabaseOptions } from 'rado';
3
3
  import { connect } from 'rado/driver/sql.js';
4
4
  import type { DatabaseHandle } from './DatabaseHandle.js';
@@ -6,24 +6,11 @@ export interface WasmDatabaseHandle extends DatabaseHandle {
6
6
  database: ReturnType<typeof connect>;
7
7
  fork(): Promise<WasmDatabaseHandle>;
8
8
  export(): Uint8Array;
9
- /** Resolves once every commit so far is stored; at once in memory. */
10
- flush(): Promise<void>;
11
- /**
12
- * Store this database from now on, replacing what the storage held, once
13
- * a database detached from it wrote its last commits.
14
- */
15
- attach(storage: Storage): Promise<void>;
16
- /**
17
- * Stop storing commits once the ones so far are written; later commits
18
- * change only the memory copy.
19
- */
20
- detach(): void;
21
9
  }
22
- /**
23
- * Open a WASM connection from the database kept in storage, or an empty one,
24
- * that stores every commit there.
25
- */
26
- export declare function syncWasmDatabase(storage: Storage, options?: DatabaseOptions): Promise<WasmDatabaseHandle>;
10
+ /** The WASM SQLite database class, loaded on first use. */
11
+ export declare function wasmSqlite(): Promise<new () => WasmSqlite>;
12
+ /** Connect to `sqlite`; forks keep its page cache size. */
13
+ export declare function wasmHandle(sqlite: WasmSqlite, options?: DatabaseOptions): WasmDatabaseHandle;
27
14
  /** Open an in-memory WASM connection, optionally from a complete SQLite file. */
28
15
  export declare function openWasmDatabase(data?: Uint8Array, options?: DatabaseOptions): Promise<WasmDatabaseHandle>;
29
16
  export declare function wasmDatabase(data?: Uint8Array): Promise<import("rado").SyncDatabase<"sqlite">>;
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  connect
3
- } from "../../chunks/chunk-66YZ47TY.js";
4
- import "../../chunks/chunk-AIU6CMVT.js";
3
+ } from "../../chunks/chunk-RAR44T5O.js";
4
+ import "../../chunks/chunk-PTYZMV5G.js";
5
5
  import "../../chunks/chunk-N47Y62CI.js";
6
6
  import "../../chunks/chunk-QBPYWU6C.js";
7
7
  import "../../chunks/chunk-2BJ2IFQM.js";
8
8
  import "../../chunks/chunk-XCZXR3C2.js";
9
- import "../../chunks/chunk-MOWR65LM.js";
9
+ import "../../chunks/chunk-PYDOMKJZ.js";
10
10
  import "../../chunks/chunk-76VMZTLN.js";
11
11
  import "../../chunks/chunk-2PIFHEYR.js";
12
12
  import "../../chunks/chunk-K62JP6HR.js";
@@ -16,33 +16,32 @@ import "../../chunks/chunk-CQ52GEHY.js";
16
16
 
17
17
  // src/database/driver/WasmDatabase.ts
18
18
  var cacheSize = -16384;
19
+ async function wasmSqlite() {
20
+ const { default: init } = await import("@alinea/sqlite-wasm");
21
+ const { Database } = await init();
22
+ return Database;
23
+ }
19
24
  function wasmHandle(sqlite, options) {
20
- sqlite.run(`pragma cache_size = ${cacheSize}`);
21
25
  return {
22
26
  database: connect(sqlite, options),
23
27
  driver: "wasm",
24
28
  fork: async () => wasmHandle(sqlite.fork(), options),
25
- export: () => sqlite.export(),
26
- flush: () => sqlite.flush(),
27
- attach: (storage) => sqlite.attach(storage),
28
- detach: () => sqlite.detach()
29
+ export: () => sqlite.export()
29
30
  };
30
31
  }
31
- async function syncWasmDatabase(storage, options) {
32
- const { default: init } = await import("@alinea/sqlite-wasm");
33
- const { Database } = await init();
34
- return wasmHandle(await Database.sync(storage), options);
35
- }
36
32
  async function openWasmDatabase(data, options) {
37
33
  const { default: init } = await import("@alinea/sqlite-wasm");
38
34
  const { Database } = await init();
39
- return wasmHandle(new Database(data), options);
35
+ const sqlite = new Database(data);
36
+ sqlite.run(`pragma cache_size = ${cacheSize}`);
37
+ return wasmHandle(sqlite, options);
40
38
  }
41
39
  async function wasmDatabase(data) {
42
40
  return (await openWasmDatabase(data)).database;
43
41
  }
44
42
  export {
45
43
  openWasmDatabase,
46
- syncWasmDatabase,
47
- wasmDatabase
44
+ wasmDatabase,
45
+ wasmHandle,
46
+ wasmSqlite
48
47
  };
@@ -4,11 +4,11 @@ import {
4
4
  json,
5
5
  text,
6
6
  varchar
7
- } from "../../chunks/chunk-ASYKC6IE.js";
7
+ } from "../../chunks/chunk-5H4D5JQL.js";
8
8
  import {
9
9
  primaryKey,
10
10
  table
11
- } from "../../chunks/chunk-MOWR65LM.js";
11
+ } from "../../chunks/chunk-PYDOMKJZ.js";
12
12
  import "../../chunks/chunk-76VMZTLN.js";
13
13
  import {
14
14
  index
@@ -20,7 +20,7 @@ import {
20
20
  } from "../../chunks/chunk-XCZXR3C2.js";
21
21
  import {
22
22
  alias
23
- } from "../../chunks/chunk-MOWR65LM.js";
23
+ } from "../../chunks/chunk-PYDOMKJZ.js";
24
24
  import "../../chunks/chunk-76VMZTLN.js";
25
25
  import "../../chunks/chunk-2PIFHEYR.js";
26
26
  import "../../chunks/chunk-K62JP6HR.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "../../chunks/chunk-XCZXR3C2.js";
18
18
  import {
19
19
  alias
20
- } from "../../chunks/chunk-MOWR65LM.js";
20
+ } from "../../chunks/chunk-PYDOMKJZ.js";
21
21
  import "../../chunks/chunk-76VMZTLN.js";
22
22
  import "../../chunks/chunk-2PIFHEYR.js";
23
23
  import "../../chunks/chunk-K62JP6HR.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  integer,
3
3
  text
4
- } from "../../chunks/chunk-ASYKC6IE.js";
4
+ } from "../../chunks/chunk-5H4D5JQL.js";
5
5
  import {
6
6
  table
7
- } from "../../chunks/chunk-MOWR65LM.js";
7
+ } from "../../chunks/chunk-PYDOMKJZ.js";
8
8
  import "../../chunks/chunk-76VMZTLN.js";
9
9
  import "../../chunks/chunk-2PIFHEYR.js";
10
10
  import "../../chunks/chunk-K62JP6HR.js";
@@ -64,27 +64,27 @@ import { Fragment, useId } from "react";
64
64
 
65
65
  // src/field/code/CodeField.module.css
66
66
  var CodeField_default = {
67
- "CodeEditorInput-string": "alinea-CodeEditorInput-string",
68
- "CodeEditorInputString": "alinea-CodeEditorInput-string",
69
- "CodeEditorInput-regex": "alinea-CodeEditorInput-regex",
70
- "CodeEditorInputRegex": "alinea-CodeEditorInput-regex",
71
- "CodeEditorInput-punctuation": "alinea-CodeEditorInput-punctuation",
72
- "CodeEditorInputPunctuation": "alinea-CodeEditorInput-punctuation",
73
- "CodeEditorInput-identifier": "alinea-CodeEditorInput-identifier",
74
- "CodeEditorInputIdentifier": "alinea-CodeEditorInput-identifier",
75
- "CodeEditorInput-pre": "alinea-CodeEditorInput-pre",
76
- "CodeEditorInputPre": "alinea-CodeEditorInput-pre",
77
67
  "CodeEditorInput-textarea": "alinea-CodeEditorInput-textarea",
78
68
  "CodeEditorInputTextarea": "alinea-CodeEditorInput-textarea",
79
- "CodeEditorInput-keyword": "alinea-CodeEditorInput-keyword",
80
- "CodeEditorInputKeyword": "alinea-CodeEditorInput-keyword",
81
- "CodeEditorInput-number": "alinea-CodeEditorInput-number",
82
- "CodeEditorInputNumber": "alinea-CodeEditorInput-number",
69
+ "CodeEditorInput": "alinea-CodeEditorInput",
70
+ "CodeEditorInput-pre": "alinea-CodeEditorInput-pre",
71
+ "CodeEditorInputPre": "alinea-CodeEditorInput-pre",
72
+ "CodeEditorInput-identifier": "alinea-CodeEditorInput-identifier",
73
+ "CodeEditorInputIdentifier": "alinea-CodeEditorInput-identifier",
83
74
  "CodeEditorInput-editor": "alinea-CodeEditorInput-editor",
84
75
  "CodeEditorInputEditor": "alinea-CodeEditorInput-editor",
85
- "CodeEditorInput": "alinea-CodeEditorInput",
86
76
  "CodeEditorInput-comment": "alinea-CodeEditorInput-comment",
87
- "CodeEditorInputComment": "alinea-CodeEditorInput-comment"
77
+ "CodeEditorInputComment": "alinea-CodeEditorInput-comment",
78
+ "CodeEditorInput-number": "alinea-CodeEditorInput-number",
79
+ "CodeEditorInputNumber": "alinea-CodeEditorInput-number",
80
+ "CodeEditorInput-string": "alinea-CodeEditorInput-string",
81
+ "CodeEditorInputString": "alinea-CodeEditorInput-string",
82
+ "CodeEditorInput-keyword": "alinea-CodeEditorInput-keyword",
83
+ "CodeEditorInputKeyword": "alinea-CodeEditorInput-keyword",
84
+ "CodeEditorInput-punctuation": "alinea-CodeEditorInput-punctuation",
85
+ "CodeEditorInputPunctuation": "alinea-CodeEditorInput-punctuation",
86
+ "CodeEditorInput-regex": "alinea-CodeEditorInput-regex",
87
+ "CodeEditorInputRegex": "alinea-CodeEditorInput-regex"
88
88
  };
89
89
 
90
90
  // src/field/code/CodeField.view.tsx
@@ -3,10 +3,10 @@ import type { InferStoredValue } from 'alinea/core/Infer';
3
3
  import type { Label } from 'alinea/core/Label';
4
4
  import type { Type } from 'alinea/core/Type';
5
5
  import type { ListRow } from 'alinea/core/ListRow';
6
- import { type LinkFieldOptions } from 'alinea/field/link/LinkField';
6
+ import { type LinkFieldOptions, type LinkFields } from 'alinea/field/link/LinkField';
7
7
  import { type EntryPickerOptions } from 'alinea/picker/entry';
8
8
  import type { EntryReference } from 'alinea/picker/entry/EntryReference';
9
- export interface EntryLink<InferredFields = undefined> extends EntryReference {
9
+ export interface EntryLink<InferredFields = {}> extends EntryReference {
10
10
  entryId: string;
11
11
  entryType: string;
12
12
  title: string;
@@ -25,9 +25,9 @@ export declare namespace EntryLink {
25
25
  }
26
26
  interface EntryOptions<Fields> extends LinkFieldOptions<EntryReference & InferStoredValue<Fields>>, Omit<EntryPickerOptions<Fields>, 'label' | 'selection'> {
27
27
  }
28
- export declare function entry<Fields = undefined>(label: Label, options?: WithoutLabel<EntryOptions<Fields>>): import("alinea/field/link/LinkField").LinkField<EntryReference & InferStoredValue<Fields>, EntryLink<{ [K in keyof Fields as Fields[K] extends import("../../core/Expr").Expr<any> ? K : never]: Fields[K] extends import("../../core/Expr").Expr<infer T_1> ? T_1 : never; } extends infer T ? { [K in keyof T]: T[K]; } : never>>;
28
+ export declare function entry<Fields = undefined>(label: Label, options?: WithoutLabel<EntryOptions<Fields>>): import("alinea/field/link/LinkField").LinkField<EntryReference & InferStoredValue<Fields>, EntryLink<LinkFields<{ [K in keyof Fields as Fields[K] extends import("../../core/Expr").Expr<any> ? K : never]: Fields[K] extends import("../../core/Expr").Expr<infer T_1> ? T_1 : never; } extends infer T ? { [K in keyof T]: T[K]; } : never>>>;
29
29
  export declare namespace entry {
30
- type EntryRow<Fields> = EntryLink<Type.Infer<Fields>> & ListRow;
30
+ type EntryRow<Fields> = EntryLink<LinkFields<Type.Infer<Fields>>> & ListRow;
31
31
  interface EntryOptions<Fields> extends LinkFieldOptions<Array<EntryReference & ListRow & InferStoredValue<Fields>>>, Omit<EntryPickerOptions<Fields>, 'label' | 'selection'> {
32
32
  }
33
33
  export function multiple<Fields = undefined>(label: Label, options?: WithoutLabel<EntryOptions<Fields>>): import("alinea/field/link/LinkField").LinksField<EntryReference & ListRow & InferStoredValue<Fields>, EntryRow<Fields>>;
@@ -2,10 +2,10 @@ import type { WithoutLabel } from 'alinea/core/Field';
2
2
  import type { InferStoredValue } from 'alinea/core/Infer';
3
3
  import type { Label } from 'alinea/core/Label';
4
4
  import type { ListRow } from 'alinea/core/ListRow';
5
- import { type LinkFieldOptions } from 'alinea/field/link/LinkField';
5
+ import { type LinkFieldOptions, type LinkFields } from 'alinea/field/link/LinkField';
6
6
  import { type EntryPickerOptions } from 'alinea/picker/entry';
7
7
  import type { EntryReference } from 'alinea/picker/entry/EntryReference';
8
- export interface FileLink<InferredFields = undefined> extends EntryReference {
8
+ export interface FileLink<InferredFields = {}> extends EntryReference {
9
9
  title: string;
10
10
  /** Public url of the file */
11
11
  url: string;
@@ -25,9 +25,9 @@ export declare namespace FileLink {
25
25
  export declare function filePicker<Fields>(multiple: boolean, options: Omit<EntryPickerOptions<Fields>, 'selection'>): import("../../core/Picker").Picker<EntryReference, EntryPickerOptions<Fields>>;
26
26
  export interface FileOptions<Fields> extends LinkFieldOptions<EntryReference & InferStoredValue<Fields>>, Omit<EntryPickerOptions<Fields>, 'label' | 'selection'> {
27
27
  }
28
- export declare function file<Fields = undefined>(label: Label, options?: WithoutLabel<FileOptions<Fields>>): import("alinea/field/link/LinkField").LinkField<EntryReference & InferStoredValue<Fields>, FileLink<{ [K in keyof Fields as Fields[K] extends import("../../core/Expr").Expr<any> ? K : never]: Fields[K] extends import("../../core/Expr").Expr<infer T_1> ? T_1 : never; } extends infer T ? { [K in keyof T]: T[K]; } : never>>;
28
+ export declare function file<Fields = undefined>(label: Label, options?: WithoutLabel<FileOptions<Fields>>): import("alinea/field/link/LinkField").LinkField<EntryReference & InferStoredValue<Fields>, FileLink<LinkFields<{ [K in keyof Fields as Fields[K] extends import("../../core/Expr").Expr<any> ? K : never]: Fields[K] extends import("../../core/Expr").Expr<infer T_1> ? T_1 : never; } extends infer T ? { [K in keyof T]: T[K]; } : never>>>;
29
29
  export declare namespace file {
30
30
  interface FilesOptions<Fields> extends LinkFieldOptions<Array<EntryReference & ListRow & InferStoredValue<Fields>>>, Omit<EntryPickerOptions<Fields>, 'label' | 'selection'> {
31
31
  }
32
- function multiple<Fields = undefined>(label: Label, options?: WithoutLabel<FilesOptions<Fields>>): import("alinea/field/link/LinkField").LinksField<EntryReference & ListRow & InferStoredValue<Fields>, FileLink<{ [K in keyof Fields as Fields[K] extends import("../../core/Expr").Expr<any> ? K : never]: Fields[K] extends import("../../core/Expr").Expr<infer T_1> ? T_1 : never; } extends infer T ? { [K in keyof T]: T[K]; } : never>>;
32
+ function multiple<Fields = undefined>(label: Label, options?: WithoutLabel<FilesOptions<Fields>>): import("alinea/field/link/LinkField").LinksField<EntryReference & ListRow & InferStoredValue<Fields>, FileLink<LinkFields<{ [K in keyof Fields as Fields[K] extends import("../../core/Expr").Expr<any> ? K : never]: Fields[K] extends import("../../core/Expr").Expr<infer T_1> ? T_1 : never; } extends infer T ? { [K in keyof T]: T[K]; } : never>>>;
33
33
  }
@@ -3,10 +3,10 @@ import type { InferStoredValue } from 'alinea/core/Infer';
3
3
  import type { Label } from 'alinea/core/Label';
4
4
  import type { Type } from 'alinea/core/Type';
5
5
  import type { ListRow } from 'alinea/core/ListRow';
6
- import { type LinkField, type LinkFieldOptions, type LinksField } from 'alinea/field/link/LinkField';
6
+ import { type LinkField, type LinkFieldOptions, type LinksField, type LinkFields } from 'alinea/field/link/LinkField';
7
7
  import { type EntryPickerOptions } from 'alinea/picker/entry';
8
8
  import type { EntryReference } from 'alinea/picker/entry/EntryReference';
9
- export interface ImageLink<InferredFields = undefined> extends EntryReference {
9
+ export interface ImageLink<InferredFields = {}> extends EntryReference {
10
10
  title: string;
11
11
  alt?: string;
12
12
  /** Public url of the image file, versioned by its hash */
@@ -43,12 +43,12 @@ export declare namespace ImageLink {
43
43
  y: number;
44
44
  }>;
45
45
  }
46
- export interface ImageField<Fields = undefined> extends LinkField<EntryReference & InferStoredValue<Fields>, ImageLink<Type.Infer<Fields>>> {
46
+ export interface ImageField<Fields = undefined> extends LinkField<EntryReference & InferStoredValue<Fields>, ImageLink<LinkFields<Type.Infer<Fields>>>> {
47
47
  }
48
48
  export interface ImageOptions<Fields> extends LinkFieldOptions<EntryReference & InferStoredValue<Fields>>, Omit<EntryPickerOptions<Fields>, 'label' | 'selection'> {
49
49
  }
50
50
  export declare function image<Fields = undefined>(label: Label, options?: WithoutLabel<ImageOptions<Fields>>): ImageField<Fields>;
51
- export interface ImagesField<Fields = undefined> extends LinksField<EntryReference & ListRow & InferStoredValue<Fields>, ImageLink<Type.Infer<Fields>>> {
51
+ export interface ImagesField<Fields = undefined> extends LinksField<EntryReference & ListRow & InferStoredValue<Fields>, ImageLink<LinkFields<Type.Infer<Fields>>>> {
52
52
  }
53
53
  export declare namespace image {
54
54
  interface ImagesOptions<Fields> extends LinkFieldOptions<Array<EntryReference & ListRow & InferStoredValue<Fields>>>, Omit<EntryPickerOptions<Fields>, 'label' | 'selection'> {
@@ -9,7 +9,7 @@ import type { EntryReference } from 'alinea/picker/entry/EntryReference';
9
9
  import { type UrlReference } from 'alinea/picker/url';
10
10
  import { EntryLink } from './EntryLink.js';
11
11
  import type { UrlLink } from './UrlLink.js';
12
- export type Link<InferredFields> = EntryLink<InferredFields> | UrlLink<InferredFields> | FileLink<InferredFields>;
12
+ export type Link<InferredFields = {}> = EntryLink<InferredFields> | UrlLink<InferredFields> | FileLink<InferredFields>;
13
13
  export interface LinkOptions<Definition, Row> extends LinkFieldOptions<Row>, EntryPickerConditions {
14
14
  fields?: Definition | Type<Definition>;
15
15
  }
@@ -7,6 +7,11 @@ import { Reference } from 'alinea/core/Reference';
7
7
  import { ListRow } from 'alinea/core/ListRow';
8
8
  import type { ReactNode } from 'react';
9
9
  /** Optional settings to configure a link field */
10
+ /**
11
+ * The extra fields of a queried link: a link without extra fields holds an
12
+ * empty object, which is also what the link types default to
13
+ */
14
+ export type LinkFields<InferredFields> = InferredFields extends undefined ? {} : InferredFields;
10
15
  export interface LinkFieldOptions<Value> extends FieldOptions<Value> {
11
16
  /**
12
17
  * Allow the same entry to be linked more than once.