alinea 2.0.0-preview.1 → 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 (201) hide show
  1. package/dist/.init/content/pages/welcome.json +1 -1
  2. package/dist/LICENSES.md +61 -34
  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 +53 -22
  15. package/dist/backend/resolver/ParsePreview.d.ts +8 -4
  16. package/dist/backend/resolver/ParsePreview.js +40 -43
  17. package/dist/bundled.d.ts +255 -60
  18. package/dist/chunks/{chunk-LUBOGJCG.js → chunk-6V4TAD2N.js} +1 -1
  19. package/dist/chunks/{chunk-TL7ZW6BX.js → chunk-A3XXZBOQ.js} +2535 -2999
  20. package/dist/chunks/chunk-AC5ATYI3.js +1434 -0
  21. package/dist/chunks/{chunk-7ORQ7BYK.js → chunk-KMLLLZ6X.js} +202 -269
  22. package/dist/chunks/{chunk-IWN3T3FL.js → chunk-O7XWTMCB.js} +1 -1
  23. package/dist/chunks/{chunk-53DZYORR.js → chunk-PAYSVIYI.js} +76 -176
  24. package/dist/chunks/{chunk-YK3OSMDM.js → chunk-S4AU6SRS.js} +188 -158
  25. package/dist/chunks/{chunk-FRYHNUEK.js → chunk-UVOEM4AH.js} +6 -3
  26. package/dist/chunks/{chunk-I7X64JTZ.js → chunk-VXZM6V4P.js} +4 -4
  27. package/dist/cli/Generate.js +3 -13
  28. package/dist/cli/Serve.js +7 -3
  29. package/dist/cli/bin.js +8 -5
  30. package/dist/cli/generate/CopyStaticFiles.js +2 -3
  31. package/dist/cli/generate/DevDB.d.ts +1 -1
  32. package/dist/cli/generate/DevDB.js +3 -5
  33. package/dist/cli/serve/CreateLocalServer.d.ts +1 -1
  34. package/dist/cli/serve/CreateLocalServer.js +3 -2
  35. package/dist/cli/serve/DevServer.d.ts +3 -2
  36. package/dist/cli/serve/DevServer.js +60 -3
  37. package/dist/cli/serve/ServeContext.d.ts +1 -0
  38. package/dist/cli/serve/StartServer.d.ts +1 -0
  39. package/dist/cli/serve/StartServer.js +6 -1
  40. package/dist/cli/util/EnsureLibs.js +2 -2
  41. package/dist/cli/util/EnsureNode.js +2 -2
  42. package/dist/cloud/CloudRemote.js +1 -1
  43. package/dist/components/Breadcrumbs.js +8 -8
  44. package/dist/components/Button.js +6 -6
  45. package/dist/components/Calendar.js +9 -9
  46. package/dist/components/Checkbox.js +9 -9
  47. package/dist/components/CheckboxGroup.js +6 -6
  48. package/dist/components/ColorSwatch.js +6 -6
  49. package/dist/components/ColorSwatchPicker.js +6 -6
  50. package/dist/components/ComboBox.js +16 -16
  51. package/dist/components/DateField.js +9 -9
  52. package/dist/components/DatePicker.js +11 -11
  53. package/dist/components/DateRangePicker.js +14 -14
  54. package/dist/components/Dialog.js +6 -6
  55. package/dist/components/Disclosure.js +14 -14
  56. package/dist/components/DropZone.js +6 -6
  57. package/dist/components/Label.js +14 -14
  58. package/dist/components/Link.js +6 -6
  59. package/dist/components/List.js +32 -32
  60. package/dist/components/Menu.js +10 -10
  61. package/dist/components/Modal.js +8 -8
  62. package/dist/components/MultipleSelect.js +25 -25
  63. package/dist/components/NumberField.d.ts +2 -1
  64. package/dist/components/NumberField.js +25 -15
  65. package/dist/components/Popover.js +6 -6
  66. package/dist/components/ProgressCircle.js +9 -9
  67. package/dist/components/RadioGroup.js +8 -8
  68. package/dist/components/SearchField.js +15 -15
  69. package/dist/components/Select.js +14 -14
  70. package/dist/components/Surface.js +2 -2
  71. package/dist/components/Switch.js +8 -8
  72. package/dist/components/Table.js +14 -14
  73. package/dist/components/Tabs.js +7 -7
  74. package/dist/components/TagGroup.js +8 -8
  75. package/dist/components/TextField.js +10 -10
  76. package/dist/components/TimeField.js +8 -8
  77. package/dist/components/Toggle.js +8 -8
  78. package/dist/components/Toolbar.js +9 -9
  79. package/dist/components/Tooltip.js +7 -7
  80. package/dist/components/Tree.js +10 -10
  81. package/dist/core/Client.js +3 -2
  82. package/dist/core/Config.d.ts +4 -0
  83. package/dist/core/Config.js +6 -0
  84. package/dist/core/Connection.d.ts +2 -2
  85. package/dist/core/Connection.js +7 -0
  86. package/dist/core/Graph.d.ts +3 -4
  87. package/dist/core/ListRow.d.ts +2 -0
  88. package/dist/core/OrderBy.d.ts +7 -3
  89. package/dist/core/TextDoc.d.ts +11 -0
  90. package/dist/core/Trace.d.ts +8 -0
  91. package/dist/core/Trace.js +32 -0
  92. package/dist/core/db/CommitRequest.d.ts +0 -3
  93. package/dist/core/db/CommitRequest.js +0 -9
  94. package/dist/core/db/EntryDB.js +1 -1
  95. package/dist/core/db/EntryIndex.d.ts +10 -0
  96. package/dist/core/db/EntryIndex.js +117 -9
  97. package/dist/core/db/EntryResolver.js +104 -29
  98. package/dist/core/db/EntryTransaction.d.ts +1 -2
  99. package/dist/core/db/EntryTransaction.js +25 -13
  100. package/dist/core/db/LocalDB.d.ts +2 -3
  101. package/dist/core/db/LocalDB.js +24 -19
  102. package/dist/core/field/RichTextField.d.ts +30 -3
  103. package/dist/core/field/RichTextField.js +125 -41
  104. package/dist/core/media/MediaAltField.d.ts +1 -0
  105. package/dist/core/media/MediaAltField.js +9 -1
  106. package/dist/core/source/OverlaySource.d.ts +12 -0
  107. package/dist/core/source/OverlaySource.js +50 -0
  108. package/dist/core/source/Source.d.ts +1 -1
  109. package/dist/core/source/Source.js +3 -3
  110. package/dist/dashboard/App.css +158 -0
  111. package/dist/dashboard/App.js +3 -3
  112. package/dist/dashboard/app/AccessDenied.js +1 -1
  113. package/dist/dashboard/app/ActivityStatus.js +14 -14
  114. package/dist/dashboard/app/AppShell.js +2 -2
  115. package/dist/dashboard/app/AuthView.js +12 -12
  116. package/dist/dashboard/app/Badge.js +2 -2
  117. package/dist/dashboard/app/CompactField.js +13 -13
  118. package/dist/dashboard/app/DashboardErrorBoundary.js +6 -6
  119. package/dist/dashboard/app/DashboardLayout.js +22 -19
  120. package/dist/dashboard/app/EntryHeader.js +10 -10
  121. package/dist/dashboard/app/EntryReferences.js +9 -9
  122. package/dist/dashboard/app/EntrySidebar.d.ts +1 -1
  123. package/dist/dashboard/app/EntrySidebar.js +19 -18
  124. package/dist/dashboard/app/EntrySidebarPreview.d.ts +1 -1
  125. package/dist/dashboard/app/EntrySidebarPreview.js +20 -15
  126. package/dist/dashboard/app/EntryTranslationBanner.js +6 -6
  127. package/dist/dashboard/app/Explorer.js +46 -46
  128. package/dist/dashboard/app/ExplorerCards.js +42 -42
  129. package/dist/dashboard/app/ExplorerFileCard.js +16 -16
  130. package/dist/dashboard/app/ExplorerList.js +15 -15
  131. package/dist/dashboard/app/ExplorerModal.js +5 -5
  132. package/dist/dashboard/app/ExplorerTable.js +54 -54
  133. package/dist/dashboard/app/ExternalLinkPicker.js +15 -4
  134. package/dist/dashboard/app/LinkPicker.js +6 -6
  135. package/dist/dashboard/app/LocaleMenu.js +11 -11
  136. package/dist/dashboard/app/SidebarLayout.d.ts +8 -0
  137. package/dist/dashboard/app/SidebarLayout.js +1169 -0
  138. package/dist/dashboard/app/SidebarTree.js +44 -44
  139. package/dist/dashboard/app/WorkspaceMenu.js +17 -17
  140. package/dist/dashboard/app/WorkspaceRoots.js +26 -26
  141. package/dist/dashboard/app/editor/FileEditor.js +28 -29
  142. package/dist/dashboard/app/editor/FilePreview.js +2 -2
  143. package/dist/dashboard/app/editor/MediaAltField.view.d.ts +1 -1
  144. package/dist/dashboard/app/editor/MediaAltField.view.js +6 -9
  145. package/dist/dashboard/app/modals/CreateEntry.js +4 -4
  146. package/dist/dashboard/app/pages/EntryPage.js +49 -25
  147. package/dist/dashboard/app/pages/UsersPage.js +38 -38
  148. package/dist/dashboard/app/ui/DashboardModal.js +22 -22
  149. package/dist/dashboard/app/ui/Rail.js +2 -2
  150. package/dist/dashboard/app/ui/Sidebar.js +2 -2
  151. package/dist/dashboard/atoms/auth.js +2 -0
  152. package/dist/dashboard/atoms/dashboard.d.ts +9 -0
  153. package/dist/dashboard/atoms/dashboard.js +17 -0
  154. package/dist/dashboard/atoms/editor.d.ts +7 -1
  155. package/dist/dashboard/atoms/editor.js +4 -1
  156. package/dist/dashboard/atoms/entry.d.ts +3 -1
  157. package/dist/dashboard/atoms/entry.js +55 -15
  158. package/dist/dashboard/atoms/explorer.js +3 -8
  159. package/dist/dashboard/atoms/preview.d.ts +3 -0
  160. package/dist/dashboard/atoms/preview.js +18 -1
  161. package/dist/dashboard/hooks.d.ts +4 -2
  162. package/dist/dashboard/hooks.js +9 -5
  163. package/dist/dashboard/icons.d.ts +1 -0
  164. package/dist/dashboard/icons.js +10 -0
  165. package/dist/field/check/CheckField.view.js +2 -2
  166. package/dist/field/code/CodeField.view.js +13 -13
  167. package/dist/field/date/DateField.view.js +12 -2
  168. package/dist/field/link/Link.js +2 -2
  169. package/dist/field/link/LinkField.view.js +88 -77
  170. package/dist/field/list/ListField.view.js +22 -33
  171. package/dist/field/metadata/MetadataField.view.js +20 -20
  172. package/dist/field/number/NumberField.d.ts +2 -0
  173. package/dist/field/number/NumberField.view.js +4 -2
  174. package/dist/field/richtext/PickTextLink.d.ts +7 -0
  175. package/dist/field/richtext/PickTextLink.js +104 -2
  176. package/dist/field/richtext/ReferenceLink.d.ts +4 -1
  177. package/dist/field/richtext/ReferenceLink.js +18 -4
  178. package/dist/field/richtext/RichTextDocument.d.ts +7 -2
  179. package/dist/field/richtext/RichTextDocument.js +34 -5
  180. package/dist/field/richtext/RichTextExtensions.d.ts +3 -1
  181. package/dist/field/richtext/RichTextExtensions.js +2704 -7467
  182. package/dist/field/richtext/RichTextField.d.ts +4 -0
  183. package/dist/field/richtext/RichTextField.story.d.ts +4 -0
  184. package/dist/field/richtext/RichTextField.view.js +44 -21
  185. package/dist/field/richtext/RichTextInsertMenu.js +281 -495
  186. package/dist/field/richtext/RichTextToolbar.d.ts +5 -2
  187. package/dist/field/richtext/RichTextToolbar.js +38 -3
  188. package/dist/field/richtext/Toolbar.d.ts +19 -1
  189. package/dist/field/richtext/Toolbar.js +18 -13
  190. package/dist/field/richtext/extensions/Anchor.js +1 -1
  191. package/dist/field/richtext/extensions/Link.js +1 -1
  192. package/dist/field/richtext/extensions/Small.js +1 -1
  193. package/dist/field/select/SelectField.view.js +8 -6
  194. package/dist/index.css +219 -14
  195. package/dist/next.cjs +18 -16
  196. package/dist/next.d.ts +2 -1
  197. package/dist/next.edge.d.ts +2 -1
  198. package/dist/ui/RichText.d.ts +1 -0
  199. package/dist/ui/RichText.js +29 -2
  200. package/package.json +6 -3
  201. package/dist/chunks/{chunk-JFROOUG6.js → chunk-NIVGVRDS.js} +17 -17
package/dist/bundled.d.ts CHANGED
@@ -75,7 +75,21 @@ declare module 'alinea/adapter/next/context' {
75
75
 
76
76
  import { Config } from 'alinea/core/Config';
77
77
  import type { RequestContext } from 'alinea/core/Connection';
78
- export function requestContext(config: Config): Promise<RequestContext>;
78
+ export function requestContext(config: Config, request?: Request): Promise<RequestContext>;
79
+
80
+ }
81
+
82
+ declare module 'alinea/adapter/next/DevRemote' {
83
+
84
+ import type { RemoteConnection, RequestContext } from 'alinea/core/Connection';
85
+ import type { Config } from 'alinea/core/Config';
86
+ export function createDevRemote(context: RequestContext, config: Config): RemoteConnection;
87
+
88
+ }
89
+
90
+ declare module 'alinea/adapter/next/ForwardCredentials' {
91
+
92
+ export function forwardDevelopmentCredentials(request: Request | undefined, apiKey: string, init?: RequestInit): RequestInit;
79
93
 
80
94
  }
81
95
 
@@ -83,6 +97,7 @@ declare module 'alinea/adapter/next/handler' {
83
97
 
84
98
  import { type BackendFactory, type BackendOptions } from 'alinea/backend/api/CreateBackend';
85
99
  import { type HandlerHooks } from 'alinea/backend/Handler';
100
+ import { Config } from 'alinea/core/Config';
86
101
  import { NextCMS } from 'alinea/adapter/next/cms';
87
102
  type Handler = (request: Request) => Promise<Response>;
88
103
  export interface NextHandlerOptions extends HandlerHooks {
@@ -90,6 +105,7 @@ declare module 'alinea/adapter/next/handler' {
90
105
  backend?: BackendFactory | BackendOptions;
91
106
  }
92
107
  export function createHandler(input: NextCMS | NextHandlerOptions): Handler;
108
+ export function handlerPathname(config: Config, requestUrl: URL): string;
93
109
  export {};
94
110
 
95
111
  }
@@ -465,30 +481,31 @@ declare module 'alinea/backend/HandleAction' {
465
481
 
466
482
  declare module 'alinea/backend/Handler' {
467
483
 
468
- import type { Entry } from 'alinea/core';
469
484
  import type { CMS } from 'alinea/core/CMS';
470
- import type { RemoteConnection, RequestContext } from 'alinea/core/Connection';
471
- import type { LocalDB } from 'alinea/core/db/LocalDB';
485
+ import type { AuthedContext, RemoteConnection, RequestContext } from 'alinea/core/Connection';
486
+ import { LocalDB } from 'alinea/core/db/LocalDB';
487
+ import type { Mutation } from 'alinea/core/db/Mutation';
472
488
  export interface Handler {
473
489
  (request: Request, context: RequestContext): Promise<Response>;
474
490
  }
475
- export type HookResponse<T = void> = void | T | Promise<T> | Promise<void>;
491
+ export type HookResponse<T = void> = void | T | Promise<void | T>;
492
+ export interface BeforeCommitContext {
493
+ mutations: ReadonlyArray<Mutation>;
494
+ }
495
+ export interface AfterCommitContext extends BeforeCommitContext {
496
+ sha: string;
497
+ }
476
498
  export interface HandlerHooks {
477
- beforeCreate?(entry: Entry): HookResponse<Entry>;
478
- afterCreate?(entry: Entry): HookResponse;
479
- beforeUpdate?(entry: Entry): HookResponse<Entry>;
480
- afterUpdate?(entry: Entry): HookResponse;
481
- beforeArchive?(entryId: string): HookResponse;
482
- afterArchive?(entryId: string): HookResponse;
483
- beforeRemove?(entryId: string): HookResponse;
484
- afterRemove?(entryId: string): HookResponse;
499
+ beforeCommit?(context: BeforeCommitContext): HookResponse<ReadonlyArray<Mutation>>;
500
+ afterCommit?(context: AfterCommitContext): HookResponse;
485
501
  }
486
502
  export interface HandlerOptions extends HandlerHooks {
487
503
  cms: CMS;
488
504
  db: LocalDB | Promise<LocalDB>;
489
505
  remote?: (context: RequestContext) => RemoteConnection;
506
+ forwardMutations?(request: Request, context: AuthedContext): Promise<Response | undefined>;
490
507
  }
491
- export function createHandler({ cms, remote, db, ...hooks }: HandlerOptions): Handler;
508
+ export function createHandler({ cms, remote, db, forwardMutations, ...hooks }: HandlerOptions): Handler;
492
509
 
493
510
  }
494
511
 
@@ -523,10 +540,14 @@ declare module 'alinea/backend/Previews' {
523
540
  declare module 'alinea/backend/resolver/ParsePreview' {
524
541
 
525
542
  import type { LocalDB } from 'alinea/core/db/LocalDB';
526
- import type { PreviewRequest } from 'alinea/core/Preview';
527
- export function createPreviewParser(local: LocalDB): {
528
- parse(preview: PreviewRequest, sync: () => Promise<unknown>): Promise<PreviewRequest | undefined>;
529
- };
543
+ import { Entry } from 'alinea/core/Entry';
544
+ import type { PreviewRequest, PreviewUpdate } from 'alinea/core/Preview';
545
+ export interface DecodedEntryPreview {
546
+ entry: Entry;
547
+ }
548
+ export type DecodedPreviewRequest = PreviewUpdate | DecodedEntryPreview;
549
+ export function decodePreviewRequest(preview: PreviewRequest): Promise<DecodedPreviewRequest>;
550
+ export function applyPreview(local: LocalDB, preview: DecodedPreviewRequest): Promise<PreviewRequest | undefined>;
530
551
 
531
552
  }
532
553
 
@@ -828,7 +849,7 @@ declare module 'alinea/cli/generate/DevDB' {
828
849
 
829
850
  import { Config } from 'alinea/core/Config';
830
851
  import type { UploadResponse } from 'alinea/core/Connection';
831
- import { type CommitRequest } from 'alinea/core/db/CommitRequest';
852
+ import type { CommitRequest } from 'alinea/core/db/CommitRequest';
832
853
  import { LocalDB } from 'alinea/core/db/LocalDB';
833
854
  import { CachedFSSource } from 'alinea/core/source/FSSource';
834
855
  export interface DevDBOptions {
@@ -932,7 +953,7 @@ declare module 'alinea/cli/serve/CreateLocalServer' {
932
953
  import type { User } from 'alinea/core/User';
933
954
  import { type Request, Response } from '@alinea/iso';
934
955
  import type { ServeContext } from 'alinea/cli/serve/ServeContext';
935
- export function createLocalServer({ cmd, configLocation, rootDir, staticDir, alineaDev, buildOptions, production, liveReload, buildId }: ServeContext, cms: CMS, handleApi: Handler, user: User): {
956
+ export function createLocalServer({ cmd, configLocation, rootDir, staticDir, alineaDev, buildOptions, production, liveReload, buildId, apiKey }: ServeContext, cms: CMS, handleApi: Handler, user: User): {
936
957
  close(): void;
937
958
  handle(input: Request): Promise<Response>;
938
959
  };
@@ -941,8 +962,8 @@ declare module 'alinea/cli/serve/CreateLocalServer' {
941
962
 
942
963
  declare module 'alinea/cli/serve/DevServer' {
943
964
 
944
- import type { Request, Response } from '@alinea/iso';
945
- import type { Config } from 'alinea/core/Config';
965
+ import { Config } from 'alinea/core/Config';
966
+ import { Request, type Response } from '@alinea/iso';
946
967
  import type { BuildOptions } from 'esbuild';
947
968
  export interface CreateDevServerOptions {
948
969
  cmd: 'dev' | 'build';
@@ -952,6 +973,7 @@ declare module 'alinea/cli/serve/DevServer' {
952
973
  buildOptions?: BuildOptions;
953
974
  alineaDev?: boolean;
954
975
  production?: boolean;
976
+ apiKey?: string;
955
977
  dashboardUrl: Promise<string>;
956
978
  onAfterGenerate?: (message: string, config: Config) => void;
957
979
  }
@@ -1033,6 +1055,7 @@ declare module 'alinea/cli/serve/ServeContext' {
1033
1055
  production: boolean;
1034
1056
  liveReload: LiveReload;
1035
1057
  buildId: string;
1058
+ apiKey: string;
1036
1059
  }
1037
1060
 
1038
1061
  }
@@ -1045,6 +1068,7 @@ declare module 'alinea/cli/serve/StartServer' {
1045
1068
  respondWith(response: Response): Promise<void>;
1046
1069
  }
1047
1070
  export interface Server {
1071
+ hostname: string;
1048
1072
  port: number;
1049
1073
  serve(abortController?: AbortController): AsyncIterable<RequestEvent>;
1050
1074
  close(): void;
@@ -1729,8 +1753,9 @@ declare module 'alinea/components/NumberField' {
1729
1753
  import { type LabelSharedProps } from 'alinea/components/Label';
1730
1754
  export interface NumberFieldProps extends Omit<NumberFieldPrimitiveProps, 'children'>, LabelSharedProps {
1731
1755
  steppers?: boolean;
1756
+ placeholder?: string;
1732
1757
  }
1733
- export function NumberField({ steppers, ...props }: NumberFieldProps): import("react").JSX.Element;
1758
+ export function NumberField({ steppers, placeholder, ...props }: NumberFieldProps): import("react").JSX.Element;
1734
1759
 
1735
1760
  }
1736
1761
 
@@ -2107,6 +2132,7 @@ declare module 'alinea/core/Config' {
2107
2132
  import { type Role } from 'alinea/core/Role';
2108
2133
  import { Root } from 'alinea/core/Root';
2109
2134
  import { Schema } from 'alinea/core/Schema';
2135
+ import type { Tracer } from 'alinea/core/Trace';
2110
2136
  import { Type } from 'alinea/core/Type';
2111
2137
  import { Workspace, type WorkspaceInternal } from 'alinea/core/Workspace';
2112
2138
  /** Configuration options */
@@ -2136,10 +2162,13 @@ declare module 'alinea/core/Config' {
2136
2162
  publicDir?: string;
2137
2163
  /** Filename of the generated dashboard, defaults to admin.html */
2138
2164
  dashboardFile?: string;
2165
+ /** Optional application-owned instrumentation for Alinea operations. */
2166
+ tracer?: Tracer;
2139
2167
  auth?: Auth.View;
2140
2168
  }
2141
2169
  export namespace Config {
2142
2170
  function baseUrl(config: Config, env?: string): string | undefined;
2171
+ function handlerUrl(config: Config): string;
2143
2172
  function adminPath(config: Config): string;
2144
2173
  function mainWorkspace(config: Config): WorkspaceInternal;
2145
2174
  function type(config: Config, name: string): Type | undefined;
@@ -2230,9 +2259,9 @@ declare module 'alinea/core/Connection' {
2230
2259
  isDev: boolean;
2231
2260
  handlerUrl: URL;
2232
2261
  apiKey: string;
2233
- user?: User;
2234
- token?: string;
2262
+ applyAuth?(init?: RequestInit): RequestInit;
2235
2263
  }
2264
+ export const developmentKeyHeader = "x-alinea-dev-key";
2236
2265
  export interface AuthedContext extends RequestContext {
2237
2266
  user: User;
2238
2267
  token: string;
@@ -2272,7 +2301,6 @@ declare module 'alinea/core/Connection' {
2272
2301
  declare module 'alinea/core/db/CommitRequest' {
2273
2302
 
2274
2303
  import type { Change, ChangeFile, ChangesBatch } from 'alinea/core/source/Change';
2275
- import type { ReadonlyTree } from 'alinea/core/source/Tree';
2276
2304
  import type { User } from 'alinea/core/User';
2277
2305
  import type { RemoveFileMutation, UploadFileMutation } from 'alinea/core/db/Mutation';
2278
2306
  export interface AddContent extends ChangeFile {
@@ -2290,10 +2318,8 @@ declare module 'alinea/core/db/CommitRequest' {
2290
2318
  user?: User;
2291
2319
  fromSha: string;
2292
2320
  intoSha: string;
2293
- checks: Array<[path: string, sha: string]>;
2294
2321
  changes: Array<CommitChange>;
2295
2322
  }
2296
- export function checkCommit(tree: ReadonlyTree, request: CommitRequest): void;
2297
2323
 
2298
2324
  }
2299
2325
 
@@ -2351,6 +2377,14 @@ declare module 'alinea/core/db/EntryIndex' {
2351
2377
  language?(language: EntryLanguageNode): boolean;
2352
2378
  entry?(entry: Entry): boolean;
2353
2379
  }
2380
+ interface EntryNodeQuery {
2381
+ ids?: ReadonlyArray<string>;
2382
+ parentIds?: ReadonlyArray<string | null>;
2383
+ urls?: ReadonlyArray<string>;
2384
+ workspaces?: ReadonlyArray<string>;
2385
+ roots?: ReadonlyArray<string>;
2386
+ types?: ReadonlyArray<string>;
2387
+ }
2354
2388
  export function combineConditions(a: EntryCondition, b: EntryCondition): EntryCondition;
2355
2389
  interface EntryVersionData {
2356
2390
  id: string;
@@ -2424,6 +2458,7 @@ declare module 'alinea/core/db/EntryIndex' {
2424
2458
  nodes: Array<EntryNode>;
2425
2459
  constructor(config: Config, versionData: Map<string, EntryVersionData>, seeds: Map<string, Seed>);
2426
2460
  byId(id: string): EntryNode | undefined;
2461
+ candidateNodes(query: EntryNodeQuery): Array<EntryNode> | undefined;
2427
2462
  get config(): Config;
2428
2463
  byDir(dir: string): EntryNode | undefined;
2429
2464
  entryByFilePath(filePath: string): Entry | undefined;
@@ -2436,6 +2471,7 @@ declare module 'alinea/core/db/EntryIndex' {
2436
2471
  initialSync: ReadonlyTree | undefined;
2437
2472
  graph: EntryGraph;
2438
2473
  constructor(config: Config);
2474
+ clone(): EntryIndex;
2439
2475
  get sha(): string;
2440
2476
  filter(filter: EntryCondition): Iterable<Entry>;
2441
2477
  findFirst<T extends Record<string, unknown>>(filter: (entry: Entry) => boolean): Entry<T> | undefined;
@@ -2633,12 +2669,11 @@ declare module 'alinea/core/db/EntryTransaction' {
2633
2669
  removeFile(mutation: Op<RemoveFileMutation>): this;
2634
2670
  uploadFile(mutation: Op<UploadFileMutation>): this;
2635
2671
  description(): string;
2636
- apply(mutations: Array<Mutation>): void;
2672
+ apply(mutations: ReadonlyArray<Mutation>): Promise<void>;
2637
2673
  toRequest(): Promise<{
2638
2674
  fromSha: string;
2639
2675
  intoSha: string;
2640
2676
  description: string;
2641
- checks: [path: string, sha: string][];
2642
2677
  changes: CommitChange[];
2643
2678
  }>;
2644
2679
  }
@@ -2721,7 +2756,7 @@ declare module 'alinea/core/db/LocalDB' {
2721
2756
  config: Config;
2722
2757
  index: EntryIndex;
2723
2758
  source: Source;
2724
- constructor(config: Config, source?: Source);
2759
+ constructor(config: Config, source?: Source, index?: EntryIndex);
2725
2760
  resolve<Query extends GraphQuery>(query: Query): Promise<AnyQueryResult<Query>>;
2726
2761
  referencesTo(query: EntryReferenceQuery): Promise<EntryReferenceResult>;
2727
2762
  get sha(): string;
@@ -2732,11 +2767,10 @@ declare module 'alinea/core/db/LocalDB' {
2732
2767
  sync(): Promise<string>;
2733
2768
  syncWith(remote: SyncApi): Promise<string>;
2734
2769
  logEntries(): Promise<void>;
2735
- request(mutations: Array<Mutation>, policy?: Policy): Promise<{
2770
+ request(mutations: ReadonlyArray<Mutation>, policy?: Policy): Promise<{
2736
2771
  fromSha: string;
2737
2772
  intoSha: string;
2738
2773
  description: string;
2739
- checks: [path: string, sha: string][];
2740
2774
  changes: import("alinea/core/db/CommitRequest").CommitChange[];
2741
2775
  }>;
2742
2776
  mutate(mutations: Array<Mutation>): Promise<{
@@ -3414,7 +3448,7 @@ declare module 'alinea/core/field/RichTextField' {
3414
3448
  import { Field, type FieldMeta, type FieldOptions } from 'alinea/core/Field';
3415
3449
  import type { InferStoredValue } from 'alinea/core/Infer';
3416
3450
  import { Schema } from 'alinea/core/Schema';
3417
- import { type TextDoc } from 'alinea/core/TextDoc';
3451
+ import { Mark, type ElementNode, type TextDoc } from 'alinea/core/TextDoc';
3418
3452
  export type RichTextMutator<R> = {
3419
3453
  insert: (id: string, block: string) => void;
3420
3454
  };
@@ -3428,10 +3462,37 @@ declare module 'alinea/core/field/RichTextField' {
3428
3462
  private doc;
3429
3463
  constructor(doc?: TextDoc<Blocks>);
3430
3464
  add<Key extends keyof Blocks>(type: Key, block: RichTextBlockInput<Blocks, Key>): this;
3431
- addHtml(html: string): this;
3465
+ addHtml(html: string, options?: ParseHTMLSyncOptions): this;
3466
+ addHtmlAsync(html: string, options?: ParseHTMLAsyncOptions): Promise<this>;
3432
3467
  value(): TextDoc<Blocks>;
3433
3468
  }
3434
- export function parseHTML(html: string): TextDoc<any>;
3469
+ export interface ParseHTMLTagHandler {
3470
+ (attributes: Record<string, string>): ElementNode | undefined;
3471
+ }
3472
+ export interface ParseHTMLMarkHandler {
3473
+ (attributes: Record<string, string>): Mark | undefined;
3474
+ }
3475
+ export interface ParseHTMLAsyncTagHandler {
3476
+ (attributes: Record<string, string>): ElementNode | undefined | PromiseLike<ElementNode | undefined>;
3477
+ }
3478
+ export interface ParseHTMLAsyncMarkHandler {
3479
+ (attributes: Record<string, string>): Mark | undefined | PromiseLike<Mark | undefined>;
3480
+ }
3481
+ export interface ParseHTMLSyncOptions {
3482
+ tags?: Record<string, ParseHTMLTagHandler>;
3483
+ marks?: Record<string, ParseHTMLMarkHandler>;
3484
+ }
3485
+ export interface ParseHTMLAsyncOptions {
3486
+ tags?: Record<string, ParseHTMLAsyncTagHandler>;
3487
+ marks?: Record<string, ParseHTMLAsyncMarkHandler>;
3488
+ }
3489
+ /**
3490
+ * Parse HTML using handlers that may perform asynchronous work, such as
3491
+ * importing remote images into a media directory.
3492
+ */
3493
+ export function parseHTMLAsync(html: string, options?: ParseHTMLAsyncOptions): Promise<TextDoc>;
3494
+ /** Parse HTML synchronously. Async handlers are only supported by parseHTMLAsync. */
3495
+ export function parseHTML(html: string, options?: ParseHTMLSyncOptions): TextDoc;
3435
3496
 
3436
3497
  }
3437
3498
 
@@ -3502,6 +3563,7 @@ declare module 'alinea/core/Graph' {
3502
3563
  import type { Condition, Filter } from 'alinea/core/Filter';
3503
3564
  import type { Infer, StoredRow } from 'alinea/core/Infer';
3504
3565
  import type { HasField } from 'alinea/core/Internal';
3566
+ import type { OrderBy } from 'alinea/core/OrderBy';
3505
3567
  import type { Page } from 'alinea/core/Page';
3506
3568
  import type { PreviewRequest } from 'alinea/core/Preview';
3507
3569
  import type { Type } from 'alinea/core/Type';
@@ -3549,11 +3611,9 @@ declare module 'alinea/core/Graph' {
3549
3611
  }
3550
3612
  export type Projection = SelectContent | SelectObject;
3551
3613
  export type InferProjection<Selection> = InferSelection<Selection>;
3552
- export interface Order {
3553
- asc?: Expr<any>;
3554
- desc?: Expr<any>;
3614
+ export type Order = OrderBy & {
3555
3615
  caseSensitive?: boolean;
3556
- }
3616
+ };
3557
3617
  type InferSelection<Selection> = Selection extends GraphQuery & Edge ? Expand<AnyQueryResult<Selection>> : Selection extends Expr<infer V> ? V : {
3558
3618
  [K in keyof Selection]: Selection[K] extends Type<infer V> ? Type.Infer<V> : InferSelection<Selection[K]>;
3559
3619
  };
@@ -3815,6 +3875,8 @@ declare module 'alinea/core/ListRow' {
3815
3875
  _id: string;
3816
3876
  _type: string;
3817
3877
  _index: string;
3878
+ _anchor?: string;
3879
+ _label?: string;
3818
3880
  }
3819
3881
  export namespace ListRow {
3820
3882
  const id = "_id";
@@ -3867,6 +3929,7 @@ declare module 'alinea/core/media/MediaAltField' {
3867
3929
  export class MediaAltField extends ScalarField<MediaAltValue, MediaAltOptions> {
3868
3930
  }
3869
3931
  export function mediaAlt(label: string, options?: WithoutLabel<MediaAltOptions>): MediaAltField;
3932
+ export function mediaAltText(value: MediaAltValue, locale?: string): string;
3870
3933
 
3871
3934
  }
3872
3935
 
@@ -4035,11 +4098,15 @@ declare module 'alinea/core/media/UploadLimits' {
4035
4098
  declare module 'alinea/core/OrderBy' {
4036
4099
 
4037
4100
  import type { Expr } from 'alinea/core/Expr';
4038
- export type OrderBy = {
4101
+ export interface AscendingOrder {
4039
4102
  asc: Expr<any>;
4040
- } | {
4103
+ desc?: never;
4104
+ }
4105
+ export interface DescendingOrder {
4106
+ asc?: never;
4041
4107
  desc: Expr<any>;
4042
- };
4108
+ }
4109
+ export type OrderBy = AscendingOrder | DescendingOrder;
4043
4110
 
4044
4111
  }
4045
4112
 
@@ -4694,6 +4761,23 @@ declare module 'alinea/core/source/MemorySource' {
4694
4761
 
4695
4762
  }
4696
4763
 
4764
+ declare module 'alinea/core/source/OverlaySource' {
4765
+
4766
+ import type { ChangesBatch } from 'alinea/core/source/Change';
4767
+ import type { GetBlobsOptions, Source } from 'alinea/core/source/Source';
4768
+ import type { ReadonlyTree } from 'alinea/core/source/Tree';
4769
+ export class OverlaySource implements Source {
4770
+ #private;
4771
+ constructor(source: Source, tree: ReadonlyTree);
4772
+ static create(source: Source): Promise<OverlaySource>;
4773
+ getTree(): Promise<ReadonlyTree>;
4774
+ getTreeIfDifferent(sha: string): Promise<ReadonlyTree | undefined>;
4775
+ getBlobs(shas: ReadonlyArray<string>, options?: GetBlobsOptions): AsyncGenerator<[sha: string, blob: Uint8Array]>;
4776
+ applyChanges(batch: ChangesBatch): Promise<void>;
4777
+ }
4778
+
4779
+ }
4780
+
4697
4781
  declare module 'alinea/core/source/ShaMismatchError' {
4698
4782
 
4699
4783
  import { HttpError } from 'alinea/core/HttpError';
@@ -4730,7 +4814,7 @@ declare module 'alinea/core/source/Source' {
4730
4814
  add(path: string, contents: Uint8Array): this;
4731
4815
  remove(path: string): this;
4732
4816
  rename(from: string, to: string): this;
4733
- compile(): Promise<{
4817
+ compile(previous?: ReadonlyTree): Promise<{
4734
4818
  from: ReadonlyTree;
4735
4819
  into: ReadonlyTree;
4736
4820
  changes: (import("alinea/core/source/Change").DeleteChange | {
@@ -4925,6 +5009,17 @@ declare module 'alinea/core/TextDoc' {
4925
5009
  export namespace ElementNode {
4926
5010
  const content = "content";
4927
5011
  }
5012
+ export interface ImageNode extends ElementNode {
5013
+ _type: 'image';
5014
+ _id?: string;
5015
+ _link?: 'image';
5016
+ _entry?: string;
5017
+ src?: string;
5018
+ alt?: string;
5019
+ title?: string;
5020
+ width?: number | string;
5021
+ height?: number | string;
5022
+ }
4928
5023
  export interface BlockNode {
4929
5024
  _id: string;
4930
5025
  _type: string;
@@ -4935,6 +5030,19 @@ declare module 'alinea/core/TextDoc' {
4935
5030
 
4936
5031
  }
4937
5032
 
5033
+ declare module 'alinea/core/Trace' {
5034
+
5035
+ import type { Config } from 'alinea/core/Config';
5036
+ export interface Tracer {
5037
+ <Result>(name: string, run: () => Promise<Result>): Promise<Result>;
5038
+ }
5039
+ export interface TraceSpan {
5040
+ <Result>(operation: () => Promise<Result>): Promise<Result>;
5041
+ }
5042
+ export function trace(config: Config, name: string): TraceSpan;
5043
+
5044
+ }
5045
+
4938
5046
  declare module 'alinea/core/Tracker' {
4939
5047
 
4940
5048
  import { Field, type FieldOptions } from 'alinea/core/Field';
@@ -5943,7 +6051,7 @@ declare module 'alinea/dashboard/app/editor/FilePreview' {
5943
6051
 
5944
6052
  declare module 'alinea/dashboard/app/editor/MediaAltField.view' {
5945
6053
 
5946
- import type { MediaAltField } from 'alinea/core/media/MediaAltField';
6054
+ import { type MediaAltField } from 'alinea/core/media/MediaAltField';
5947
6055
  export interface MediaAltFieldViewProps {
5948
6056
  field: MediaAltField;
5949
6057
  }
@@ -6074,7 +6182,7 @@ declare module 'alinea/dashboard/app/EntrySidebar' {
6074
6182
  onOpenChange?: (isOpen: boolean) => void;
6075
6183
  }
6076
6184
  export type EntrySidebarTab = 'preview' | 'history' | 'references';
6077
- export function entrySidebar(get: Getter, entry: EntryAtoms, localeData: EntryLocaleAtoms): Promise<EntrySidebarProps | undefined>;
6185
+ export function entrySidebar(get: Getter, entry: EntryAtoms, localeData: EntryLocaleAtoms, isOpen?: boolean): Promise<EntrySidebarProps | undefined>;
6078
6186
  export function EntrySidebar({ entry, localeData, selectedTab, previousVersionsOpen, onOpenChange }: EntrySidebarProps): import("react").JSX.Element;
6079
6187
  export type EntrySidebarVersionStatus = EntryStatus | 'unpublished' | 'none';
6080
6188
  export interface EntrySidebarVersionRowProps {
@@ -6099,7 +6207,7 @@ declare module 'alinea/dashboard/app/EntrySidebarPreview' {
6099
6207
  }
6100
6208
  export function EntrySidebarPreview({ entry, localeData }: EntrySidebarPreviewProps): import("react").JSX.Element;
6101
6209
  export interface EntrySidebarBrowserPreviewProps {
6102
- localeData: Pick<EntryLocaleAtoms, 'previewUrl' | 'retryPreviewUrl'> & Partial<Pick<EntryLocaleAtoms, 'previewPayloadSignal' | 'updatePreviewPayload'>>;
6210
+ localeData: Pick<EntryLocaleAtoms, 'previewUrlState' | 'retryPreviewUrl'> & Partial<Pick<EntryLocaleAtoms, 'previewPayloadSignal' | 'updatePreviewPayload'>>;
6103
6211
  }
6104
6212
  export function EntrySidebarBrowserPreview({ localeData }: EntrySidebarBrowserPreviewProps): import("react").JSX.Element;
6105
6213
 
@@ -6406,6 +6514,19 @@ declare module 'alinea/dashboard/app/pages/UsersPage' {
6406
6514
 
6407
6515
  }
6408
6516
 
6517
+ declare module 'alinea/dashboard/app/SidebarLayout' {
6518
+
6519
+ import { type ReactNode } from 'react';
6520
+ export interface SidebarLayoutProps {
6521
+ children: ReactNode;
6522
+ sidebar: ReactNode;
6523
+ side: 'left' | 'right';
6524
+ visible?: boolean;
6525
+ }
6526
+ export function SidebarLayout({ children, sidebar, side, visible }: SidebarLayoutProps): import("react").JSX.Element;
6527
+
6528
+ }
6529
+
6409
6530
  declare module 'alinea/dashboard/app/SidebarTree' {
6410
6531
 
6411
6532
  import { type Page } from 'alinea/dashboard/atoms/nav';
@@ -6779,6 +6900,15 @@ declare module 'alinea/dashboard/atoms/dashboard' {
6779
6900
 
6780
6901
  import type { SetStateAction } from 'react';
6781
6902
  export type DashboardTheme = 'system' | 'light' | 'dark';
6903
+ export const dashboardMobileAtom: import("jotai").PrimitiveAtom<boolean> & {
6904
+ init: boolean;
6905
+ };
6906
+ export const navigationSidebarWidthAtom: import("jotai").PrimitiveAtom<number> & {
6907
+ init: number;
6908
+ };
6909
+ export const entrySidebarWidthAtom: import("jotai").PrimitiveAtom<number> & {
6910
+ init: number;
6911
+ };
6782
6912
  export const entrySidebarOpenAtom: import("jotai").PrimitiveAtom<boolean> & {
6783
6913
  init: boolean;
6784
6914
  };
@@ -6801,6 +6931,10 @@ declare module 'alinea/dashboard/atoms/editor' {
6801
6931
  import { Type } from 'alinea/core/Type';
6802
6932
  import type { Atom, WritableAtom } from 'jotai';
6803
6933
  import type { ComponentType, ReactNode } from 'react';
6934
+ export interface ResolvedEditorImage {
6935
+ src: string;
6936
+ alt: string;
6937
+ }
6804
6938
  export interface EditorNode {
6805
6939
  readOnly: boolean;
6806
6940
  nodes: WritableAtom<unknown, [unknown], void>;
@@ -6811,6 +6945,7 @@ declare module 'alinea/dashboard/atoms/editor' {
6811
6945
  anchors: Atom<Array<EntryAnchorTarget>>;
6812
6946
  node: EditorNode;
6813
6947
  parent?: EditorModel;
6948
+ resolvedImages: ReadonlyMap<string, ResolvedEditorImage>;
6814
6949
  sections: Array<EditorSection>;
6815
6950
  type: Type;
6816
6951
  field(key: string): EditorField | undefined;
@@ -6841,10 +6976,11 @@ declare module 'alinea/dashboard/atoms/editor' {
6841
6976
  parent?: EntryEditor | undefined;
6842
6977
  resource?: Resource | undefined;
6843
6978
  policy?: Policy | undefined;
6979
+ resolvedImages: ReadonlyMap<string, ResolvedEditorImage>;
6844
6980
  anchors: Atom<Array<EntryAnchorTarget>>;
6845
6981
  value: Atom<object>;
6846
6982
  sections: Array<EntryEditorSection>;
6847
- constructor(type: Type, node: EditorNode, parent?: EntryEditor | undefined, resource?: Resource | undefined, policy?: Policy | undefined);
6983
+ constructor(type: Type, node: EditorNode, parent?: EntryEditor | undefined, resource?: Resource | undefined, policy?: Policy | undefined, resolvedImages?: ReadonlyMap<string, ResolvedEditorImage>);
6848
6984
  field: (key: string) => EntryEditorField | undefined;
6849
6985
  get(field: Field): EntryEditorField | undefined;
6850
6986
  }
@@ -6884,6 +7020,7 @@ declare module 'alinea/dashboard/atoms/entry' {
6884
7020
  import type { Order } from 'alinea/core/Graph';
6885
7021
  import { type EntryDefaultView } from 'alinea/core/Type';
6886
7022
  import { Atom, Getter } from 'jotai';
7023
+ import type { ResolvedEditorImage } from 'alinea/dashboard/atoms/editor';
6887
7024
  import { ReactiveNode } from 'alinea/dashboard/atoms/ReactiveNode';
6888
7025
  interface EntryData {
6889
7026
  id: string;
@@ -6949,6 +7086,7 @@ declare module 'alinea/dashboard/atoms/entry' {
6949
7086
  historyReady: Atom<Promise<import("alinea/core/Connection").Revision[]>>;
6950
7087
  history: Atom<import("alinea/core/Connection").Revision[]>;
6951
7088
  selectedNode: Atom<Promise<ReactiveNode<object>>>;
7089
+ richTextImages: Atom<Promise<Map<string, ResolvedEditorImage>>>;
6952
7090
  anchors: Atom<Promise<import("alinea/core/Field").EntryAnchorTarget[]>>;
6953
7091
  retryPreviewUrl: import("jotai").WritableAtom<null, [], void> & {
6954
7092
  init: null;
@@ -7004,7 +7142,7 @@ declare module 'alinea/dashboard/atoms/entry' {
7004
7142
  searchableText: string;
7005
7143
  } | undefined>;
7006
7144
  previewUrlReady: Atom<Promise<string | undefined>>;
7007
- previewUrl: Atom<string | undefined>;
7145
+ previewUrlState: Atom<readonly [false, string | undefined] | readonly [true, string | undefined]>;
7008
7146
  previewPayloadSignal: Atom<(object | null | undefined)[]>;
7009
7147
  updatePreviewPayload: import("jotai").WritableAtom<null, [], Promise<string | undefined>> & {
7010
7148
  init: null;
@@ -7504,7 +7642,10 @@ declare module 'alinea/dashboard/atoms/nav' {
7504
7642
 
7505
7643
  declare module 'alinea/dashboard/atoms/preview' {
7506
7644
 
7645
+ import type { LocalConnection } from 'alinea/core/Connection';
7507
7646
  import type { PreviewMetadata } from 'alinea/core/Preview';
7647
+ export function getPreviewToken(client: LocalConnection): Promise<string | undefined>;
7648
+ export function retryPreviewToken(client: LocalConnection): void;
7508
7649
  export const previewMetadataAtom: import("jotai").PrimitiveAtom<PreviewMetadata | undefined> & {
7509
7650
  init: PreviewMetadata | undefined;
7510
7651
  };
@@ -8096,7 +8237,7 @@ declare module 'alinea/dashboard/hooks' {
8096
8237
  import type { WorkspaceInternal } from 'alinea/core/Workspace';
8097
8238
  import { Type } from 'alinea';
8098
8239
  import type { ComponentType, Dispatch, PropsWithChildren, SetStateAction } from 'react';
8099
- import { type EditorModel, type EditorNode, EntryEditor } from 'alinea/dashboard/atoms/editor';
8240
+ import { type EditorModel, type EditorNode, EntryEditor, type ResolvedEditorImage } from 'alinea/dashboard/atoms/editor';
8100
8241
  import type { EntryAtoms, EntryLocaleAtoms } from 'alinea/dashboard/atoms/entry';
8101
8242
  import type { Page } from 'alinea/dashboard/atoms/nav';
8102
8243
  import type { RootAtoms } from 'alinea/dashboard/atoms/root';
@@ -8104,6 +8245,7 @@ declare module 'alinea/dashboard/hooks' {
8104
8245
  interface EntryContextValue {
8105
8246
  entry: EntryAtoms;
8106
8247
  localeData: EntryLocaleAtoms;
8248
+ richTextImages: ReadonlyMap<string, ResolvedEditorImage>;
8107
8249
  selectedEntry: EntryRecord<Record<string, unknown>>;
8108
8250
  }
8109
8251
  export interface DashboardOptions {
@@ -8171,9 +8313,10 @@ declare module 'alinea/dashboard/hooks' {
8171
8313
  export interface EntryScopeProps {
8172
8314
  entry: EntryAtoms;
8173
8315
  localeData: EntryLocaleAtoms;
8316
+ richTextImages: ReadonlyMap<string, ResolvedEditorImage>;
8174
8317
  selectedEntry: EntryRecord<Record<string, unknown>>;
8175
8318
  }
8176
- export function EntryScope({ children, entry, localeData, selectedEntry }: PropsWithChildren<EntryScopeProps>): import("react").FunctionComponentElement<import("react").ProviderProps<EntryContextValue | null>>;
8319
+ export function EntryScope({ children, entry, localeData, richTextImages, selectedEntry }: PropsWithChildren<EntryScopeProps>): import("react").FunctionComponentElement<import("react").ProviderProps<EntryContextValue | null>>;
8177
8320
  export function useEntryAtoms(): EntryContextValue;
8178
8321
  export function useOptionalEntryAtoms(): EntryContextValue | null;
8179
8322
  /**
@@ -8356,6 +8499,7 @@ declare module 'alinea/dashboard/icons' {
8356
8499
  export function IcRoundMoreVert(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
8357
8500
  export function IcRoundNorthEast(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
8358
8501
  export function IcRoundNumbers(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
8502
+ export function IcRoundOpenInFull(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
8359
8503
  export function IcRoundOpenInNew(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
8360
8504
  export function IcRoundPanorama(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
8361
8505
  export function IcRoundPermMedia(props: SVGProps<SVGSVGElement>): import("react").JSX.Element;
@@ -9352,6 +9496,8 @@ declare module 'alinea/field/number/NumberField' {
9352
9496
  help?: ReactNode;
9353
9497
  /** Display a minimal version */
9354
9498
  inline?: boolean;
9499
+ /** Text displayed when the field is empty */
9500
+ placeholder?: string;
9355
9501
  /** A minimum value */
9356
9502
  minValue?: number;
9357
9503
  /** A maximum value */
@@ -9584,7 +9730,9 @@ declare module 'alinea/field/richtext/PickTextLink' {
9584
9730
  import { Reference } from 'alinea/core/Reference';
9585
9731
  export interface PickerValue {
9586
9732
  link?: Reference;
9733
+ alt?: string;
9587
9734
  description?: string;
9735
+ src?: string;
9588
9736
  title?: string;
9589
9737
  blank?: boolean;
9590
9738
  }
@@ -9595,9 +9743,14 @@ declare module 'alinea/field/richtext/PickTextLink' {
9595
9743
  export interface PickTextLinkFunc {
9596
9744
  (options: Partial<PickerOptions>): Promise<PickerValue | undefined>;
9597
9745
  }
9746
+ export interface PickRichTextImageFunc {
9747
+ (options: Partial<PickerOptions>): Promise<PickerValue | undefined>;
9748
+ }
9598
9749
  export interface PickTextLinkState {
9599
9750
  isOpen: boolean;
9751
+ kind: 'image' | 'link';
9600
9752
  options: Partial<PickerOptions>;
9753
+ pickImage: PickRichTextImageFunc;
9601
9754
  pickLink: PickTextLinkFunc;
9602
9755
  cancel: () => void;
9603
9756
  confirm: (value: PickerValue | undefined) => void;
@@ -9615,10 +9768,13 @@ declare module 'alinea/field/richtext/ReferenceLink' {
9615
9768
  import { Reference } from 'alinea/core/Reference';
9616
9769
  import type { HTMLProps } from 'react';
9617
9770
  interface Anchor extends HTMLProps<HTMLAnchorElement> {
9771
+ _id?: string;
9772
+ _entry?: string;
9773
+ _link?: 'entry' | 'file' | 'image' | 'url';
9618
9774
  'data-id'?: string;
9619
9775
  'data-entry'?: string;
9620
9776
  'data-anchor'?: string;
9621
- 'data-link'?: 'entry' | 'file' | 'url';
9777
+ 'data-link'?: 'entry' | 'file' | 'image' | 'url';
9622
9778
  'data-suffix'?: string;
9623
9779
  }
9624
9780
  export function referenceToAttributes(reference: Reference): Anchor;
@@ -9695,8 +9851,13 @@ declare module 'alinea/field/richtext/RichTextBlockValue' {
9695
9851
  declare module 'alinea/field/richtext/RichTextDocument' {
9696
9852
 
9697
9853
  import { BlockNode, type TextDoc } from 'alinea/core/TextDoc';
9698
- import type { JSONContent } from '@tiptap/core';
9699
- export function editorContent(nodes: TextDoc): JSONContent;
9854
+ import { type Editor, type JSONContent } from '@tiptap/core';
9855
+ /** Include data attributes produced by custom extensions in the stored document. */
9856
+ export function editorDocument(editor: Editor): JSONContent;
9857
+ export function editorContent(nodes: TextDoc, images?: ReadonlyMap<string, {
9858
+ src: string;
9859
+ alt: string;
9860
+ }>): JSONContent;
9700
9861
  export function editorNodes(content: JSONContent, resolveBlock?: (id: string, typeName: string, snapshot: BlockNode | undefined) => BlockNode | undefined): TextDoc;
9701
9862
 
9702
9863
  }
@@ -9718,6 +9879,7 @@ declare module 'alinea/field/richtext/RichTextExtensions' {
9718
9879
  Italic: import("@tiptap/core").Mark<import("@tiptap/extension-italic").ItalicOptions, any>;
9719
9880
  Strike: import("@tiptap/core").Mark<import("@tiptap/extension-strike").StrikeOptions, any>;
9720
9881
  HorizontalRule: TipTapNode<import("@tiptap/extension-horizontal-rule").HorizontalRuleOptions, any>;
9882
+ Image: TipTapNode<import("@tiptap/extension-image").ImageOptions, any>;
9721
9883
  BulletList: TipTapNode<import("@tiptap/extension-list").BulletListOptions, any>;
9722
9884
  OrderedList: TipTapNode<import("@tiptap/extension-list").OrderedListOptions, any>;
9723
9885
  ListItem: TipTapNode<import("@tiptap/extension-list").ListItemOptions, any>;
@@ -9738,7 +9900,7 @@ declare module 'alinea/field/richtext/RichTextExtensions' {
9738
9900
  Highlight: import("@tiptap/core").Mark<import("@tiptap/extension-highlight").HighlightOptions, any>;
9739
9901
  UndoRedo: Extension<import("@tiptap/extensions").UndoRedoOptions, any>;
9740
9902
  };
9741
- export function defaultExtensionConfig(getEntryAnchors?: () => Iterable<string>): {
9903
+ export function defaultExtensionConfig(getEntryAnchors?: () => Iterable<string>, enableImageResize?: boolean): {
9742
9904
  Document: TipTapNode<any, any>;
9743
9905
  Text: TipTapNode<any, any>;
9744
9906
  Paragraph: TipTapNode<import("@tiptap/extension-paragraph").ParagraphOptions, any>;
@@ -9748,6 +9910,7 @@ declare module 'alinea/field/richtext/RichTextExtensions' {
9748
9910
  Italic: import("@tiptap/core").Mark<import("@tiptap/extension-italic").ItalicOptions, any>;
9749
9911
  Strike: import("@tiptap/core").Mark<import("@tiptap/extension-strike").StrikeOptions, any>;
9750
9912
  HorizontalRule: TipTapNode<import("@tiptap/extension-horizontal-rule").HorizontalRuleOptions, any>;
9913
+ Image: TipTapNode<import("@tiptap/extension-image").ImageOptions, any>;
9751
9914
  BulletList: TipTapNode<import("@tiptap/extension-list").BulletListOptions, any>;
9752
9915
  OrderedList: TipTapNode<import("@tiptap/extension-list").OrderedListOptions, any>;
9753
9916
  ListItem: TipTapNode<import("@tiptap/extension-list").ListItemOptions, any>;
@@ -9799,10 +9962,14 @@ declare module 'alinea/field/richtext/RichTextField' {
9799
9962
  help?: ReactNode;
9800
9963
  /** Display a minimal version */
9801
9964
  inline?: boolean;
9965
+ /** Text shown when the editor is empty */
9966
+ placeholder?: string;
9802
9967
  /** Index the text value of this field */
9803
9968
  searchable?: boolean;
9804
9969
  /** Enable inserting and editing tables */
9805
9970
  enableTables?: boolean;
9971
+ /** Enable inserting and editing images */
9972
+ enableImages?: boolean;
9806
9973
  /** Configure the toolbar layout and items */
9807
9974
  toolbar?: ToolbarConfig;
9808
9975
  /** Configure tiptap extensions */
@@ -9823,12 +9990,16 @@ declare module 'alinea/field/richtext/RichTextField.story' {
9823
9990
 
9824
9991
  export function RichTextStory(): import("react").JSX.Element;
9825
9992
  export function RichTextPlainStory(): import("react").JSX.Element;
9993
+ export function RichTextImageStory(): import("react").JSX.Element;
9994
+ export function RichTextImageDisabledStory(): import("react").JSX.Element;
9995
+ export function RichTextReadOnlyImageStory(): import("react").JSX.Element;
9826
9996
  export function RichTextLargeStory(): import("react").JSX.Element;
9827
9997
  export function RichTextImportedListStory(): import("react").JSX.Element;
9828
9998
  export function RichTextCustomToolbarStory(): import("react").JSX.Element;
9829
9999
  export function RichTextEmptyStory(): import("react").JSX.Element;
9830
10000
  export function RichTextLegacyEmptyStory(): import("react").JSX.Element;
9831
10001
  export function RichTextReadOnlyStory(): import("react").JSX.Element;
10002
+ export function RichTextInlineStory(): import("react").JSX.Element;
9832
10003
 
9833
10004
  }
9834
10005
 
@@ -9878,20 +10049,23 @@ declare module 'alinea/field/richtext/RichTextState' {
9878
10049
  declare module 'alinea/field/richtext/RichTextToolbar' {
9879
10050
 
9880
10051
  import type { Editor } from '@tiptap/core';
9881
- import type { PickTextLinkFunc } from 'alinea/field/richtext/PickTextLink';
10052
+ import type { PickRichTextImageFunc, PickTextLinkFunc } from 'alinea/field/richtext/PickTextLink';
9882
10053
  import { type ToolbarConfig } from 'alinea/field/richtext/Toolbar';
9883
10054
  import type { PickTextAnchorFunc } from 'alinea/field/richtext/PickTextAnchor';
9884
10055
  export interface RichTextToolbarProps {
9885
10056
  editor: Editor;
10057
+ enableImages?: boolean;
9886
10058
  enableTables?: boolean;
9887
10059
  ownerId: string;
10060
+ pickImage?: PickRichTextImageFunc;
9888
10061
  pickLink?: PickTextLinkFunc;
9889
10062
  pickAnchor?: PickTextAnchorFunc;
9890
10063
  getEntryAnchors: () => Array<string>;
9891
10064
  toolbar?: ToolbarConfig;
9892
10065
  onFocusChange: (focused: boolean, nextTarget?: EventTarget | null) => void;
9893
10066
  }
9894
- export function RichTextToolbar({ editor, enableTables, ownerId, pickLink, pickAnchor, getEntryAnchors, toolbar, onFocusChange }: RichTextToolbarProps): import("react").JSX.Element;
10067
+ export function RichTextToolbar({ editor, enableImages, enableTables, ownerId, pickImage, pickLink, pickAnchor, getEntryAnchors, toolbar, onFocusChange }: RichTextToolbarProps): import("react").JSX.Element;
10068
+ export function createImageHandler(editor: Editor, pickImage: PickRichTextImageFunc | undefined, exec: () => ReturnType<Editor['chain']>): () => void;
9895
10069
 
9896
10070
  }
9897
10071
 
@@ -9900,6 +10074,7 @@ declare module 'alinea/field/richtext/Toolbar' {
9900
10074
  import type { Editor } from '@tiptap/react';
9901
10075
  import type { ComponentType, ReactElement, ReactNode } from 'react';
9902
10076
  import type { PickTextLinkFunc } from 'alinea/field/richtext/PickTextLink';
10077
+ import type { PickRichTextImageFunc } from 'alinea/field/richtext/PickTextLink';
9903
10078
  export interface RichTextCommand {
9904
10079
  (): ReturnType<Editor['chain']>;
9905
10080
  }
@@ -9926,9 +10101,12 @@ declare module 'alinea/field/richtext/Toolbar' {
9926
10101
  export interface RichTextToolbarContext {
9927
10102
  editor: Editor;
9928
10103
  focusToggle: (target: EventTarget | null) => void;
10104
+ pickImage: PickRichTextImageFunc;
9929
10105
  pickLink: PickTextLinkFunc;
10106
+ enableImages?: boolean;
9930
10107
  enableTables?: boolean;
9931
10108
  exec: RichTextCommand;
10109
+ handleImage: () => void;
9932
10110
  handleLink: () => void;
9933
10111
  handleAnchor: () => void;
9934
10112
  toolbar: ToolbarConfig;
@@ -10078,6 +10256,16 @@ declare module 'alinea/field/richtext/Toolbar' {
10078
10256
  };
10079
10257
  };
10080
10258
  };
10259
+ export const images: {
10260
+ group: {
10261
+ image: {
10262
+ icon: () => import("react").JSX.Element;
10263
+ title: string;
10264
+ active: ({ editor }: RichTextToolbarContext) => boolean;
10265
+ onSelect: ({ handleImage }: RichTextToolbarContext) => void;
10266
+ };
10267
+ };
10268
+ };
10081
10269
  export const anchors: {
10082
10270
  group: {
10083
10271
  anchor: {
@@ -10099,7 +10287,11 @@ declare module 'alinea/field/richtext/Toolbar' {
10099
10287
  title: string;
10100
10288
  onSelect: ({ exec }: RichTextToolbarContext) => boolean;
10101
10289
  };
10102
- export function defaultToolbar(enableTables: boolean): ToolbarConfig;
10290
+ export interface DefaultToolbarOptions {
10291
+ enableImages?: boolean;
10292
+ enableTables?: boolean;
10293
+ }
10294
+ export function defaultToolbar({ enableImages, enableTables }?: DefaultToolbarOptions): ToolbarConfig;
10103
10295
  export {};
10104
10296
 
10105
10297
  }
@@ -10352,7 +10544,8 @@ declare module 'alinea' {
10352
10544
  declare module 'alinea/next' {
10353
10545
 
10354
10546
  export { createCMS } from 'alinea/adapter/next/cms';
10355
- export { createHandler } from 'alinea/adapter/next/handler';
10547
+ export { createHandler, type NextHandlerOptions } from 'alinea/adapter/next/handler';
10548
+ export type { AfterCommitContext, BeforeCommitContext } from 'alinea/backend/Handler';
10356
10549
  export { withAlinea } from 'alinea/adapter/next/with-alinea';
10357
10550
 
10358
10551
  }
@@ -10360,7 +10553,8 @@ declare module 'alinea/next' {
10360
10553
  declare module 'alinea/next.edge' {
10361
10554
 
10362
10555
  export { createCMS } from 'alinea/adapter/next/cms';
10363
- export { createHandler } from 'alinea/adapter/next/handler';
10556
+ export { createHandler, type NextHandlerOptions } from 'alinea/adapter/next/handler';
10557
+ export type { AfterCommitContext, BeforeCommitContext } from 'alinea/backend/Handler';
10364
10558
 
10365
10559
  }
10366
10560
 
@@ -11083,6 +11277,7 @@ declare module 'alinea/ui/RichText' {
11083
11277
  li?: ComponentType<JSX.IntrinsicElements['li']> | ReactElement;
11084
11278
  blockquote?: ComponentType<JSX.IntrinsicElements['blockquote']> | ReactElement;
11085
11279
  hr?: ComponentType<JSX.IntrinsicElements['hr']> | ReactElement;
11280
+ img?: ComponentType<JSX.IntrinsicElements['img']> | ReactElement;
11086
11281
  br?: ComponentType<JSX.IntrinsicElements['br']> | ReactElement;
11087
11282
  small?: ComponentType<JSX.IntrinsicElements['small']> | ReactElement;
11088
11283
  sub?: ComponentType<JSX.IntrinsicElements['sub']> | ReactElement;