@mjml-agent-editor/editor 0.1.11 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -98,6 +98,29 @@ satisfying the two interfaces works, including an in-memory object.
98
98
 
99
99
  Forgetting the provider throws with an explanation rather than failing on a null read.
100
100
 
101
+ ### Images
102
+
103
+ The image picker — opened by double-clicking an image, from its toolbar, or from the
104
+ Settings panel — uploads to and picks from an optional `images` library. Where the files
105
+ live is up to the host: S3, R2, a CDN.
106
+
107
+ ```tsx
108
+ const images: ImageLibrary = {
109
+ list: () => fetch("/api/images").then((r) => r.json()), // { images, quota? }
110
+ upload: (file) => fetch("/api/images", { method: "POST", body: file }).then((r) => r.json()),
111
+ remove: (id) => fetch(`/api/images/${id}`, { method: "DELETE" }).then(() => {}),
112
+ };
113
+
114
+ <EditorStoreProvider stores={{ documents, comments, images }}>
115
+ ```
116
+
117
+ `quota` (`{ used, limit }`) is shown in the picker and stops uploads when reached. Leave
118
+ `remove` out for a read-only gallery — a host that caps uploads but cannot reclaim the
119
+ storage would otherwise be handing out a way round its own cap.
120
+
121
+ Without a library the picker takes URLs only. The editor never inlines a file as base64:
122
+ most mail clients block `data:` images, and every agent turn would pay for the bytes.
123
+
101
124
  ## Copy
102
125
 
103
126
  Every word the editor renders comes from a dictionary with English defaults, so a host
@@ -173,6 +196,29 @@ of the message that started it; keep that message somewhere and put it back into
173
196
  written, so a host's own sentence about limits or a document that is already busy reaches
174
197
  them intact.
175
198
 
199
+ ## When the host refuses
200
+
201
+ `onBeforeSend` flushes unsaved canvas changes before a turn, and **a rejection stops the
202
+ turn**, keeping the prompt in the box: the agent reads the stored document, so it would
203
+ otherwise answer about a version the visitor has moved past. The flush writes only when
204
+ the canvas differs from what the store last returned.
205
+
206
+ While a turn runs, from that flush until the document it left is loaded, the canvas is
207
+ read only, so the agent is the only writer. `ChatPanel` and `EmailEditor` coordinate this
208
+ through `EditorStoreProvider`; nothing needs wiring.
209
+
210
+ The visitor sees the host's own sentence when the rejection carries one:
211
+
212
+ | The rejection | Shown |
213
+ | ---------------------------------------- | --------------------------- |
214
+ | a `status` outside 400–499 | `labels.documentSaveFailed` |
215
+ | message is `{"error": "..."}` | the `error` string |
216
+ | a `status` of 400–499, any other message | the `message`, unless HTML |
217
+ | no status and no recognizable body | `labels.documentSaveFailed` |
218
+
219
+ So a `DocumentStore.save` refusing a document over a size cap should throw with
220
+ `status: 413` and a sentence. Autosave reports the same way, under one toast id.
221
+
176
222
  ## A note on field names
177
223
 
178
224
  The ports are camelCase (`sectionId`, `objectId`, `projectData`); Postgres columns are