@agent-native/core 0.91.2 → 0.92.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 +2 -2
- package/corpus/core/CHANGELOG.md +17 -0
- package/corpus/core/docs/content/faq.mdx +17 -0
- package/corpus/core/docs/content/notifications.mdx +12 -6
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +140 -46
- package/corpus/core/src/agent/tool-search.ts +71 -4
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/upgrade.ts +798 -0
- package/corpus/core/src/client/AssistantChat.tsx +1 -1
- package/corpus/core/src/client/HighlightedCodeBlock.tsx +20 -3
- package/corpus/core/src/client/agent-chat-adapter.ts +31 -6
- package/corpus/core/src/client/chat/message-components.tsx +85 -8
- package/corpus/core/src/client/chat/tool-call-display.tsx +355 -144
- package/corpus/core/src/client/code-agent-chat-adapter.ts +2 -9
- package/corpus/core/src/client/session-replay.ts +3 -97
- package/corpus/core/src/client/settings/SettingsPanel.tsx +533 -389
- package/corpus/core/src/client/settings/SettingsSection.tsx +154 -17
- package/corpus/core/src/client/sse-event-processor.ts +29 -2
- package/corpus/core/src/extensions/actions.ts +113 -5
- package/corpus/core/src/notifications/channels.ts +88 -25
- package/corpus/core/src/notifications/registry.ts +17 -3
- package/corpus/core/src/notifications/types.ts +4 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +7 -3
- package/corpus/core/src/server/request-context.ts +7 -0
- package/corpus/core/src/styles/agent-conversation.css +1 -1
- package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/default/AGENTS.md +10 -3
- package/corpus/core/src/templates/default/package.json +2 -1
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/headless/AGENTS.md +9 -3
- package/corpus/core/src/templates/headless/package.json +1 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/workspace-root/AGENTS.md +10 -4
- package/corpus/core/src/templates/workspace-root/package.json +1 -0
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +5 -6
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/analytics/AGENTS.md +7 -5
- package/corpus/templates/analytics/actions/save-monitor.ts +14 -0
- package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +41 -6
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +122 -11
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +8 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +151 -32
- package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +17 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +4 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +54 -190
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-tables-keep-their-size-while-loading.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitoring-uptime-and-errors-tabs-now-clearly-show-which-view-is-active.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-uses-stock-rrweb-sizing-again-so-recorded.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-dashboard-menus-now-open-above-the-dashboard-canvas.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-uptime-alerting-clarifies-in-app-inbox-vs-email-and-lets-you-paste-slack-or-webhook-urls-per-monitor.md +6 -0
- package/corpus/templates/analytics/docs/uptime-monitoring.md +13 -11
- package/corpus/templates/analytics/server/db/schema-monitoring.ts +4 -0
- package/corpus/templates/analytics/server/lib/uptime-monitors.ts +60 -12
- package/corpus/templates/analytics/server/plugins/db.ts +10 -0
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-notes-stay-active-from-tray-and-shortcut-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-popovers-can-start-notes-and-join-the-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-notes-keep-their-recording-state-when-the-desktop.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-reminder-dropdowns-now-expand-fully-instead-of-being.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +123 -3
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +15 -1
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -0
- package/corpus/templates/clips/desktop/src/styles.css +23 -1
- package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +1 -3
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +40 -6
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -2
- package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +3 -5
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +23 -19
- package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +0 -1
- package/corpus/templates/clips/desktop/src-tauri/src/state.rs +5 -0
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -6
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/content/actions/_batch-utils.ts +8 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +7 -5
- package/corpus/templates/content/actions/_database-source-utils.ts +776 -319
- package/corpus/templates/content/actions/_database-utils.ts +6 -1
- package/corpus/templates/content/actions/_property-utils.ts +168 -0
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +19 -12
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +19 -12
- package/corpus/templates/content/actions/delete-document.ts +9 -13
- package/corpus/templates/content/actions/refresh-content-database-source.ts +5 -5
- package/corpus/templates/content/app/components/editor/body-hydration.ts +35 -11
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +47 -5
- package/corpus/templates/content/app/hooks/use-documents.ts +8 -2
- package/corpus/templates/content/changelog/2026-07-08-builder-source-sync-now-completes-reliably-on-hosted-databases.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-fixed-builder-database-sync-so-large-sources-continue-past-t.md +6 -0
- package/corpus/templates/content/server/plugins/db.ts +19 -0
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/videos/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/voice/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/agent/production-agent.d.ts +5 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +112 -42
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/tool-search.d.ts +2 -0
- package/dist/agent/tool-search.d.ts.map +1 -1
- package/dist/agent/tool-search.js +60 -4
- package/dist/agent/tool-search.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/upgrade.d.ts +100 -0
- package/dist/cli/upgrade.d.ts.map +1 -0
- package/dist/cli/upgrade.js +678 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/client/AssistantChat.js +1 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/HighlightedCodeBlock.d.ts +2 -0
- package/dist/client/HighlightedCodeBlock.d.ts.map +1 -1
- package/dist/client/HighlightedCodeBlock.js +10 -1
- package/dist/client/HighlightedCodeBlock.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +32 -4
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +61 -8
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +12 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +136 -42
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +2 -9
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/session-replay.d.ts +0 -8
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +3 -80
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +52 -19
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.d.ts +19 -4
- package/dist/client/settings/SettingsSection.d.ts.map +1 -1
- package/dist/client/settings/SettingsSection.js +33 -4
- package/dist/client/settings/SettingsSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +9 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +20 -2
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +85 -5
- package/dist/extensions/actions.js.map +1 -1
- package/dist/notifications/channels.d.ts +8 -3
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +61 -22
- package/dist/notifications/channels.js.map +1 -1
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +14 -3
- package/dist/notifications/registry.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/types.d.ts +4 -1
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/notifications/types.js.map +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-chat-plugin.d.ts +5 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/styles/agent-conversation.css +1 -1
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/default/AGENTS.md +10 -3
- package/dist/templates/default/package.json +2 -1
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/headless/AGENTS.md +9 -3
- package/dist/templates/headless/package.json +1 -0
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/workspace-root/AGENTS.md +10 -4
- package/dist/templates/workspace-root/package.json +1 -0
- package/docs/content/faq.mdx +17 -0
- package/docs/content/notifications.mdx +12 -6
- package/package.json +2 -2
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/default/AGENTS.md +10 -3
- package/src/templates/default/package.json +2 -1
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/headless/AGENTS.md +9 -3
- package/src/templates/headless/package.json +1 -0
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/workspace-root/AGENTS.md +10 -4
- package/src/templates/workspace-root/package.json +1 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-clamps-ultra-wide-viewports-while-keeping-the.md +0 -6
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
federateSources,
|
|
17
17
|
} from "./_federation-join.js";
|
|
18
18
|
import {
|
|
19
|
+
listPropertiesForDatabaseDocuments,
|
|
19
20
|
listPropertiesForDatabase,
|
|
20
21
|
serializeDatabase,
|
|
21
22
|
} from "./_property-utils.js";
|
|
@@ -197,6 +198,10 @@ export async function getContentDatabaseResponse(
|
|
|
197
198
|
)
|
|
198
199
|
: [];
|
|
199
200
|
const documentById = new Map(documents.map((doc) => [doc.id, doc]));
|
|
201
|
+
const propertiesByDocumentId = await listPropertiesForDatabaseDocuments(
|
|
202
|
+
databaseId,
|
|
203
|
+
documents,
|
|
204
|
+
);
|
|
200
205
|
const queuedBodyHydrationItemIds =
|
|
201
206
|
items.length > 0
|
|
202
207
|
? new Set(
|
|
@@ -234,7 +239,7 @@ export async function getContentDatabaseResponse(
|
|
|
234
239
|
bodyHydration: serializeBodyHydration(item, {
|
|
235
240
|
queued: bodyHydrationQueued,
|
|
236
241
|
}),
|
|
237
|
-
properties:
|
|
242
|
+
properties: propertiesByDocumentId.get(document.id) ?? [],
|
|
238
243
|
});
|
|
239
244
|
}
|
|
240
245
|
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
type DocumentPropertyType,
|
|
42
42
|
type DocumentPropertyValue,
|
|
43
43
|
} from "../shared/properties.js";
|
|
44
|
+
import { chunks } from "./_batch-utils.js";
|
|
44
45
|
|
|
45
46
|
type DocumentRow = InferSelectModel<typeof schema.documents>;
|
|
46
47
|
type ContentDatabaseRow = InferSelectModel<typeof schema.contentDatabases>;
|
|
@@ -526,6 +527,173 @@ export async function listPropertiesForDatabase(
|
|
|
526
527
|
return nextProperties;
|
|
527
528
|
}
|
|
528
529
|
|
|
530
|
+
function serializePropertyDefinition(
|
|
531
|
+
definition: typeof schema.documentPropertyDefinitions.$inferSelect,
|
|
532
|
+
) {
|
|
533
|
+
const type = definition.type as DocumentPropertyType;
|
|
534
|
+
return {
|
|
535
|
+
id: definition.id,
|
|
536
|
+
databaseId: definition.databaseId,
|
|
537
|
+
name: definition.name,
|
|
538
|
+
type,
|
|
539
|
+
visibility: normalizePropertyVisibility(definition.visibility),
|
|
540
|
+
options: parsePropertyOptions(definition.optionsJson),
|
|
541
|
+
position: definition.position,
|
|
542
|
+
createdAt: definition.createdAt,
|
|
543
|
+
updatedAt: definition.updatedAt,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function propertyValueKey(documentId: string, propertyId: string) {
|
|
548
|
+
return `${documentId}\0${propertyId}`;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export async function listPropertiesForDatabaseDocuments(
|
|
552
|
+
databaseId: string,
|
|
553
|
+
valueDocuments: DocumentRow[],
|
|
554
|
+
): Promise<Map<string, DocumentProperty[]>> {
|
|
555
|
+
const db = getDb();
|
|
556
|
+
const definitions = await db
|
|
557
|
+
.select()
|
|
558
|
+
.from(schema.documentPropertyDefinitions)
|
|
559
|
+
.where(eq(schema.documentPropertyDefinitions.databaseId, databaseId))
|
|
560
|
+
.orderBy(asc(schema.documentPropertyDefinitions.position));
|
|
561
|
+
const result = new Map<string, DocumentProperty[]>();
|
|
562
|
+
if (valueDocuments.length === 0) return result;
|
|
563
|
+
if (definitions.length === 0) {
|
|
564
|
+
for (const document of valueDocuments) result.set(document.id, []);
|
|
565
|
+
return result;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const documentIds = valueDocuments.map((document) => document.id);
|
|
569
|
+
const propertyIds = definitions.map((definition) => definition.id);
|
|
570
|
+
const values: Array<typeof schema.documentPropertyValues.$inferSelect> = [];
|
|
571
|
+
for (const documentIdChunk of chunks(documentIds, 200)) {
|
|
572
|
+
for (const propertyIdChunk of chunks(propertyIds, 200)) {
|
|
573
|
+
values.push(
|
|
574
|
+
...(await db
|
|
575
|
+
.select()
|
|
576
|
+
.from(schema.documentPropertyValues)
|
|
577
|
+
.where(
|
|
578
|
+
and(
|
|
579
|
+
inArray(
|
|
580
|
+
schema.documentPropertyValues.documentId,
|
|
581
|
+
documentIdChunk,
|
|
582
|
+
),
|
|
583
|
+
inArray(
|
|
584
|
+
schema.documentPropertyValues.propertyId,
|
|
585
|
+
propertyIdChunk,
|
|
586
|
+
),
|
|
587
|
+
),
|
|
588
|
+
)),
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
const valueByDocumentAndProperty = new Map(
|
|
593
|
+
values.map((value) => [
|
|
594
|
+
propertyValueKey(value.documentId, value.propertyId),
|
|
595
|
+
value,
|
|
596
|
+
]),
|
|
597
|
+
);
|
|
598
|
+
|
|
599
|
+
const rowNumberByDocumentId = definitions.some((definition) =>
|
|
600
|
+
isComputedPropertyType(definition.type as DocumentPropertyType),
|
|
601
|
+
)
|
|
602
|
+
? await databaseRowNumbersByDocumentId(databaseId)
|
|
603
|
+
: new Map<string, number>();
|
|
604
|
+
|
|
605
|
+
const blockContentByDocumentAndProperty = new Map<string, string>();
|
|
606
|
+
const hasAdditionalBlocksFields = definitions.some((definition) => {
|
|
607
|
+
const type = definition.type as DocumentPropertyType;
|
|
608
|
+
return (
|
|
609
|
+
isBlocksPropertyType(type) &&
|
|
610
|
+
!isPrimaryBlocksField(parsePropertyOptions(definition.optionsJson))
|
|
611
|
+
);
|
|
612
|
+
});
|
|
613
|
+
if (hasAdditionalBlocksFields) {
|
|
614
|
+
for (const documentIdChunk of chunks(documentIds, 200)) {
|
|
615
|
+
const rows = await db
|
|
616
|
+
.select({
|
|
617
|
+
documentId: schema.documentBlockFieldContents.documentId,
|
|
618
|
+
propertyId: schema.documentBlockFieldContents.propertyId,
|
|
619
|
+
content: schema.documentBlockFieldContents.content,
|
|
620
|
+
})
|
|
621
|
+
.from(schema.documentBlockFieldContents)
|
|
622
|
+
.where(
|
|
623
|
+
inArray(
|
|
624
|
+
schema.documentBlockFieldContents.documentId,
|
|
625
|
+
documentIdChunk,
|
|
626
|
+
),
|
|
627
|
+
);
|
|
628
|
+
for (const row of rows) {
|
|
629
|
+
blockContentByDocumentAndProperty.set(
|
|
630
|
+
propertyValueKey(row.documentId, row.propertyId),
|
|
631
|
+
row.content ?? "",
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
for (const document of valueDocuments) {
|
|
638
|
+
const properties = definitions.map((definition) => {
|
|
639
|
+
const propertyDefinition = serializePropertyDefinition(definition);
|
|
640
|
+
const storedValue = valueByDocumentAndProperty.get(
|
|
641
|
+
propertyValueKey(document.id, definition.id),
|
|
642
|
+
);
|
|
643
|
+
return {
|
|
644
|
+
definition: propertyDefinition,
|
|
645
|
+
value:
|
|
646
|
+
isComputedPropertyType(propertyDefinition.type) &&
|
|
647
|
+
propertyDefinition.type !== "formula"
|
|
648
|
+
? computedPropertyValue(propertyDefinition.type, document, {
|
|
649
|
+
databaseRowNumber: rowNumberByDocumentId.get(document.id),
|
|
650
|
+
})
|
|
651
|
+
: isBlocksPropertyType(propertyDefinition.type)
|
|
652
|
+
? resolveBlocksFieldValue({
|
|
653
|
+
options: propertyDefinition.options,
|
|
654
|
+
documentBody: document.content,
|
|
655
|
+
blockFieldContent: blockContentByDocumentAndProperty.get(
|
|
656
|
+
propertyValueKey(document.id, definition.id),
|
|
657
|
+
),
|
|
658
|
+
})
|
|
659
|
+
: parsePropertyValue(storedValue?.valueJson),
|
|
660
|
+
editable: !isComputedPropertyType(propertyDefinition.type),
|
|
661
|
+
};
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
const valuesByName = Object.fromEntries(
|
|
665
|
+
properties
|
|
666
|
+
.filter((property) => property.definition.type !== "formula")
|
|
667
|
+
.map((property) => [property.definition.name, property.value]),
|
|
668
|
+
);
|
|
669
|
+
const evaluatedProperties = properties.map((property) =>
|
|
670
|
+
property.definition.type === "formula"
|
|
671
|
+
? {
|
|
672
|
+
...property,
|
|
673
|
+
value: evaluatePropertyFormula(
|
|
674
|
+
property.definition.options.formula,
|
|
675
|
+
valuesByName,
|
|
676
|
+
),
|
|
677
|
+
}
|
|
678
|
+
: property,
|
|
679
|
+
);
|
|
680
|
+
const nextProperties = [];
|
|
681
|
+
for (const property of evaluatedProperties) {
|
|
682
|
+
if (property.definition.type === "rollup") {
|
|
683
|
+
nextProperties.push({
|
|
684
|
+
...property,
|
|
685
|
+
value: await evaluatePropertyRollup(property, evaluatedProperties),
|
|
686
|
+
});
|
|
687
|
+
} else {
|
|
688
|
+
nextProperties.push(property);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
result.set(document.id, nextProperties);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
return result;
|
|
695
|
+
}
|
|
696
|
+
|
|
529
697
|
async function evaluatePropertyRollup(
|
|
530
698
|
property: DocumentProperty,
|
|
531
699
|
properties: DocumentProperty[],
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
type DocumentPropertyOptions,
|
|
22
22
|
type DocumentPropertyType,
|
|
23
23
|
} from "../shared/properties.js";
|
|
24
|
+
import { chunks } from "./_batch-utils.js";
|
|
24
25
|
import {
|
|
25
26
|
resolveDatabaseForSourceMutation,
|
|
26
27
|
serializeSourceField,
|
|
@@ -343,7 +344,11 @@ export default defineAction({
|
|
|
343
344
|
const sourceRows = isSecondary
|
|
344
345
|
? []
|
|
345
346
|
: await db
|
|
346
|
-
.select(
|
|
347
|
+
.select({
|
|
348
|
+
databaseItemId: schema.contentDatabaseSourceRows.databaseItemId,
|
|
349
|
+
documentId: schema.contentDatabaseSourceRows.documentId,
|
|
350
|
+
sourceValuesJson: schema.contentDatabaseSourceRows.sourceValuesJson,
|
|
351
|
+
})
|
|
347
352
|
.from(schema.contentDatabaseSourceRows)
|
|
348
353
|
.where(eq(schema.contentDatabaseSourceRows.sourceId, source.id));
|
|
349
354
|
const builderMetadata = builderMetadataForSourceField({
|
|
@@ -397,17 +402,19 @@ export default defineAction({
|
|
|
397
402
|
options,
|
|
398
403
|
);
|
|
399
404
|
if (itemValues.length > 0) {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
405
|
+
for (const chunk of chunks(itemValues, 200)) {
|
|
406
|
+
await db.insert(schema.documentPropertyValues).values(
|
|
407
|
+
chunk.map((row) => ({
|
|
408
|
+
id: nanoid(),
|
|
409
|
+
ownerEmail: database.ownerEmail,
|
|
410
|
+
documentId: row.documentId,
|
|
411
|
+
propertyId,
|
|
412
|
+
valueJson: serializePropertyValue(row.value),
|
|
413
|
+
createdAt: now,
|
|
414
|
+
updatedAt: now,
|
|
415
|
+
})),
|
|
416
|
+
);
|
|
417
|
+
}
|
|
411
418
|
}
|
|
412
419
|
|
|
413
420
|
const sourceField = serializeSourceField(
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
ContentDatabaseResponse,
|
|
10
10
|
} from "../shared/api.js";
|
|
11
11
|
import { serializePropertyValue } from "../shared/properties.js";
|
|
12
|
+
import { chunks } from "./_batch-utils.js";
|
|
12
13
|
import { resolveDatabaseForSourceMutation } from "./_database-source-utils.js";
|
|
13
14
|
import { getContentDatabaseResponse } from "./_database-utils.js";
|
|
14
15
|
import { nanoid } from "./_property-utils.js";
|
|
@@ -207,7 +208,11 @@ export default defineAction({
|
|
|
207
208
|
}
|
|
208
209
|
if (federationRole !== "secondary") {
|
|
209
210
|
const sourceRows = await db
|
|
210
|
-
.select(
|
|
211
|
+
.select({
|
|
212
|
+
databaseItemId: schema.contentDatabaseSourceRows.databaseItemId,
|
|
213
|
+
documentId: schema.contentDatabaseSourceRows.documentId,
|
|
214
|
+
sourceValuesJson: schema.contentDatabaseSourceRows.sourceValuesJson,
|
|
215
|
+
})
|
|
211
216
|
.from(schema.contentDatabaseSourceRows)
|
|
212
217
|
.where(eq(schema.contentDatabaseSourceRows.sourceId, source.id));
|
|
213
218
|
const itemValues = sourceFieldPropertyValuesFromRows(
|
|
@@ -237,17 +242,19 @@ export default defineAction({
|
|
|
237
242
|
);
|
|
238
243
|
}
|
|
239
244
|
if (itemValues.length > 0) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
for (const chunk of chunks(itemValues, 200)) {
|
|
246
|
+
await db.insert(schema.documentPropertyValues).values(
|
|
247
|
+
chunk.map((row) => ({
|
|
248
|
+
id: nanoid(),
|
|
249
|
+
ownerEmail: database.ownerEmail,
|
|
250
|
+
documentId: row.documentId,
|
|
251
|
+
propertyId: property.id,
|
|
252
|
+
valueJson: serializePropertyValue(row.value),
|
|
253
|
+
createdAt: now,
|
|
254
|
+
updatedAt: now,
|
|
255
|
+
})),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
251
258
|
}
|
|
252
259
|
}
|
|
253
260
|
|
|
@@ -5,6 +5,7 @@ import { and, eq, inArray } from "drizzle-orm";
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
|
|
7
7
|
import { getDb, schema } from "../server/db/index.js";
|
|
8
|
+
import { chunks } from "./_batch-utils.js";
|
|
8
9
|
import {
|
|
9
10
|
deleteLocalFileDocument,
|
|
10
11
|
isLocalDocumentId,
|
|
@@ -13,21 +14,13 @@ import {
|
|
|
13
14
|
|
|
14
15
|
const DELETE_BATCH_SIZE = 90;
|
|
15
16
|
|
|
16
|
-
function chunks<T>(items: T[], size = DELETE_BATCH_SIZE): T[][] {
|
|
17
|
-
const out: T[][] = [];
|
|
18
|
-
for (let index = 0; index < items.length; index += size) {
|
|
19
|
-
out.push(items.slice(index, index + size));
|
|
20
|
-
}
|
|
21
|
-
return out;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
17
|
async function selectDocumentChildren(
|
|
25
18
|
db: ReturnType<typeof getDb>,
|
|
26
19
|
parentIds: string[],
|
|
27
20
|
ownerEmail: string,
|
|
28
21
|
) {
|
|
29
22
|
const rows: Array<{ id: string }> = [];
|
|
30
|
-
for (const batch of chunks(parentIds)) {
|
|
23
|
+
for (const batch of chunks(parentIds, DELETE_BATCH_SIZE)) {
|
|
31
24
|
rows.push(
|
|
32
25
|
...(await db
|
|
33
26
|
.select({ id: schema.documents.id })
|
|
@@ -49,7 +42,7 @@ async function selectOwnedDatabaseIds(
|
|
|
49
42
|
ownerEmail: string,
|
|
50
43
|
) {
|
|
51
44
|
const rows: Array<{ id: string }> = [];
|
|
52
|
-
for (const batch of chunks(documentIds)) {
|
|
45
|
+
for (const batch of chunks(documentIds, DELETE_BATCH_SIZE)) {
|
|
53
46
|
rows.push(
|
|
54
47
|
...(await db
|
|
55
48
|
.select({ id: schema.contentDatabases.id })
|
|
@@ -71,7 +64,7 @@ async function selectDatabaseItemDocuments(
|
|
|
71
64
|
ownerEmail: string,
|
|
72
65
|
) {
|
|
73
66
|
const rows: Array<{ documentId: string }> = [];
|
|
74
|
-
for (const batch of chunks(databaseIds)) {
|
|
67
|
+
for (const batch of chunks(databaseIds, DELETE_BATCH_SIZE)) {
|
|
75
68
|
rows.push(
|
|
76
69
|
...(await db
|
|
77
70
|
.select({ documentId: schema.contentDatabaseItems.documentId })
|
|
@@ -87,7 +80,10 @@ async function selectDatabaseItemDocuments(
|
|
|
87
80
|
if (rows.length === 0) return rows;
|
|
88
81
|
|
|
89
82
|
const ownedRows: Array<{ id: string }> = [];
|
|
90
|
-
for (const batch of chunks(
|
|
83
|
+
for (const batch of chunks(
|
|
84
|
+
rows.map((row) => row.documentId),
|
|
85
|
+
DELETE_BATCH_SIZE,
|
|
86
|
+
)) {
|
|
91
87
|
ownedRows.push(
|
|
92
88
|
...(await db
|
|
93
89
|
.select({ id: schema.documents.id })
|
|
@@ -167,7 +163,7 @@ async function deleteWhereIn<T>(
|
|
|
167
163
|
items: T[],
|
|
168
164
|
run: (batch: T[]) => Promise<unknown>,
|
|
169
165
|
) {
|
|
170
|
-
for (const batch of chunks(items)) {
|
|
166
|
+
for (const batch of chunks(items, DELETE_BATCH_SIZE)) {
|
|
171
167
|
if (batch.length > 0) await run(batch);
|
|
172
168
|
}
|
|
173
169
|
}
|
|
@@ -4,7 +4,8 @@ import { z } from "zod";
|
|
|
4
4
|
|
|
5
5
|
import type { ContentDatabaseSourceStatusResponse } from "../shared/api.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
7
|
+
getContentDatabaseSourceSnapshot,
|
|
8
|
+
getContentDatabaseSourceSnapshotById,
|
|
8
9
|
getExistingSourceForWrite,
|
|
9
10
|
resyncBuilderCmsSourceSnapshot,
|
|
10
11
|
resyncMockSourceSnapshot,
|
|
@@ -60,10 +61,9 @@ export default defineAction({
|
|
|
60
61
|
} else {
|
|
61
62
|
throw new Error(`Unsupported source type "${source.sourceType}".`);
|
|
62
63
|
}
|
|
63
|
-
const snapshot =
|
|
64
|
-
database,
|
|
65
|
-
|
|
66
|
-
);
|
|
64
|
+
const snapshot = args.sourceId
|
|
65
|
+
? await getContentDatabaseSourceSnapshotById(database, args.sourceId)
|
|
66
|
+
: await getContentDatabaseSourceSnapshot(database);
|
|
67
67
|
|
|
68
68
|
const builderProgress =
|
|
69
69
|
snapshot?.sourceType === "builder-cms" ? snapshot.metadata : null;
|
|
@@ -39,29 +39,39 @@ export function builderBodyHydrationDisplayHydratedCount(args: {
|
|
|
39
39
|
export function databaseItemBodyHydrationIsPending(
|
|
40
40
|
item: Pick<ContentDatabaseItem, "bodyHydration" | "document">,
|
|
41
41
|
) {
|
|
42
|
+
const hydration =
|
|
43
|
+
item.bodyHydration ?? item.document.databaseMembership?.bodyHydration;
|
|
42
44
|
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
sourceBackedEmptyBodyNeedsHydration({
|
|
46
|
+
sourceId: item.document.databaseMembership?.sourceId,
|
|
47
|
+
content: item.document.content,
|
|
48
|
+
hydration,
|
|
49
|
+
})
|
|
46
50
|
) {
|
|
47
51
|
return true;
|
|
48
52
|
}
|
|
49
|
-
return builderBodyHydrationIsPending(
|
|
50
|
-
item.bodyHydration ?? item.document.databaseMembership?.bodyHydration,
|
|
51
|
-
);
|
|
53
|
+
return builderBodyHydrationIsPending(hydration);
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
export function documentBodyHydrationIsPending(
|
|
55
|
-
document: Pick<Document, "databaseMembership">,
|
|
57
|
+
document: Pick<Document, "content" | "databaseMembership">,
|
|
56
58
|
) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
const hydration = document.databaseMembership?.bodyHydration;
|
|
60
|
+
if (
|
|
61
|
+
sourceBackedEmptyBodyNeedsHydration({
|
|
62
|
+
sourceId: document.databaseMembership?.sourceId,
|
|
63
|
+
content: document.content,
|
|
64
|
+
hydration,
|
|
65
|
+
})
|
|
66
|
+
) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return builderBodyHydrationIsPending(hydration);
|
|
60
70
|
}
|
|
61
71
|
|
|
62
72
|
export function previewBodyHydrationIsPending(args: {
|
|
63
73
|
item: Pick<ContentDatabaseItem, "bodyHydration" | "document">;
|
|
64
|
-
document: Pick<Document, "databaseMembership"> | null | undefined;
|
|
74
|
+
document: Pick<Document, "content" | "databaseMembership"> | null | undefined;
|
|
65
75
|
}) {
|
|
66
76
|
const membership =
|
|
67
77
|
args.document?.databaseMembership ?? args.item.document.databaseMembership;
|
|
@@ -101,6 +111,20 @@ export function isEffectivelyEmptyDocumentContent(
|
|
|
101
111
|
return normalized === "" || normalized === "<empty-block/>";
|
|
102
112
|
}
|
|
103
113
|
|
|
114
|
+
function sourceBackedEmptyBodyNeedsHydration(args: {
|
|
115
|
+
sourceId: string | null | undefined;
|
|
116
|
+
content: string | null | undefined;
|
|
117
|
+
hydration: ContentDatabaseBodyHydration | null | undefined;
|
|
118
|
+
}) {
|
|
119
|
+
if (!args.sourceId || !isEffectivelyEmptyDocumentContent(args.content)) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
if (!args.hydration) return true;
|
|
123
|
+
if (builderBodyHydrationIsPending(args.hydration)) return true;
|
|
124
|
+
if (args.hydration.status === "error") return false;
|
|
125
|
+
return args.hydration.status === "hydrated" && !args.hydration.version;
|
|
126
|
+
}
|
|
127
|
+
|
|
104
128
|
export function shouldIgnorePreviewEmptyNormalization(args: {
|
|
105
129
|
currentContent: string | null | undefined;
|
|
106
130
|
nextContent: string | null | undefined;
|
|
@@ -7159,6 +7159,11 @@ function BuilderSourceContinuationBar({
|
|
|
7159
7159
|
)
|
|
7160
7160
|
: rawFetchedCount;
|
|
7161
7161
|
const hasMore = source.metadata.lastReadHasMore === true && !rowsComplete;
|
|
7162
|
+
const fetchedCountDetail = builderSourceContinuationFetchedCountDetail(
|
|
7163
|
+
source,
|
|
7164
|
+
fetchedCount,
|
|
7165
|
+
rowsComplete,
|
|
7166
|
+
);
|
|
7162
7167
|
const bodyHydrationActive =
|
|
7163
7168
|
!hasMore &&
|
|
7164
7169
|
!!bodyHydration &&
|
|
@@ -7212,7 +7217,9 @@ function BuilderSourceContinuationBar({
|
|
|
7212
7217
|
failed: bodyHydration.error,
|
|
7213
7218
|
},
|
|
7214
7219
|
)
|
|
7215
|
-
: dbText("builderRowsFetchedSoFar", {
|
|
7220
|
+
: dbText("builderRowsFetchedSoFar", {
|
|
7221
|
+
count: fetchedCountDetail ?? fetchedCount,
|
|
7222
|
+
});
|
|
7216
7223
|
|
|
7217
7224
|
return (
|
|
7218
7225
|
<div
|
|
@@ -8030,6 +8037,24 @@ export function builderSourceContinuationProgressPercent(
|
|
|
8030
8037
|
: rawPercent;
|
|
8031
8038
|
}
|
|
8032
8039
|
|
|
8040
|
+
export function builderSourceContinuationFetchedCountDetail(
|
|
8041
|
+
source: Pick<ContentDatabaseSource, "metadata">,
|
|
8042
|
+
fetchedCount: number | null,
|
|
8043
|
+
rowsComplete = false,
|
|
8044
|
+
) {
|
|
8045
|
+
const knownFetchTotal =
|
|
8046
|
+
!rowsComplete &&
|
|
8047
|
+
source.metadata.lastReadHasMore === true &&
|
|
8048
|
+
typeof source.metadata.lastReadLimit === "number"
|
|
8049
|
+
? source.metadata.lastReadLimit
|
|
8050
|
+
: null;
|
|
8051
|
+
return fetchedCount !== null &&
|
|
8052
|
+
knownFetchTotal !== null &&
|
|
8053
|
+
knownFetchTotal > fetchedCount
|
|
8054
|
+
? `${fetchedCount} of ${knownFetchTotal}`
|
|
8055
|
+
: fetchedCount;
|
|
8056
|
+
}
|
|
8057
|
+
|
|
8033
8058
|
export function builderSourceContinuationWatchdogDecision(refires: number) {
|
|
8034
8059
|
return "refire";
|
|
8035
8060
|
}
|
|
@@ -12427,12 +12452,24 @@ function isTablePropertyVisible(
|
|
|
12427
12452
|
});
|
|
12428
12453
|
}
|
|
12429
12454
|
|
|
12430
|
-
function databaseTableCellDisplayValue(
|
|
12455
|
+
function databaseTableCellDisplayValue(
|
|
12456
|
+
property: DocumentProperty,
|
|
12457
|
+
item?: Pick<ContentDatabaseItem, "bodyHydration" | "document">,
|
|
12458
|
+
) {
|
|
12431
12459
|
// Blocks columns show a word count, never the dumped body content.
|
|
12432
12460
|
if (property.definition.type === "blocks") {
|
|
12433
12461
|
const content = typeof property.value === "string" ? property.value : "";
|
|
12434
12462
|
const words = countWords(content);
|
|
12435
|
-
if (words === 0)
|
|
12463
|
+
if (words === 0) {
|
|
12464
|
+
if (item && databaseItemBodyHydrationIsPending(item)) {
|
|
12465
|
+
return (
|
|
12466
|
+
<span className="text-muted-foreground">
|
|
12467
|
+
{dbText("builderBodySyncing")}
|
|
12468
|
+
</span>
|
|
12469
|
+
);
|
|
12470
|
+
}
|
|
12471
|
+
return <span aria-hidden="true"> </span>;
|
|
12472
|
+
}
|
|
12436
12473
|
return (
|
|
12437
12474
|
<span className="text-muted-foreground">{formatWordCount(content)}</span>
|
|
12438
12475
|
);
|
|
@@ -16865,6 +16902,9 @@ function DatabaseTableRow({
|
|
|
16865
16902
|
item.properties.find(
|
|
16866
16903
|
(candidate) => candidate.definition.id === property.definition.id,
|
|
16867
16904
|
) ?? property;
|
|
16905
|
+
const bodyCellHydrationPending =
|
|
16906
|
+
itemProperty.definition.type === "blocks" &&
|
|
16907
|
+
databaseItemBodyHydrationIsPending(item);
|
|
16868
16908
|
|
|
16869
16909
|
const value = (
|
|
16870
16910
|
<div
|
|
@@ -16873,10 +16913,12 @@ function DatabaseTableRow({
|
|
|
16873
16913
|
wrapCells
|
|
16874
16914
|
? "whitespace-normal break-words"
|
|
16875
16915
|
: "truncate whitespace-nowrap",
|
|
16876
|
-
isEmptyPropertyValue(itemProperty.value) &&
|
|
16916
|
+
isEmptyPropertyValue(itemProperty.value) &&
|
|
16917
|
+
!bodyCellHydrationPending &&
|
|
16918
|
+
"text-transparent",
|
|
16877
16919
|
)}
|
|
16878
16920
|
>
|
|
16879
|
-
{databaseTableCellDisplayValue(itemProperty)}
|
|
16921
|
+
{databaseTableCellDisplayValue(itemProperty, item)}
|
|
16880
16922
|
</div>
|
|
16881
16923
|
);
|
|
16882
16924
|
const isEditableCheckbox =
|
|
@@ -14,6 +14,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
|
|
14
14
|
import { toast } from "sonner";
|
|
15
15
|
|
|
16
16
|
import { databaseItemBodyHydrationIsPending } from "@/components/editor/body-hydration";
|
|
17
|
+
import { isEffectivelyEmptyDocumentContent } from "@/components/editor/body-hydration";
|
|
17
18
|
|
|
18
19
|
import type { DocumentUpdateConflictResponse } from "../../actions/update-document";
|
|
19
20
|
import { useRestoreContentDatabase } from "./use-content-database";
|
|
@@ -85,14 +86,19 @@ export function seedDatabaseItemDocumentCaches(
|
|
|
85
86
|
queryClient: Pick<QueryClient, "getQueryData" | "setQueryData">,
|
|
86
87
|
item: ContentDatabaseItem,
|
|
87
88
|
) {
|
|
89
|
+
const sourceBackedEmptyBody =
|
|
90
|
+
(!!item.bodyHydration || !!item.document.databaseMembership?.sourceId) &&
|
|
91
|
+
isEffectivelyEmptyDocumentContent(item.document.content);
|
|
88
92
|
// Seed only cold caches. Overwriting an existing entry would bump its
|
|
89
93
|
// freshness with possibly older table-snapshot data (a background database
|
|
90
94
|
// refetch can lag a just-saved document edit) and suppress the correcting
|
|
91
95
|
// refetch for the whole staleTime window. Rows whose Builder body has not
|
|
92
|
-
// hydrated yet
|
|
93
|
-
//
|
|
96
|
+
// hydrated yet, or whose source-backed list snapshot intentionally omits the
|
|
97
|
+
// body, are never seeded: their empty table-snapshot `content` would render as
|
|
98
|
+
// an authoritative empty document.
|
|
94
99
|
if (
|
|
95
100
|
!databaseItemBodyHydrationIsPending(item) &&
|
|
101
|
+
!sourceBackedEmptyBody &&
|
|
96
102
|
queryClient.getQueryData(documentQueryKey(item.document.id)) === undefined
|
|
97
103
|
) {
|
|
98
104
|
queryClient.setQueryData<Document>(documentQueryKey(item.document.id), {
|
|
@@ -616,6 +616,25 @@ const runContentMigrations = runMigrations(
|
|
|
616
616
|
// becoming unrelated top-level comments. See actions/sync-notion-comments.ts.
|
|
617
617
|
sql: `ALTER TABLE document_comments ADD COLUMN IF NOT EXISTS notion_discussion_id TEXT`,
|
|
618
618
|
},
|
|
619
|
+
{
|
|
620
|
+
version: 63,
|
|
621
|
+
name: "builder-source-refresh-hot-path-indexes",
|
|
622
|
+
sql: `CREATE INDEX IF NOT EXISTS content_database_items_database_position_idx ON content_database_items (database_id, position);
|
|
623
|
+
CREATE INDEX IF NOT EXISTS content_database_items_document_idx ON content_database_items (document_id);
|
|
624
|
+
CREATE INDEX IF NOT EXISTS content_database_source_rows_source_created_idx ON content_database_source_rows (source_id, created_at);
|
|
625
|
+
CREATE INDEX IF NOT EXISTS content_database_source_rows_source_document_idx ON content_database_source_rows (source_id, document_id);
|
|
626
|
+
CREATE INDEX IF NOT EXISTS content_database_source_rows_source_item_idx ON content_database_source_rows (source_id, database_item_id);
|
|
627
|
+
CREATE INDEX IF NOT EXISTS content_database_source_rows_source_row_idx ON content_database_source_rows (source_id, source_row_id);
|
|
628
|
+
CREATE INDEX IF NOT EXISTS content_database_source_fields_source_key_idx ON content_database_source_fields (source_id, source_field_key);
|
|
629
|
+
CREATE INDEX IF NOT EXISTS content_database_source_fields_source_property_idx ON content_database_source_fields (source_id, property_id);
|
|
630
|
+
CREATE INDEX IF NOT EXISTS content_database_body_hydration_queue_source_document_idx ON content_database_body_hydration_queue (source_id, document_id, priority, created_at)`,
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
version: 64,
|
|
634
|
+
name: "document-property-value-hot-path-indexes",
|
|
635
|
+
sql: `CREATE INDEX IF NOT EXISTS document_property_values_document_property_idx ON document_property_values (document_id, property_id);
|
|
636
|
+
CREATE INDEX IF NOT EXISTS document_property_values_property_document_idx ON document_property_values (property_id, document_id)`,
|
|
637
|
+
},
|
|
619
638
|
],
|
|
620
639
|
{ table: "content_migrations" },
|
|
621
640
|
);
|