@agent-native/core-corpus 0.210.2 → 0.211.0
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +41 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +4 -2
- package/corpus/templates/analytics/CHANGELOG.md +18 -0
- package/corpus/templates/analytics/actions/build-data-index.ts +11 -2
- package/corpus/templates/analytics/actions/configure-content-collection.ts +29 -4
- package/corpus/templates/analytics/actions/configure-first-party-events-model.ts +9 -7
- package/corpus/templates/analytics/actions/create-analytics-public-key.ts +4 -0
- package/corpus/templates/analytics/actions/estimate-content-signups-cost.ts +72 -0
- package/corpus/templates/analytics/actions/estimate-query-cost.ts +16 -134
- package/corpus/templates/analytics/actions/list-sigma-workbooks.ts +123 -42
- package/corpus/templates/analytics/actions/migrate-sigma-workbook.ts +20 -17
- package/corpus/templates/analytics/actions/revoke-analytics-public-key.ts +4 -0
- package/corpus/templates/analytics/app/components/dashboard/SigmaMigrationDialog.tsx +246 -680
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/analytics/app/i18n/en-US.ts +54 -55
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +0 -1
- package/corpus/templates/analytics/app/pages/DataSources.tsx +56 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/filter-vars.ts +4 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +26 -8
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/interpolate.ts +3 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/panel-cost-notice.ts +172 -0
- package/corpus/templates/analytics/app/pages/data-sources/SearchConsoleDetail.tsx +441 -0
- package/corpus/templates/analytics/changelog/2026-10-15-a-content-dashboard-lists-every-blog-article-with-its-author.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-15-data-sources-has-a-google-search-console-card-that-shows-the.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-16-the-content-dashboard-can-show-signups-per-blog-article.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-19-creating-or-revoking-a-public-analytics-key-now-asks-you-to-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-19-search-sigma-workbooks-by-name-and-open-ones-a-teammate-alre.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-blog-signup-attribution-excludes-signups-before-the-first-vi.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-collapsed-analytics-navigation-starts-at-the-top.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-content-keeps-successful-coverage-dates-and-missing-day-gaps.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-private-github-repositories-can-be-indexed-with-your-connect.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-search-console-preserves-backfill-and-paused-collection.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-search-console-refreshes-historical-coverage-when-properties.md +6 -0
- package/corpus/templates/analytics/changelog/2026-10-20-search-console-setup-keeps-saved-properties-readable-and-sup.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/content-view.json +182 -0
- package/corpus/templates/analytics/server/db/schema.ts +1 -0
- package/corpus/templates/analytics/server/lib/bi-migration/external-dashboards-store.ts +56 -18
- package/corpus/templates/analytics/server/lib/bi-migration/unfinished-import.ts +64 -0
- package/corpus/templates/analytics/server/lib/builtin-dashboard-pass.ts +17 -2
- package/corpus/templates/analytics/server/lib/content-metrics/collect.ts +2 -0
- package/corpus/templates/analytics/server/lib/content-metrics/config.ts +92 -3
- package/corpus/templates/analytics/server/lib/content-metrics/legacy-content-view.json +172 -0
- package/corpus/templates/analytics/server/lib/content-metrics/migration.ts +2 -0
- package/corpus/templates/analytics/server/lib/content-metrics/steps/daily-metrics.ts +8 -3
- package/corpus/templates/analytics/server/lib/content-metrics/steps/search-console.ts +16 -3
- package/corpus/templates/analytics/server/lib/content-metrics/steps/signups.ts +240 -0
- package/corpus/templates/analytics/server/lib/content-metrics/store.ts +5 -0
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +21 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-verification.ts +300 -5
- package/corpus/templates/analytics/server/lib/dashboard-seeds.ts +2 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +28 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +128 -24
- package/corpus/templates/analytics/server/lib/google-analytics.ts +56 -16
- package/corpus/templates/analytics/server/lib/index-build-github.ts +5 -0
- package/corpus/templates/analytics/server/lib/provider-credentials.ts +47 -2
- package/corpus/templates/analytics/server/lib/query-cost-estimate.ts +184 -5
- package/corpus/templates/analytics/server/plugins/db.ts +9 -1
- package/corpus/templates/analytics/shared/builtin-dashboard-ids.ts +2 -0
- package/corpus/templates/analytics/shared/search-console-property.ts +78 -0
- package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/calendar/actions/delete-event.ts +1 -3
- package/corpus/templates/calendar/actions/delete-events.ts +1 -2
- package/corpus/templates/calendar/actions/event-action-helpers.ts +0 -4
- package/corpus/templates/calendar/actions/update-event.ts +2 -6
- package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/clips/CHANGELOG.md +11 -24
- package/corpus/templates/clips/actions/create-recording-upload.ts +5 -1
- package/corpus/templates/clips/app/components/player/chapter-list.tsx +7 -6
- package/corpus/templates/clips/app/components/player/comment-composer.tsx +5 -1
- package/corpus/templates/clips/app/components/player/player-controls.tsx +1 -0
- package/corpus/templates/clips/app/components/player/scrubber.tsx +4 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -3
- package/corpus/templates/clips/app/lib/extension-auth.ts +70 -0
- package/corpus/templates/clips/app/root.tsx +22 -10
- package/corpus/templates/clips/app/routes/_app.notifications.tsx +3 -0
- package/corpus/templates/clips/app/routes/import.tsx +115 -110
- package/corpus/templates/clips/changelog/2026-10-16-agent-uploads-can-use-free-clips-storage.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-agents-see-a-clip-s-frames-as-soon-as-it-finishes-processing.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-chapter-list-times-now-match-the-player-s-clock-and-each-cha.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-editing-a-comment-puts-the-cursor-after-its-text-and-reply-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-19-youtube-import-followups.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-20-locally-saved-desktop-recordings-now-appear-in-the-recovery-.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +29 -186
- package/corpus/templates/clips/desktop/src/components/RecordingRecovery.tsx +171 -16
- package/corpus/templates/clips/desktop/src/lib/record-first.ts +9 -32
- package/corpus/templates/clips/desktop/src/lib/recording-recovery.ts +30 -1
- package/corpus/templates/clips/server/lib/agent-frame-request.ts +5 -2
- package/corpus/templates/clips/server/lib/recording-upload-ticket.ts +8 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +2 -0
- package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/content/CHANGELOG.md +12 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +5 -15
- package/corpus/templates/content/actions/_database-navigation.ts +3 -3
- package/corpus/templates/content/actions/_database-utils.ts +10 -22
- package/corpus/templates/content/actions/_database-view-setup.ts +16 -76
- package/corpus/templates/content/actions/create-comment-ai-suggestion.ts +93 -44
- package/corpus/templates/content/actions/export-document.ts +2 -14
- package/corpus/templates/content/actions/suggest-document-edit.ts +5 -7
- package/corpus/templates/content/actions/update-content-database-view.ts +2 -14
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +86 -30
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +64 -28
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +6 -46
- package/corpus/templates/content/app/components/editor/PageDraftRecovery.tsx +72 -7
- package/corpus/templates/content/app/components/editor/TableHoverControls.tsx +292 -103
- package/corpus/templates/content/app/components/editor/ThreadSuggestion.tsx +147 -40
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +108 -11
- package/corpus/templates/content/app/components/editor/database/ContentTable.tsx +2 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +150 -166
- package/corpus/templates/content/app/components/editor/database/database-cell-comments.tsx +515 -0
- package/corpus/templates/content/app/components/editor/database/database-item-comments.tsx +5 -43
- package/corpus/templates/content/app/components/editor/database/filter-sort.ts +8 -783
- package/corpus/templates/content/app/components/editor/live-editor-session.ts +5 -1
- package/corpus/templates/content/app/components/editor/page-draft-journal.ts +61 -1
- package/corpus/templates/content/app/components/editor/property-comments.tsx +35 -4
- package/corpus/templates/content/app/components/editor/property-date-format.ts +45 -0
- package/corpus/templates/content/app/components/editor/thread-suggestions.ts +30 -0
- package/corpus/templates/content/app/components/editor/useDocumentReconcileRecovery.ts +23 -4
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +36 -10
- package/corpus/templates/content/app/global.css +23 -0
- package/corpus/templates/content/app/i18n-data.ts +1 -0
- package/corpus/templates/content/changelog/2026-10-16-opening-a-page-in-a-new-tab-while-another-tab-is-still-savin.md +6 -0
- package/corpus/templates/content/changelog/2026-10-16-typing-steadily-in-one-tab-no-longer-makes-another-open-tab-.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-database-views-can-filter-the-same-property-more-than-once-n.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-edits-made-from-a-block-s-menu-or-a-table-s-row-and-column-m.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-starting-a-comment-puts-the-cursor-in-the-comment-box-ready-.md +6 -0
- package/corpus/templates/content/changelog/2026-10-19-table-row-and-column-options-now-appear-for-the-row-or-colum.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.comment.page-owned.md +5 -1
- package/corpus/templates/content/docs/product/capabilities/content.revision.suggestions.md +3 -1
- package/corpus/templates/content/e2e/helpers.ts +10 -0
- package/corpus/templates/content/shared/api.ts +18 -12
- package/corpus/templates/content/shared/database-query.ts +107 -13
- package/corpus/templates/content/shared/suggestion-diff.ts +35 -0
- package/corpus/templates/crm/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/design/CHANGELOG.md +2 -0
- package/corpus/templates/design/actions/delete-file.ts +1 -4
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +10 -1
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +24 -4
- package/corpus/templates/design/app/pages/design-editor/commands/mode-change.ts +14 -9
- package/corpus/templates/design/app/pages/design-editor/domains/use-editor-modes.ts +23 -2
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +29 -0
- package/corpus/templates/design/changelog/2026-10-19-reply-and-edit-on-a-comment-in-the-sidebar-or-on-a-canvas-pi.md +6 -0
- package/corpus/templates/design/changelog/2026-10-20-comments-return-to-the-mode-they-came-from-and-layers-search.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +185 -85
- package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/dispatch/CHANGELOG.md +4 -0
- package/corpus/templates/dispatch/actions/apply-workspace-connection-setup.ts +4 -0
- package/corpus/templates/dispatch/actions/delete-workspace-connection.ts +4 -0
- package/corpus/templates/dispatch/actions/set-workspace-connection-grant.ts +4 -0
- package/corpus/templates/dispatch/actions/upsert-workspace-connection.ts +4 -0
- package/corpus/templates/dispatch/changelog/2026-10-19-vault-secrets-grants-link-tokens-app-access-and-workspace-co.md +6 -0
- package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +105 -33
- package/corpus/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +128 -74
- package/corpus/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +39 -11
- package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/mail/.agents/skills/contacts-and-crm/SKILL.md +22 -17
- package/corpus/templates/mail/AGENTS.md +1 -1
- package/corpus/templates/mail/CHANGELOG.md +14 -0
- package/corpus/templates/mail/actions/provider-api-request.ts +3 -3
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +211 -54
- package/corpus/templates/mail/app/hooks/use-inbox-threads.ts +26 -2
- package/corpus/templates/mail/app/i18n/en-US.ts +5 -1
- package/corpus/templates/mail/app/lib/gong-connection.ts +27 -0
- package/corpus/templates/mail/app/lib/thread-cache.ts +110 -9
- package/corpus/templates/mail/app/root.tsx +10 -2
- package/corpus/templates/mail/changelog/2026-10-20-connected-gong-settings-now-open-the-shared-integration-mana.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-gong-connection-details-now-match-the-call-data-available-in.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-improve-gong-setup-with-a-click-to-connect-flow-and-permissi.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-mail-lets-you-retry-when-it-cannot-check-your-gong-access.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-mail-thread-cache-stays-isolated-when-mailbox-scope-changes.md +6 -0
- package/corpus/templates/mail/changelog/2026-10-20-the-inbox-and-recently-opened-threads-now-open-instantly-fro.md +6 -0
- package/corpus/templates/mail/server/handlers/emails.ts +9 -0
- package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/plan/CHANGELOG.md +4 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +173 -33
- package/corpus/templates/plan/changelog/2026-10-19-opening-a-comment-thread-puts-the-cursor-in-the-reply-box-an.md +6 -0
- package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +5 -3
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +6 -42
- package/corpus/templates/slides/app/components/editor/FloatingToolbar.tsx +3 -7
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +5 -14
- package/corpus/templates/slides/app/i18n/en-US.ts +0 -2
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +27 -33
- package/corpus/templates/slides/scripts/edit-fidelity/run.ts +1 -3
- package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +5 -3
- package/package.json +1 -1
|
@@ -171,6 +171,10 @@ import {
|
|
|
171
171
|
PropertyCommentControl,
|
|
172
172
|
usePropertyCommentRowState,
|
|
173
173
|
} from "./property-comments";
|
|
174
|
+
import {
|
|
175
|
+
formatPropertyDate,
|
|
176
|
+
formatPropertyDateTime,
|
|
177
|
+
} from "./property-date-format";
|
|
174
178
|
|
|
175
179
|
type TFunction = ReturnType<typeof useT>;
|
|
176
180
|
|
|
@@ -282,56 +286,12 @@ function slugify(value: string) {
|
|
|
282
286
|
return slug || `option-${Date.now()}`;
|
|
283
287
|
}
|
|
284
288
|
|
|
285
|
-
function formatDate(value: string) {
|
|
286
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
287
|
-
const [year, month, day] = value.split("-").map(Number);
|
|
288
|
-
return new Intl.DateTimeFormat(undefined, {
|
|
289
|
-
month: "short",
|
|
290
|
-
day: "numeric",
|
|
291
|
-
year: "numeric",
|
|
292
|
-
}).format(new Date(year, month - 1, day));
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const date = new Date(value);
|
|
296
|
-
if (Number.isNaN(date.getTime())) return value;
|
|
297
|
-
return new Intl.DateTimeFormat(undefined, {
|
|
298
|
-
month: "short",
|
|
299
|
-
day: "numeric",
|
|
300
|
-
year: "numeric",
|
|
301
|
-
}).format(date);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
function formatDateTime(value: string) {
|
|
305
|
-
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value)) {
|
|
306
|
-
const [datePart, timePart] = value.split("T");
|
|
307
|
-
const [year, month, day] = datePart.split("-").map(Number);
|
|
308
|
-
const [hour, minute] = timePart.split(":").map(Number);
|
|
309
|
-
return new Intl.DateTimeFormat(undefined, {
|
|
310
|
-
month: "short",
|
|
311
|
-
day: "numeric",
|
|
312
|
-
year: "numeric",
|
|
313
|
-
hour: "numeric",
|
|
314
|
-
minute: "2-digit",
|
|
315
|
-
}).format(new Date(year, month - 1, day, hour, minute));
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const date = new Date(value);
|
|
319
|
-
if (Number.isNaN(date.getTime())) return value;
|
|
320
|
-
return new Intl.DateTimeFormat(undefined, {
|
|
321
|
-
month: "short",
|
|
322
|
-
day: "numeric",
|
|
323
|
-
year: "numeric",
|
|
324
|
-
hour: "numeric",
|
|
325
|
-
minute: "2-digit",
|
|
326
|
-
}).format(date);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
289
|
function formatPropertyDateDisplayValue(
|
|
330
290
|
value: DocumentProperty["value"],
|
|
331
291
|
t?: TFunction,
|
|
332
292
|
) {
|
|
333
293
|
const includeTime = documentPropertyDateIncludesTime(value);
|
|
334
|
-
const formatter = includeTime ?
|
|
294
|
+
const formatter = includeTime ? formatPropertyDateTime : formatPropertyDate;
|
|
335
295
|
const start = documentPropertyDatePart(value, "start");
|
|
336
296
|
const end = documentPropertyDatePart(value, "end");
|
|
337
297
|
if (!start) return tWithFallback(t, "editor.properties.empty", "Empty");
|
|
@@ -392,7 +352,7 @@ export function displayValue(
|
|
|
392
352
|
}
|
|
393
353
|
|
|
394
354
|
if (type === "created_time" || type === "last_edited_time") {
|
|
395
|
-
return <span>{
|
|
355
|
+
return <span>{formatPropertyDateTime(propertyText(value))}</span>;
|
|
396
356
|
}
|
|
397
357
|
|
|
398
358
|
if (type === "person") {
|
|
@@ -37,6 +37,7 @@ import { DocumentEditorSkeleton } from "./DocumentEditorSkeleton";
|
|
|
37
37
|
import { LiveEditorSessionContext } from "./live-editor-session";
|
|
38
38
|
import {
|
|
39
39
|
clearPageDraftJournal,
|
|
40
|
+
liveDraftWriterIds,
|
|
40
41
|
readPageDraftJournal,
|
|
41
42
|
sweepLegacyRetainedPageDraftMarkers,
|
|
42
43
|
writePageDraftJournal,
|
|
@@ -110,6 +111,20 @@ export function PageDraftRecovery({
|
|
|
110
111
|
"checking" | "promoting" | "waiting_sql" | "ready" | "failed"
|
|
111
112
|
>("checking");
|
|
112
113
|
const [journalRevision, setJournalRevision] = useState(0);
|
|
114
|
+
// Another tab's open editor settles its own journal entries; replaying one
|
|
115
|
+
// here races its save queue and sends a save for text nobody typed here.
|
|
116
|
+
// A query only knows the editors open when it ran, so it holds for the
|
|
117
|
+
// journal entry and SQL draft it was taken for; a tab opened since writes
|
|
118
|
+
// entries it misses.
|
|
119
|
+
const [liveWriters, setLiveWriters] = useState<{
|
|
120
|
+
scopeKey: string;
|
|
121
|
+
entryKey: string | null;
|
|
122
|
+
draftKey: string | null;
|
|
123
|
+
writerIds: ReadonlySet<string>;
|
|
124
|
+
} | null>(null);
|
|
125
|
+
const scopeLiveWriters =
|
|
126
|
+
liveWriters && liveWriters.scopeKey === scopeKey ? liveWriters : null;
|
|
127
|
+
const skippedWriterIds = scopeLiveWriters?.writerIds;
|
|
113
128
|
const journalAttemptRef = useRef<string | null>(null);
|
|
114
129
|
const automaticRecoveryRef = useRef<string | null>(null);
|
|
115
130
|
const automaticLegacyRecoveryRef = useRef<string | null>(null);
|
|
@@ -124,6 +139,17 @@ export function PageDraftRecovery({
|
|
|
124
139
|
drafts.data.draft.editorSessionId === liveEditorSessionId
|
|
125
140
|
? null
|
|
126
141
|
: drafts.data?.draft;
|
|
142
|
+
// So does an editor open in another tab; settling its draft here would move
|
|
143
|
+
// text it is still saving to History. Its draft can outlive its journal
|
|
144
|
+
// entry, or have none when that write failed, so the draft is checked too.
|
|
145
|
+
const draftKey = draft?.editorSessionId
|
|
146
|
+
? `${draft.editorSessionId}:${draft.editGeneration}:${draft.version}`
|
|
147
|
+
: null;
|
|
148
|
+
const draftLivenessKnown =
|
|
149
|
+
draftKey === null || scopeLiveWriters?.draftKey === draftKey;
|
|
150
|
+
const draftOpenElsewhere = Boolean(
|
|
151
|
+
draft?.editorSessionId && skippedWriterIds?.has(draft.editorSessionId),
|
|
152
|
+
);
|
|
127
153
|
// No scope until the session read returns; the session cache expires, so a
|
|
128
154
|
// page opened later can mount before then. Unverified until it does.
|
|
129
155
|
const scopeVerified = scopeKey !== null && verifiedScopeKey === scopeKey;
|
|
@@ -190,11 +216,40 @@ export function PageDraftRecovery({
|
|
|
190
216
|
};
|
|
191
217
|
let entry;
|
|
192
218
|
try {
|
|
193
|
-
entry = readPageDraftJournal(scope);
|
|
219
|
+
entry = readPageDraftJournal(scope, skippedWriterIds);
|
|
194
220
|
} catch {
|
|
195
221
|
setJournalState("failed");
|
|
196
222
|
return;
|
|
197
223
|
}
|
|
224
|
+
const entryKey = entry
|
|
225
|
+
? `${entry.scope.writerId}:${entry.snapshot.editGeneration}:${entry.writtenAt}`
|
|
226
|
+
: null;
|
|
227
|
+
if (
|
|
228
|
+
scopeKey &&
|
|
229
|
+
((entryKey !== null && scopeLiveWriters?.entryKey !== entryKey) ||
|
|
230
|
+
!draftLivenessKnown)
|
|
231
|
+
) {
|
|
232
|
+
let cancelled = false;
|
|
233
|
+
void liveDraftWriterIds().then(
|
|
234
|
+
(writerIds) => {
|
|
235
|
+
// Without Web Locks no writer reads as live, so every entry
|
|
236
|
+
// replays, as it did before writer locks.
|
|
237
|
+
if (!cancelled)
|
|
238
|
+
setLiveWriters({
|
|
239
|
+
scopeKey,
|
|
240
|
+
entryKey,
|
|
241
|
+
draftKey,
|
|
242
|
+
writerIds: writerIds ?? new Set(),
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
() => {
|
|
246
|
+
if (!cancelled) setJournalState("failed");
|
|
247
|
+
},
|
|
248
|
+
);
|
|
249
|
+
return () => {
|
|
250
|
+
cancelled = true;
|
|
251
|
+
};
|
|
252
|
+
}
|
|
198
253
|
if (!entry) {
|
|
199
254
|
sweepLegacyRetainedPageDraftMarkers();
|
|
200
255
|
setJournalState("ready");
|
|
@@ -471,6 +526,8 @@ export function PageDraftRecovery({
|
|
|
471
526
|
editorReleased,
|
|
472
527
|
journalRevision,
|
|
473
528
|
journalState,
|
|
529
|
+
scopeKey,
|
|
530
|
+
scopeLiveWriters,
|
|
474
531
|
scopeVerified,
|
|
475
532
|
session?.email,
|
|
476
533
|
session?.orgId,
|
|
@@ -690,6 +747,8 @@ export function PageDraftRecovery({
|
|
|
690
747
|
if (
|
|
691
748
|
!draft ||
|
|
692
749
|
!hasEditIdentity ||
|
|
750
|
+
!draftLivenessKnown ||
|
|
751
|
+
draftOpenElsewhere ||
|
|
693
752
|
busy ||
|
|
694
753
|
failure ||
|
|
695
754
|
journalState === "checking" ||
|
|
@@ -712,11 +771,14 @@ export function PageDraftRecovery({
|
|
|
712
771
|
}
|
|
713
772
|
if (session?.email) {
|
|
714
773
|
try {
|
|
715
|
-
const journal = readPageDraftJournal(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
774
|
+
const journal = readPageDraftJournal(
|
|
775
|
+
{
|
|
776
|
+
accountId: session.email.trim().toLowerCase(),
|
|
777
|
+
orgId: session.orgId ?? null,
|
|
778
|
+
documentId: document.id,
|
|
779
|
+
},
|
|
780
|
+
skippedWriterIds,
|
|
781
|
+
);
|
|
720
782
|
if (
|
|
721
783
|
journal?.snapshot.title === draft.title &&
|
|
722
784
|
journal.snapshot.content === draft.content
|
|
@@ -733,12 +795,15 @@ export function PageDraftRecovery({
|
|
|
733
795
|
busy,
|
|
734
796
|
document,
|
|
735
797
|
draft,
|
|
798
|
+
draftLivenessKnown,
|
|
799
|
+
draftOpenElsewhere,
|
|
736
800
|
failure,
|
|
737
801
|
hasEditIdentity,
|
|
738
802
|
journalState,
|
|
739
803
|
scopeVerified,
|
|
740
804
|
session?.email,
|
|
741
805
|
session?.orgId,
|
|
806
|
+
skippedWriterIds,
|
|
742
807
|
]);
|
|
743
808
|
|
|
744
809
|
// Keep the editor at one tree position so a notice never remounts it.
|
|
@@ -795,7 +860,7 @@ export function PageDraftRecovery({
|
|
|
795
860
|
}
|
|
796
861
|
/>
|
|
797
862
|
);
|
|
798
|
-
if (!draft) return withNotice(null);
|
|
863
|
+
if (!draft || draftOpenElsewhere) return withNotice(null);
|
|
799
864
|
// Legacy drafts are preserved automatically; that path toasts once.
|
|
800
865
|
if (!hasEditIdentity && !failure) return withNotice(null);
|
|
801
866
|
if (!failure)
|