@elytracms/studio 0.0.99 → 0.0.101

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 (133) hide show
  1. package/convex/analytics-cost.test.ts +1 -1
  2. package/convex/cms.ts +29 -2
  3. package/convex/records-column-transform.convex.test.ts +5 -3
  4. package/convex/records-one-write.convex.test.ts +218 -0
  5. package/convex/redirect-migration.test.ts +1 -1
  6. package/convex/redirects.ts +2 -2
  7. package/convex/shared-capture.convex.test.ts +165 -0
  8. package/convex/version-kind-stamping.test.ts +118 -0
  9. package/dist/components/ai/ai-chat-panel-lazy.js +7 -2
  10. package/dist/components/ai/ai-chat-panel-lazy.js.map +1 -1
  11. package/dist/components/ai/proposal-card.js +2 -1
  12. package/dist/components/ai/proposal-card.js.map +1 -1
  13. package/dist/components/ai/proposal-unfilled.d.ts +14 -0
  14. package/dist/components/ai/proposal-unfilled.js +33 -0
  15. package/dist/components/ai/proposal-unfilled.js.map +1 -0
  16. package/dist/components/ai/translate-document-action.js +8 -6
  17. package/dist/components/ai/translate-document-action.js.map +1 -1
  18. package/dist/components/app-views/studio-config.d.ts +12 -12
  19. package/dist/components/app-views/studio-config.js.map +1 -1
  20. package/dist/components/builder/builder-store.d.ts +37 -1
  21. package/dist/components/builder/builder-store.js +21 -6
  22. package/dist/components/builder/builder-store.js.map +1 -1
  23. package/dist/components/builder/canvas-chrome-css.d.ts +1 -1
  24. package/dist/components/builder/canvas-chrome-css.js +1 -1
  25. package/dist/components/builder/canvas-chrome-css.js.map +1 -1
  26. package/dist/components/builder/canvas-chrome.d.ts +1 -1
  27. package/dist/components/builder/canvas-chrome.js +1 -1
  28. package/dist/components/builder/canvas-chrome.js.map +1 -1
  29. package/dist/components/builder/canvas-rebase.d.ts +4 -4
  30. package/dist/components/builder/canvas-rebase.js +3 -2
  31. package/dist/components/builder/canvas-rebase.js.map +1 -1
  32. package/dist/components/builder/canvas-render-context.d.ts +1 -1
  33. package/dist/components/builder/canvas-render-context.js +1 -1
  34. package/dist/components/builder/canvas-render-context.js.map +1 -1
  35. package/dist/components/builder/composition-field-editor-lazy.js +2 -1
  36. package/dist/components/builder/composition-field-editor-lazy.js.map +1 -1
  37. package/dist/components/builder/reuse-context.d.ts +8 -2
  38. package/dist/components/builder/reuse-context.js +62 -7
  39. package/dist/components/builder/reuse-context.js.map +1 -1
  40. package/dist/components/builder/reuse.d.ts +106 -70
  41. package/dist/components/builder/reuse.js +125 -108
  42. package/dist/components/builder/reuse.js.map +1 -1
  43. package/dist/components/cms/cms-store.d.ts +9 -1
  44. package/dist/components/cms/cms-store.js +1 -0
  45. package/dist/components/cms/cms-store.js.map +1 -1
  46. package/dist/components/cms/detail-editor.js +13 -13
  47. package/dist/components/cms/detail-editor.js.map +1 -1
  48. package/dist/components/cms/prop-fields.js +1 -1
  49. package/dist/components/cms/prop-fields.js.map +1 -1
  50. package/dist/components/cms/rich-text/lazy.js +2 -1
  51. package/dist/components/cms/rich-text/lazy.js.map +1 -1
  52. package/dist/components/cms/rich-text/toolbar-state.d.ts +1 -1
  53. package/dist/components/cms/rich-text/toolbar-state.js +1 -1
  54. package/dist/components/cms/rich-text/toolbar-state.js.map +1 -1
  55. package/dist/components/cms/use-field-focus.js +3 -3
  56. package/dist/components/cms/use-field-focus.js.map +1 -1
  57. package/dist/components/cms/version-compare-lazy.js +2 -1
  58. package/dist/components/cms/version-compare-lazy.js.map +1 -1
  59. package/dist/components/components/components-index.js +1 -1
  60. package/dist/components/components/components-index.js.map +1 -1
  61. package/dist/components/deployment-setup-gate.d.ts +1 -1
  62. package/dist/components/deployment-setup-gate.js +1 -1
  63. package/dist/components/deployment-setup-gate.js.map +1 -1
  64. package/dist/components/load-failure.d.ts +62 -0
  65. package/dist/components/load-failure.js +110 -0
  66. package/dist/components/load-failure.js.map +1 -0
  67. package/dist/components/notifications/shell-findings.js +3 -3
  68. package/dist/components/notifications/shell-findings.js.map +1 -1
  69. package/dist/components/records/record-rail.js +16 -5
  70. package/dist/components/records/record-rail.js.map +1 -1
  71. package/dist/customization.d.ts +3 -3
  72. package/dist/customization.js.map +1 -1
  73. package/dist/lib/ai/apply-content.js +99 -28
  74. package/dist/lib/ai/apply-content.js.map +1 -1
  75. package/dist/lib/ai/chat-context.d.ts +73 -7
  76. package/dist/lib/ai/chat-context.js +133 -14
  77. package/dist/lib/ai/chat-context.js.map +1 -1
  78. package/dist/lib/ai/chat-state.d.ts +7 -1
  79. package/dist/lib/ai/chat-state.js.map +1 -1
  80. package/dist/lib/ai/constraints.d.ts +5 -0
  81. package/dist/lib/ai/constraints.js +21 -6
  82. package/dist/lib/ai/constraints.js.map +1 -1
  83. package/dist/lib/ai/fake-provider.d.ts +76 -26
  84. package/dist/lib/ai/fake-provider.js +210 -66
  85. package/dist/lib/ai/fake-provider.js.map +1 -1
  86. package/dist/lib/ai/index.d.ts +1 -0
  87. package/dist/lib/ai/index.js +1 -0
  88. package/dist/lib/ai/index.js.map +1 -1
  89. package/dist/lib/ai/keyless-assistant.d.ts +37 -0
  90. package/dist/lib/ai/keyless-assistant.js +193 -0
  91. package/dist/lib/ai/keyless-assistant.js.map +1 -0
  92. package/dist/lib/ai/shape.d.ts +25 -2
  93. package/dist/lib/ai/shape.js +58 -7
  94. package/dist/lib/ai/shape.js.map +1 -1
  95. package/dist/lib/ai/tools.d.ts +11 -1
  96. package/dist/lib/ai/tools.js +51 -6
  97. package/dist/lib/ai/tools.js.map +1 -1
  98. package/dist/lib/ai/translate-document.js +6 -5
  99. package/dist/lib/ai/translate-document.js.map +1 -1
  100. package/dist/lib/ai/types.d.ts +22 -7
  101. package/dist/lib/ai/types.js.map +1 -1
  102. package/dist/lib/ai/update-fields.js +9 -6
  103. package/dist/lib/ai/update-fields.js.map +1 -1
  104. package/dist/lib/ai/writer-form.d.ts +11 -3
  105. package/dist/lib/ai/writer-form.js +105 -18
  106. package/dist/lib/ai/writer-form.js.map +1 -1
  107. package/dist/lib/auth-errors.d.ts +1 -1
  108. package/dist/lib/auth-errors.js +1 -1
  109. package/dist/lib/auth-errors.js.map +1 -1
  110. package/dist/lib/engine-version.d.ts +1 -1
  111. package/dist/lib/engine-version.js +1 -1
  112. package/dist/lib/engine-version.js.map +1 -1
  113. package/dist/lib/i18n/messages.de.d.ts +1 -1
  114. package/dist/lib/i18n/messages.de.js +24 -7
  115. package/dist/lib/i18n/messages.de.js.map +1 -1
  116. package/dist/lib/i18n/messages.en.d.ts +19 -3
  117. package/dist/lib/i18n/messages.en.js +30 -9
  118. package/dist/lib/i18n/messages.en.js.map +1 -1
  119. package/dist/lib/operations/cms-persistence.d.ts +18 -0
  120. package/dist/lib/operations/cms-persistence.js +56 -15
  121. package/dist/lib/operations/cms-persistence.js.map +1 -1
  122. package/dist/lib/persistence/convex-adapter.d.ts +2 -0
  123. package/dist/lib/persistence/convex-adapter.js +67 -2
  124. package/dist/lib/persistence/convex-adapter.js.map +1 -1
  125. package/dist/lib/workspace/index.d.ts +3 -3
  126. package/dist/lib/workspace/index.js +3 -3
  127. package/dist/lib/workspace/index.js.map +1 -1
  128. package/dist/router/navigate-once.d.ts +1 -1
  129. package/dist/router/navigate-once.js.map +1 -1
  130. package/dist/router/root.d.ts +3 -2
  131. package/dist/router/root.js +25 -4
  132. package/dist/router/root.js.map +1 -1
  133. package/package.json +3 -3
@@ -129,6 +129,14 @@ export type CommitOutcome = {
129
129
  readonly status: 'failed';
130
130
  readonly error: OperationError;
131
131
  };
132
+ /**
133
+ * EC-728 — what {@link CmsPersister.deleteCreated} did: `deleted`; `gone` (already deleted);
134
+ * `changed` (written since the create — edited or published); `referenced` (a strict relation
135
+ * references it); `not-created` (this session holds no create receipt for it); `failed`.
136
+ */
137
+ export type DeleteCreatedOutcome = 'deleted' | 'gone' | 'changed' | 'referenced' | 'not-created' | 'failed';
138
+ /** EC-728 — the refusal of a conditional delete, read off the operation's error (pure). */
139
+ export declare function deleteCreatedRefusal(error: OperationError): Exclude<DeleteCreatedOutcome, 'deleted' | 'not-created'>;
132
140
  export interface CmsPersister {
133
141
  /** Adopt a server row as this session's base for its document (hydration, a create result). */
134
142
  track(row: TrackedRow): void;
@@ -193,6 +201,16 @@ export interface CmsPersister {
193
201
  */
194
202
  replace(document: CmsDocument, revision: number | undefined, authoredOn?: CmsDocument): void;
195
203
  deleteDocument(ref: DocumentRef): void;
204
+ /**
205
+ * EC-728 — delete a document THIS session created, only while it is exactly as created:
206
+ * `documents.delete` with the precondition `{ revision }` = the revision this session's own
207
+ * create landed at (its receipt — never a later read), so a write by anyone since (an edit,
208
+ * a publish) refuses it in the store's own step, and the store's strict-referrer guard
209
+ * refuses it while a strict relation references it. Sent after every write queued before
210
+ * it. Nothing is reported on the session's error surface — a refusal is an expected answer
211
+ * the caller words; the session drops the document only once the store has deleted it.
212
+ */
213
+ deleteCreated(ref: DocumentRef): Promise<DeleteCreatedOutcome>;
196
214
  unpublishDocument(ref: DocumentRef): void;
197
215
  /**
198
216
  * Adopt a server row pushed by the document subscription (EC-595 point 7): applied
@@ -1,5 +1,15 @@
1
- import { applyDocumentPatches, documentKey, documentValueBuckets, expandValuePath, fieldPath, formatValuePath, isValuePathPrefix, readValueAt, selfTypeDocument, semanticValueEqual, touchedPaths, touchedPathsOfEntry, valuePathsOverlap, } from '@elytracms/core/cms-core';
1
+ import { applyDocumentPatches, documentKey, expandValuePath, fieldPositionPatches, formatValuePath, isValuePathPrefix, readValueAt, selfTypeDocument, semanticValueEqual, touchedPaths, touchedPathsOfEntry, valuePathsOverlap, } from '@elytracms/core/cms-core';
2
2
  import { createPersistQueue } from './persist-queue.js';
3
+ /** EC-728 — the refusal of a conditional delete, read off the operation's error (pure). */
4
+ export function deleteCreatedRefusal(error) {
5
+ if (error.code === 'not-found')
6
+ return 'gone';
7
+ if (error.code !== 'conflict')
8
+ return 'failed';
9
+ if ((error.referrers?.length ?? 0) > 0)
10
+ return 'referenced';
11
+ return error.current === null ? 'gone' : 'changed';
12
+ }
3
13
  /** EC-686 — a decomposed alias is re-sent at most this often (each time a colleague wrote the document in between). */
4
14
  const ALIAS_ATTEMPTS = 3;
5
15
  /** How many own writes a document's ledger keeps (an older base just stops lifting — a conflict, never a borrow). */
@@ -231,22 +241,16 @@ function withAlias(document, alias) {
231
241
  /**
232
242
  * EC-686 item 1 — what a whole-document snapshot changed against the view it was made from,
233
243
  * position by position: a `set` (or an `unset`, the value gone) of every field position —
234
- * `values[f]`, `localized[l][f]` — whose value differs by THE equality
235
- * (`documentValueBuckets` + `semanticValueEqual`, the document diff's own reading). Every
236
- * value change of a document is one of these; its slot `alias` is the one key that is not.
244
+ * `values[f]`, `localized[l][f]` — whose value differs by THE equality. Every value change of
245
+ * a document is one of these; its slot `alias` is the one key that is not.
246
+ *
247
+ * EC-703 (Codex round 6 F33): THE own-property per-position diff (`fieldPositionPatches`,
248
+ * cms-core — the one the publish strip reads too). This copy read `bucket.after[key]`, so a
249
+ * removed field named after an `Object.prototype` member became `set constructor = Object`
250
+ * and every later `documentOf` threw (measured).
237
251
  */
238
252
  function positionPatches(view, snapshot) {
239
- const patches = [];
240
- for (const bucket of documentValueBuckets(view, snapshot)) {
241
- for (const key of new Set([...Object.keys(bucket.before), ...Object.keys(bucket.after)])) {
242
- if (semanticValueEqual(bucket.before[key], bucket.after[key]))
243
- continue;
244
- const path = fieldPath(key, bucket.locale);
245
- const value = bucket.after[key];
246
- patches.push(value === undefined ? { op: 'unset', path } : { op: 'set', path, value });
247
- }
248
- }
249
- return patches;
253
+ return fieldPositionPatches(view, snapshot);
250
254
  }
251
255
  export function createCmsPersister(options) {
252
256
  const queue = createPersistQueue((error) => {
@@ -1188,6 +1192,43 @@ export function createCmsPersister(options) {
1188
1192
  emitDocument(entry);
1189
1193
  schedule(entry);
1190
1194
  },
1195
+ deleteCreated(ref) {
1196
+ const entry = entryOf(ref);
1197
+ return new Promise((resolve) => {
1198
+ // Queued like every write: whatever was committed before it is sent first.
1199
+ queue.push(async () => {
1200
+ if (entry.deleted)
1201
+ return resolve('gone');
1202
+ if (entry.created === undefined)
1203
+ return resolve('not-created');
1204
+ // A write of ours committed and not sent yet is an edit since the create.
1205
+ if (entry.queue.length > 0)
1206
+ return resolve('changed');
1207
+ const operations = await options.getOperations();
1208
+ entry.busy = true;
1209
+ try {
1210
+ const result = await operations.documents.delete({
1211
+ projectId: options.projectId,
1212
+ ref: entry.ref,
1213
+ precondition: { revision: entry.created },
1214
+ });
1215
+ if (result.ok) {
1216
+ markGone(entry);
1217
+ resolve('deleted');
1218
+ }
1219
+ else
1220
+ resolve(deleteCreatedRefusal(result.error));
1221
+ }
1222
+ catch {
1223
+ resolve('failed');
1224
+ }
1225
+ finally {
1226
+ entry.busy = false;
1227
+ adoptHeld(entry);
1228
+ }
1229
+ });
1230
+ });
1231
+ },
1191
1232
  deleteDocument(ref) {
1192
1233
  const entry = entryOf(ref);
1193
1234
  dropQueued(entry, { status: 'failed', error: goneError(ref) });