alinea 2.0.0-preview.0 → 2.0.0-preview.2

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 (237) hide show
  1. package/dist/.init/content/pages/welcome.json +1 -1
  2. package/dist/LICENSES.md +134 -80
  3. package/dist/adapter/next/DevRemote.d.ts +3 -0
  4. package/dist/adapter/next/DevRemote.js +37 -0
  5. package/dist/adapter/next/ForwardCredentials.d.ts +1 -0
  6. package/dist/adapter/next/ForwardCredentials.js +17 -0
  7. package/dist/adapter/next/cms.js +86 -38
  8. package/dist/adapter/next/context.d.ts +1 -1
  9. package/dist/adapter/next/context.js +11 -3
  10. package/dist/adapter/next/handler.d.ts +2 -0
  11. package/dist/adapter/next/handler.js +23 -16
  12. package/dist/adapter/next/with-alinea.js +18 -16
  13. package/dist/backend/Handler.d.ts +14 -13
  14. package/dist/backend/Handler.js +70 -36
  15. package/dist/backend/resolver/ParsePreview.d.ts +8 -4
  16. package/dist/backend/resolver/ParsePreview.js +40 -43
  17. package/dist/backend/router/Router.d.ts +1 -0
  18. package/dist/backend/router/Router.js +21 -15
  19. package/dist/bundled.d.ts +369 -99
  20. package/dist/chunks/chunk-6UT4N4CO.js +919 -0
  21. package/dist/chunks/{chunk-LUBOGJCG.js → chunk-6V4TAD2N.js} +1 -1
  22. package/dist/chunks/{chunk-TL7ZW6BX.js → chunk-A3XXZBOQ.js} +2535 -2999
  23. package/dist/chunks/chunk-AC5ATYI3.js +1434 -0
  24. package/dist/chunks/{chunk-7ORQ7BYK.js → chunk-KMLLLZ6X.js} +202 -269
  25. package/dist/chunks/{chunk-IWN3T3FL.js → chunk-O7XWTMCB.js} +1 -1
  26. package/dist/chunks/{chunk-53DZYORR.js → chunk-PAYSVIYI.js} +76 -176
  27. package/dist/chunks/{chunk-YK3OSMDM.js → chunk-S4AU6SRS.js} +188 -158
  28. package/dist/chunks/{chunk-EQ3TDHYD.js → chunk-UVOEM4AH.js} +6 -3
  29. package/dist/chunks/{chunk-I7X64JTZ.js → chunk-VXZM6V4P.js} +4 -4
  30. package/dist/cli/Generate.js +3 -13
  31. package/dist/cli/Serve.js +7 -3
  32. package/dist/cli/bin.js +8 -5
  33. package/dist/cli/generate/CompileConfig.js +3 -2
  34. package/dist/cli/generate/CopyStaticFiles.js +2 -3
  35. package/dist/cli/generate/DevDB.d.ts +1 -1
  36. package/dist/cli/generate/DevDB.js +3 -5
  37. package/dist/cli/serve/CreateLocalServer.d.ts +1 -1
  38. package/dist/cli/serve/CreateLocalServer.js +3 -2
  39. package/dist/cli/serve/DevServer.d.ts +3 -2
  40. package/dist/cli/serve/DevServer.js +60 -3
  41. package/dist/cli/serve/ServeContext.d.ts +1 -0
  42. package/dist/cli/serve/StartServer.d.ts +1 -0
  43. package/dist/cli/serve/StartServer.js +6 -1
  44. package/dist/cli/util/EnsureLibs.js +2 -2
  45. package/dist/cli/util/EnsureNode.js +2 -2
  46. package/dist/cloud/CloudRemote.d.ts +2 -1
  47. package/dist/cloud/CloudRemote.js +3 -2
  48. package/dist/components/Breadcrumbs.js +8 -8
  49. package/dist/components/Button.js +6 -6
  50. package/dist/components/Calendar.js +11 -11
  51. package/dist/components/Checkbox.js +7 -7
  52. package/dist/components/CheckboxGroup.js +6 -6
  53. package/dist/components/ColorSwatch.js +6 -6
  54. package/dist/components/ColorSwatchPicker.js +6 -6
  55. package/dist/components/ComboBox.js +17 -17
  56. package/dist/components/DateField.js +9 -9
  57. package/dist/components/DatePicker.js +10 -10
  58. package/dist/components/DateRangePicker.js +14 -14
  59. package/dist/components/Dialog.js +6 -6
  60. package/dist/components/Disclosure.js +13 -13
  61. package/dist/components/DropZone.js +6 -6
  62. package/dist/components/Label.js +16 -16
  63. package/dist/components/Link.js +6 -6
  64. package/dist/components/List.js +34 -34
  65. package/dist/components/Menu.js +10 -10
  66. package/dist/components/Modal.js +8 -8
  67. package/dist/components/MultipleSelect.js +33 -33
  68. package/dist/components/NumberField.d.ts +2 -1
  69. package/dist/components/NumberField.js +21 -11
  70. package/dist/components/Popover.js +6 -6
  71. package/dist/components/ProgressCircle.js +10 -10
  72. package/dist/components/RadioGroup.js +6 -6
  73. package/dist/components/SearchField.js +11 -11
  74. package/dist/components/Select.js +13 -13
  75. package/dist/components/Surface.js +3 -3
  76. package/dist/components/Switch.js +6 -6
  77. package/dist/components/Table.js +13 -13
  78. package/dist/components/Tabs.js +8 -8
  79. package/dist/components/TagGroup.js +7 -7
  80. package/dist/components/TextField.js +10 -10
  81. package/dist/components/TimeField.js +6 -6
  82. package/dist/components/Toggle.js +6 -6
  83. package/dist/components/Toolbar.js +7 -7
  84. package/dist/components/Tooltip.js +10 -10
  85. package/dist/components/Tree.js +9 -9
  86. package/dist/core/BlobTransport.d.ts +5 -0
  87. package/dist/core/BlobTransport.js +79 -0
  88. package/dist/core/Client.d.ts +2 -1
  89. package/dist/core/Client.js +17 -12
  90. package/dist/core/Config.d.ts +4 -0
  91. package/dist/core/Config.js +6 -0
  92. package/dist/core/Connection.d.ts +4 -3
  93. package/dist/core/Connection.js +7 -0
  94. package/dist/core/Graph.d.ts +3 -4
  95. package/dist/core/ListRow.d.ts +2 -0
  96. package/dist/core/OrderBy.d.ts +7 -3
  97. package/dist/core/TextDoc.d.ts +11 -0
  98. package/dist/core/Trace.d.ts +8 -0
  99. package/dist/core/Trace.js +32 -0
  100. package/dist/core/Type.d.ts +7 -1
  101. package/dist/core/db/CommitRequest.d.ts +0 -3
  102. package/dist/core/db/CommitRequest.js +0 -9
  103. package/dist/core/db/EntryDB.js +1 -1
  104. package/dist/core/db/EntryIndex.d.ts +12 -2
  105. package/dist/core/db/EntryIndex.js +131 -22
  106. package/dist/core/db/EntryResolver.js +104 -29
  107. package/dist/core/db/EntryTransaction.d.ts +1 -2
  108. package/dist/core/db/EntryTransaction.js +29 -22
  109. package/dist/core/db/LocalDB.d.ts +5 -5
  110. package/dist/core/db/LocalDB.js +27 -12
  111. package/dist/core/field/RichTextField.d.ts +30 -3
  112. package/dist/core/field/RichTextField.js +124 -56
  113. package/dist/core/media/MediaAltField.d.ts +1 -0
  114. package/dist/core/media/MediaAltField.js +9 -1
  115. package/dist/core/media/MediaLocation.d.ts +5 -2
  116. package/dist/core/media/MediaLocation.js +6 -7
  117. package/dist/core/media/MediaTypes.js +11 -0
  118. package/dist/core/source/CombinedSource.d.ts +2 -2
  119. package/dist/core/source/CombinedSource.js +6 -3
  120. package/dist/core/source/FSSource.d.ts +4 -3
  121. package/dist/core/source/FSSource.js +59 -27
  122. package/dist/core/source/GithubSource.d.ts +2 -2
  123. package/dist/core/source/GithubSource.js +21 -9
  124. package/dist/core/source/IndexedDBSource.d.ts +2 -2
  125. package/dist/core/source/IndexedDBSource.js +3 -1
  126. package/dist/core/source/MemorySource.d.ts +2 -2
  127. package/dist/core/source/MemorySource.js +3 -1
  128. package/dist/core/source/OverlaySource.d.ts +12 -0
  129. package/dist/core/source/OverlaySource.js +50 -0
  130. package/dist/core/source/Source.d.ts +5 -2
  131. package/dist/core/source/Source.js +3 -3
  132. package/dist/core/util/Async.d.ts +8 -2
  133. package/dist/core/util/Async.js +67 -0
  134. package/dist/core/util/EntryFilenames.d.ts +2 -2
  135. package/dist/core/util/EntryFilenames.js +3 -3
  136. package/dist/dashboard/App.css +158 -0
  137. package/dist/dashboard/App.js +2 -2
  138. package/dist/dashboard/app/AccessDenied.js +3 -3
  139. package/dist/dashboard/app/ActivityStatus.js +15 -15
  140. package/dist/dashboard/app/AppShell.js +1 -1
  141. package/dist/dashboard/app/AuthView.js +11 -11
  142. package/dist/dashboard/app/CompactField.js +10 -10
  143. package/dist/dashboard/app/DashboardErrorBoundary.js +5 -5
  144. package/dist/dashboard/app/DashboardLayout.js +22 -19
  145. package/dist/dashboard/app/EntryHeader.js +12 -12
  146. package/dist/dashboard/app/EntryReferences.js +9 -9
  147. package/dist/dashboard/app/EntrySidebar.d.ts +1 -1
  148. package/dist/dashboard/app/EntrySidebar.js +17 -16
  149. package/dist/dashboard/app/EntrySidebarPreview.d.ts +1 -1
  150. package/dist/dashboard/app/EntrySidebarPreview.js +19 -14
  151. package/dist/dashboard/app/EntryTranslationBanner.js +7 -7
  152. package/dist/dashboard/app/Explorer.js +51 -43
  153. package/dist/dashboard/app/ExplorerCards.js +34 -34
  154. package/dist/dashboard/app/ExplorerFileCard.js +18 -18
  155. package/dist/dashboard/app/ExplorerList.js +13 -13
  156. package/dist/dashboard/app/ExplorerModal.js +3 -3
  157. package/dist/dashboard/app/ExplorerTable.js +76 -61
  158. package/dist/dashboard/app/ExternalLinkPicker.js +15 -4
  159. package/dist/dashboard/app/LinkPicker.js +8 -8
  160. package/dist/dashboard/app/LocaleMenu.js +12 -12
  161. package/dist/dashboard/app/SidebarLayout.d.ts +8 -0
  162. package/dist/dashboard/app/SidebarLayout.js +1169 -0
  163. package/dist/dashboard/app/SidebarTree.js +46 -46
  164. package/dist/dashboard/app/WorkspaceMenu.js +17 -17
  165. package/dist/dashboard/app/WorkspaceRoots.js +23 -23
  166. package/dist/dashboard/app/editor/FileEditor.d.ts +2 -1
  167. package/dist/dashboard/app/editor/FileEditor.js +41 -32
  168. package/dist/dashboard/app/editor/FilePreview.js +4 -4
  169. package/dist/dashboard/app/editor/MediaAltField.view.d.ts +1 -1
  170. package/dist/dashboard/app/editor/MediaAltField.view.js +6 -9
  171. package/dist/dashboard/app/modals/CreateEntry.js +4 -4
  172. package/dist/dashboard/app/pages/EntryPage.js +57 -31
  173. package/dist/dashboard/app/pages/UsersPage.js +33 -33
  174. package/dist/dashboard/app/ui/DashboardModal.js +23 -23
  175. package/dist/dashboard/app/ui/Rail.js +3 -3
  176. package/dist/dashboard/app/ui/Sidebar.js +2 -2
  177. package/dist/dashboard/atoms/auth.js +2 -0
  178. package/dist/dashboard/atoms/dashboard.d.ts +9 -0
  179. package/dist/dashboard/atoms/dashboard.js +17 -0
  180. package/dist/dashboard/atoms/editor.d.ts +7 -1
  181. package/dist/dashboard/atoms/editor.js +4 -1
  182. package/dist/dashboard/atoms/entry.d.ts +48 -2
  183. package/dist/dashboard/atoms/entry.js +222 -17
  184. package/dist/dashboard/atoms/explorer.js +4 -9
  185. package/dist/dashboard/atoms/preview.d.ts +3 -0
  186. package/dist/dashboard/atoms/preview.js +18 -1
  187. package/dist/dashboard/atoms/root.d.ts +4 -1
  188. package/dist/dashboard/atoms/root.js +96 -157
  189. package/dist/dashboard/hooks.d.ts +4 -2
  190. package/dist/dashboard/hooks.js +9 -5
  191. package/dist/dashboard/icons.d.ts +1 -0
  192. package/dist/dashboard/icons.js +10 -0
  193. package/dist/field/check/CheckField.view.js +2 -2
  194. package/dist/field/code/CodeField.view.js +12 -12
  195. package/dist/field/date/DateField.view.js +12 -2
  196. package/dist/field/link/FileLink.d.ts +2 -2
  197. package/dist/field/link/FileLink.js +5 -3
  198. package/dist/field/link/ImageLink.d.ts +1 -1
  199. package/dist/field/link/ImageLink.js +1 -1
  200. package/dist/field/link/Link.js +2 -2
  201. package/dist/field/link/LinkField.view.js +155 -128
  202. package/dist/field/list/ListField.view.js +22 -33
  203. package/dist/field/metadata/MetadataField.view.js +19 -19
  204. package/dist/field/number/NumberField.d.ts +2 -0
  205. package/dist/field/number/NumberField.view.js +4 -2
  206. package/dist/field/richtext/PickTextLink.d.ts +7 -0
  207. package/dist/field/richtext/PickTextLink.js +104 -2
  208. package/dist/field/richtext/ReferenceLink.d.ts +4 -1
  209. package/dist/field/richtext/ReferenceLink.js +18 -4
  210. package/dist/field/richtext/RichTextDocument.d.ts +7 -2
  211. package/dist/field/richtext/RichTextDocument.js +34 -5
  212. package/dist/field/richtext/RichTextExtensions.d.ts +3 -1
  213. package/dist/field/richtext/RichTextExtensions.js +2704 -7467
  214. package/dist/field/richtext/RichTextField.d.ts +4 -0
  215. package/dist/field/richtext/RichTextField.story.d.ts +4 -0
  216. package/dist/field/richtext/RichTextField.view.js +43 -20
  217. package/dist/field/richtext/RichTextInsertMenu.js +281 -495
  218. package/dist/field/richtext/RichTextToolbar.d.ts +5 -2
  219. package/dist/field/richtext/RichTextToolbar.js +38 -3
  220. package/dist/field/richtext/Toolbar.d.ts +19 -1
  221. package/dist/field/richtext/Toolbar.js +18 -13
  222. package/dist/field/richtext/extensions/Anchor.js +1 -1
  223. package/dist/field/richtext/extensions/Link.js +1 -1
  224. package/dist/field/richtext/extensions/Small.js +1 -1
  225. package/dist/field/select/SelectField.view.js +8 -6
  226. package/dist/index.css +227 -16
  227. package/dist/next.cjs +18 -16
  228. package/dist/next.d.ts +2 -1
  229. package/dist/next.edge.d.ts +2 -1
  230. package/dist/picker/entry/EntryPicker.js +9 -35
  231. package/dist/preview/PreviewPayload.js +35 -250
  232. package/dist/ui/RichText.d.ts +1 -0
  233. package/dist/ui/RichText.js +29 -2
  234. package/package.json +6 -3
  235. package/dist/cli/util/ExternalPlugin.d.ts +0 -2
  236. package/dist/cli/util/ExternalPlugin.js +0 -919
  237. package/dist/chunks/{chunk-JFROOUG6.js → chunk-NIVGVRDS.js} +17 -17
@@ -11,8 +11,10 @@ import { JsonLoader } from "alinea/backend/loader/JsonLoader";
11
11
  import { Config } from "alinea/core/Config";
12
12
  import { Entry } from "alinea/core/Entry";
13
13
  import { createRecord, parseRecord } from "alinea/core/EntryRecord";
14
- import { getRoot, getWorkspace } from "alinea/core/Internal";
14
+ import { getRoot, getType, getWorkspace } from "alinea/core/Internal";
15
15
  import { createPreview } from "alinea/core/media/CreatePreview.browser";
16
+ import { mediaAltText } from "alinea/core/media/MediaAltField";
17
+ import { MediaFile } from "alinea/core/media/MediaTypes";
16
18
  import { Permission } from "alinea/core/Role";
17
19
  import { Root } from "alinea/core/Root";
18
20
  import { createFilePatch } from "alinea/core/source/FilePatch";
@@ -24,9 +26,10 @@ import { encodePreviewPayload } from "alinea/preview/PreviewPayload";
24
26
  import { parents, translations } from "alinea/query";
25
27
  import { clientAtom, configAtom, graphAtom } from "./core.js";
26
28
  import { entryRevisionAtom, shaAtom } from "./graph.js";
29
+ import { getPreviewToken, retryPreviewToken } from "./preview.js";
27
30
  import { ReactiveNode } from "./ReactiveNode.js";
28
31
  import { policyAtom, userAtom } from "./user.js";
29
- import { dispense, loader } from "./utils.js";
32
+ import { atomWithPending, dispense, loader } from "./utils.js";
30
33
  var selection = {
31
34
  id: Entry.id,
32
35
  type: Entry.type,
@@ -166,6 +169,46 @@ var EntryLocaleAtoms = class {
166
169
  });
167
170
  return new ReactiveNode(value, readOnly);
168
171
  });
172
+ richTextImages = atom(async (get) => {
173
+ const entry = await get(this.selectedEntry);
174
+ const config = get(configAtom);
175
+ const type = config.schema[entry.type];
176
+ assert(type, `Type "${entry.type}" not found in config`);
177
+ const value = Type.withInitialValue(type, {
178
+ ...Type.initialValue(type),
179
+ ...entry.data
180
+ });
181
+ const imageIds = Array.from(
182
+ new Set(
183
+ Type.references(type, value).filter((reference) => reference.linkType === "image").map((reference) => reference.targetId)
184
+ )
185
+ );
186
+ if (imageIds.length === 0) return /* @__PURE__ */ new Map();
187
+ const graph = get(graphAtom);
188
+ const images = await graph.find({
189
+ id: { in: imageIds },
190
+ preferredLocale: this.requestedLocale ?? entry.locale ?? void 0,
191
+ status: "preferDraft",
192
+ select: {
193
+ id: Entry.id,
194
+ url: Entry.url,
195
+ alt: MediaFile.alt
196
+ }
197
+ });
198
+ const baseUrl = Config.baseUrl(config) ?? (typeof location === "undefined" ? void 0 : location.href);
199
+ return new Map(
200
+ images.map((image) => [
201
+ image.id,
202
+ {
203
+ src: URL.parse(image.url, baseUrl)?.href ?? "",
204
+ alt: mediaAltText(
205
+ image.alt,
206
+ this.requestedLocale ?? entry.locale ?? void 0
207
+ )
208
+ }
209
+ ])
210
+ );
211
+ });
169
212
  anchors = atom(async (get) => {
170
213
  const entry = await get(this.selectedEntry);
171
214
  const node = await get(this.selectedNode);
@@ -173,9 +216,10 @@ var EntryLocaleAtoms = class {
173
216
  assert(type, `Type "${entry.type}" not found in config`);
174
217
  return Type.anchors(type, get(node.value));
175
218
  });
176
- #previewRetry = atom(0);
219
+ #previewUrlRetry = atom(0);
177
220
  retryPreviewUrl = atom(null, (get, set) => {
178
- set(this.#previewRetry, (current) => current + 1);
221
+ retryPreviewToken(get(clientAtom));
222
+ set(this.#previewUrlRetry, (current) => current + 1);
179
223
  });
180
224
  previewEntryReady = atom(async (get) => {
181
225
  const activeEntry = await get(this.selectedEntry);
@@ -189,31 +233,27 @@ var EntryLocaleAtoms = class {
189
233
  };
190
234
  });
191
235
  previewEntry = unwrap(this.previewEntryReady, (previous) => previous);
192
- #previewTargetUrl = atom((get) => {
193
- const versions = get(this.versions);
194
- const entry = Array.from(versions.values()).find((version) => version.active) ?? versions.values().next().value;
195
- return entry?.url;
196
- });
197
236
  previewUrlReady = atom(async (get) => {
198
- get(this.#previewRetry);
199
- const targetUrl = get(this.#previewTargetUrl);
237
+ get(this.#previewUrlRetry);
238
+ const versions = get(this.versions);
239
+ const targetUrl = Array.from(versions.values()).find((version) => version.active)?.url ?? versions.values().next().value?.url;
200
240
  if (!targetUrl) return void 0;
201
241
  const config = get(configAtom);
202
- const client = get(clientAtom);
203
- if (typeof client.previewToken !== "function") return void 0;
204
242
  try {
205
243
  const base = new URL(
206
- config.handlerUrl ?? "",
244
+ Config.handlerUrl(config),
207
245
  Config.baseUrl(config) ?? (typeof location === "undefined" ? "http://localhost" : location.href)
208
246
  );
209
- base.searchParams.set("preview", await client.previewToken());
247
+ const previewToken = await getPreviewToken(get(clientAtom));
248
+ if (!previewToken) return void 0;
249
+ base.searchParams.set("preview", previewToken);
210
250
  base.searchParams.set("returnTo", targetUrl);
211
251
  return base.toString();
212
252
  } catch {
213
253
  return void 0;
214
254
  }
215
255
  });
216
- previewUrl = unwrap(this.previewUrlReady, (previous) => previous);
256
+ previewUrlState = atomWithPending(this.previewUrlReady);
217
257
  previewPayloadSignal = atom((get) => {
218
258
  const version = get(this.selectedVersion);
219
259
  const editing = get(this.currentlyEditing);
@@ -501,6 +541,9 @@ var EntryAtoms = class {
501
541
  parentId = atom((get) => get(this.data).parentId);
502
542
  workspace = atom((get) => get(this.data).workspace);
503
543
  root = atom((get) => get(this.data).root);
544
+ parentPaths = atom(
545
+ (get) => get(this.data).parents.filter((parent) => parent.main).map((parent) => parent.path)
546
+ );
504
547
  hasChildren = atom((get) => get(this.data).hasChildren);
505
548
  canPublishParents = atom(
506
549
  (get) => get(this.data).parents.every((parent) => parent.status === "published")
@@ -601,9 +644,171 @@ var MissingEntryError = class extends Error {
601
644
  }
602
645
  id;
603
646
  };
647
+ var treeEntrySelect = {
648
+ id: Entry.id,
649
+ title: Entry.title,
650
+ type: Entry.type,
651
+ status: Entry.status,
652
+ main: Entry.main,
653
+ locale: Entry.locale,
654
+ parentId: Entry.parentId,
655
+ parents: Entry.parents,
656
+ workspace: Entry.workspace,
657
+ root: Entry.root
658
+ };
659
+ var treeChildSelect = {
660
+ id: Entry.id,
661
+ type: Entry.type,
662
+ locale: Entry.locale,
663
+ parentId: Entry.parentId,
664
+ parents: Entry.parents,
665
+ workspace: Entry.workspace,
666
+ root: Entry.root
667
+ };
668
+ function preferredTreeEntries(items, locale) {
669
+ const translated = new Set(
670
+ items.filter((item) => item.locale === locale).map((item) => item.id)
671
+ );
672
+ const untranslated = /* @__PURE__ */ new Set();
673
+ return items.filter((item) => {
674
+ if (translated.has(item.id)) return item.locale === locale;
675
+ if (untranslated.has(item.id)) return false;
676
+ untranslated.add(item.id);
677
+ return true;
678
+ });
679
+ }
680
+ async function loadTreeChildren(get, location2, locale, orderBy) {
681
+ const config = get(configAtom);
682
+ const graph = get(graphAtom);
683
+ const policy = get(policyAtom);
684
+ const visibleTypes = entries(config.schema).filter(([, type]) => !Type.isHidden(type)).map(([name]) => name);
685
+ const matches = await graph.find({
686
+ ...location2,
687
+ filter: { _type: { in: visibleTypes } },
688
+ orderBy,
689
+ select: treeChildSelect,
690
+ status: "preferDraft"
691
+ });
692
+ return preferredTreeEntries(
693
+ matches.filter((entry) => policy.canRead(entry)),
694
+ locale
695
+ ).map((entry) => treeEntryAtoms(entry.id));
696
+ }
697
+ var treeEntryLoader = atom((get) => {
698
+ const config = get(configAtom);
699
+ const graph = get(graphAtom);
700
+ const policy = get(policyAtom);
701
+ const visibleTypes = entries(config.schema).filter(([, type]) => !Type.isHidden(type)).map(([name]) => name);
702
+ return loader(async (ids) => {
703
+ const [rows, children] = await Promise.all([
704
+ graph.find({
705
+ id: { in: ids },
706
+ select: treeEntrySelect,
707
+ status: "preferDraft"
708
+ }),
709
+ graph.find({
710
+ filter: { _type: { in: visibleTypes } },
711
+ parentId: { in: ids },
712
+ select: treeChildSelect,
713
+ status: "preferDraft"
714
+ })
715
+ ]);
716
+ const entriesById = /* @__PURE__ */ new Map();
717
+ for (const entry of rows) {
718
+ const versions = entriesById.get(entry.id) ?? [];
719
+ versions.push(entry);
720
+ entriesById.set(entry.id, versions);
721
+ }
722
+ const parentsWithChildren = new Set(
723
+ children.filter((child) => policy.canRead(child)).flatMap((child) => child.parentId ? [child.parentId] : [])
724
+ );
725
+ return ids.map((id) => {
726
+ const entryVersions = entriesById.get(id);
727
+ if (!entryVersions) return [null, new MissingEntryError(id)];
728
+ return [
729
+ {
730
+ entries: entryVersions,
731
+ hasChildren: parentsWithChildren.has(id)
732
+ },
733
+ null
734
+ ];
735
+ });
736
+ });
737
+ });
738
+ var TreeEntryAtoms = class {
739
+ constructor(id) {
740
+ this.id = id;
741
+ }
742
+ id;
743
+ #data = atom(async (get) => {
744
+ get(entryRevisionAtom(this.id));
745
+ const [data, error] = await get(treeEntryLoader)(this.id);
746
+ if (error) throw error;
747
+ assert(data, `Tree entry "${this.id}" not found`);
748
+ return data;
749
+ });
750
+ ready = atom(async (get) => {
751
+ await get(this.#data);
752
+ return this;
753
+ });
754
+ raw = dispense(
755
+ (locale) => atom(async (get) => {
756
+ const data = await get(this.#data);
757
+ const entry = preferredTreeEntries(data.entries, locale)[0];
758
+ assert(entry, `Tree entry "${this.id}" has no versions`);
759
+ return entry;
760
+ })
761
+ );
762
+ summary = dispense(
763
+ (locale) => atom(async (get) => {
764
+ const data = await get(this.#data);
765
+ const config = get(configAtom);
766
+ const policy = get(policyAtom);
767
+ const entry = preferredTreeEntries(
768
+ data.entries.filter((candidate) => {
769
+ const type = config.schema[candidate.type];
770
+ return Boolean(
771
+ type && !Type.isHidden(type) && policy.canRead(candidate)
772
+ );
773
+ }),
774
+ locale
775
+ )[0];
776
+ if (!entry) throw new MissingEntryError(this.id);
777
+ return { ...entry, hasChildren: data.hasChildren };
778
+ })
779
+ );
780
+ parents = atom(async (get) => {
781
+ const entry = await get(this.raw(null));
782
+ const models = entry.parents.map(treeEntryAtoms);
783
+ await Promise.all(models.map((model) => get(model.ready)));
784
+ return models;
785
+ });
786
+ children = dispense(
787
+ (locale) => atom(async (get) => {
788
+ get(shaAtom);
789
+ const entry = await get(this.raw(locale));
790
+ const type = get(configAtom).schema[entry.type];
791
+ assert(type, `Type "${entry.type}" not found in config`);
792
+ return loadTreeChildren(
793
+ get,
794
+ {
795
+ workspace: entry.workspace,
796
+ root: entry.root,
797
+ parentId: this.id
798
+ },
799
+ locale,
800
+ getType(type).orderChildrenBy
801
+ );
802
+ })
803
+ );
804
+ };
805
+ var treeEntryAtoms = dispense((id) => new TreeEntryAtoms(id));
604
806
  export {
605
807
  EntryAtoms,
606
808
  EntryLocaleAtoms,
607
809
  MissingEntryError,
608
- entryAtoms
810
+ TreeEntryAtoms,
811
+ entryAtoms,
812
+ loadTreeChildren,
813
+ treeEntryAtoms
609
814
  };
@@ -354,7 +354,7 @@ var ExplorerAtoms = class {
354
354
  );
355
355
  sort = atom(
356
356
  (get) => get(this.#selectedSort) ?? {
357
- sortBy: get(this.isMedia) ? "title" : "index",
357
+ sortBy: "index",
358
358
  direction: "asc"
359
359
  },
360
360
  (get, set, sortBy) => {
@@ -496,6 +496,7 @@ var ExplorerAtoms = class {
496
496
  const graph = get(graphAtom);
497
497
  const sort = get(this.sort);
498
498
  const filter = get(this.filter);
499
+ const orderField = sort.sortBy === "title" ? Entry.title : sort.sortBy === "path" ? Entry.path : sort.sortBy === "size" ? MediaFile.size : sort.sortBy === "id" ? Entry.id : Entry.index;
499
500
  const entries = await graph.find({
500
501
  workspace: entry.workspace,
501
502
  root: entry.root,
@@ -505,10 +506,7 @@ var ExplorerAtoms = class {
505
506
  type: filter,
506
507
  status: "preferDraft",
507
508
  groupBy: Entry.id,
508
- orderBy: {
509
- [sort.direction]: sort.sortBy === "title" ? Entry.title : sort.sortBy === "path" ? Entry.path : sort.sortBy === "size" ? MediaFile.size : sort.sortBy === "id" ? Entry.id : Entry.index,
510
- caseSensitive: sort.sortBy !== "id"
511
- },
509
+ orderBy: sort.direction === "asc" ? { asc: orderField, caseSensitive: sort.sortBy !== "id" } : { desc: orderField, caseSensitive: sort.sortBy !== "id" },
512
510
  select: {
513
511
  active: Entry.active,
514
512
  createdAt: Entry.createdAt,
@@ -596,10 +594,7 @@ var ExplorerAtoms = class {
596
594
  type: filter,
597
595
  status: "preferDraft",
598
596
  groupBy: Entry.id,
599
- orderBy: search ? void 0 : selectedSort === void 0 && defaultOrderBy !== void 0 ? defaultOrderBy : {
600
- [sort.direction]: orderField,
601
- caseSensitive: sort.sortBy !== "id"
602
- },
597
+ orderBy: search ? void 0 : selectedSort === void 0 && defaultOrderBy !== void 0 ? defaultOrderBy : sort.direction === "asc" ? { asc: orderField, caseSensitive: sort.sortBy !== "id" } : { desc: orderField, caseSensitive: sort.sortBy !== "id" },
603
598
  select: {
604
599
  active: Entry.active,
605
600
  createdAt: Entry.createdAt,
@@ -1,4 +1,7 @@
1
+ import type { LocalConnection } from 'alinea/core/Connection';
1
2
  import type { PreviewMetadata } from 'alinea/core/Preview';
3
+ export declare function getPreviewToken(client: LocalConnection): Promise<string | undefined>;
4
+ export declare function retryPreviewToken(client: LocalConnection): void;
2
5
  export declare const previewMetadataAtom: import("jotai").PrimitiveAtom<PreviewMetadata | undefined> & {
3
6
  init: PreviewMetadata | undefined;
4
7
  };
@@ -4,7 +4,24 @@ import {
4
4
  import "../../chunks/chunk-CQ52GEHY.js";
5
5
 
6
6
  // src/dashboard/atoms/preview.ts
7
+ var previewTokens = /* @__PURE__ */ new WeakMap();
8
+ function getPreviewToken(client) {
9
+ const current = previewTokens.get(client);
10
+ if (current) return current;
11
+ const request = typeof client.previewToken === "function" ? client.previewToken() : Promise.resolve(void 0);
12
+ const token = request.catch((error) => {
13
+ if (previewTokens.get(client) === token) previewTokens.delete(client);
14
+ throw error;
15
+ });
16
+ previewTokens.set(client, token);
17
+ return token;
18
+ }
19
+ function retryPreviewToken(client) {
20
+ previewTokens.delete(client);
21
+ }
7
22
  var previewMetadataAtom = atom(void 0);
8
23
  export {
9
- previewMetadataAtom
24
+ getPreviewToken,
25
+ previewMetadataAtom,
26
+ retryPreviewToken
10
27
  };
@@ -1,4 +1,4 @@
1
- import { type EntryStatus } from 'alinea/core/Entry';
1
+ import type { EntryStatus } from 'alinea/core/Entry';
2
2
  import type { RootData, RootI18n } from 'alinea/core/Root';
3
3
  import type { DragItem, DragTypes, DropOperation, DropTarget } from '@react-types/shared';
4
4
  import { type ExplorerAtoms } from 'alinea/dashboard/atoms/explorer';
@@ -6,6 +6,7 @@ import { type Atom, type PrimitiveAtom } from 'jotai';
6
6
  import type { ComponentType } from 'react';
7
7
  import type { DroppableCollectionInsertDropEvent, DroppableCollectionOnItemDropEvent, DroppableCollectionReorderEvent, Key } from 'react-aria-components';
8
8
  import { LucideFile } from '../icons.js';
9
+ import { type TreeEntryAtoms } from './entry.js';
9
10
  export interface RootViewProps {
10
11
  root: RootData;
11
12
  }
@@ -45,6 +46,7 @@ export declare class TreeAtoms {
45
46
  constructor(root: RootAtoms, locale: string | null, selectedKeys: Atom<Set<Key>>, viewState?: TreeViewState);
46
47
  snapshot: Atom<TreeSnapshot>;
47
48
  items: Atom<RootTreeItem[]>;
49
+ children: (id: string) => Atom<Promise<TreeEntryAtoms[]>>;
48
50
  item: (id: string) => Atom<RootTreeItem>;
49
51
  selectedItem: Atom<RootTreeItem | undefined>;
50
52
  ready: Atom<Promise<{
@@ -62,6 +64,7 @@ export declare class RootAtoms {
62
64
  explorer: ExplorerAtoms;
63
65
  constructor(workspace: string, key: string);
64
66
  createTree(locale: string | null, selectedKeys: Atom<Set<Key>>, expandedKeys?: PrimitiveAtom<Set<string>>): TreeAtoms;
67
+ treeEntries: (locale: string | null) => Atom<Promise<TreeEntryAtoms[]>>;
65
68
  children: (parentId: string | null) => ExplorerAtoms;
66
69
  label: Atom<string>;
67
70
  icon: Atom<typeof LucideFile | ComponentType>;