@tearleads/client-sdk 0.1.44 → 0.1.46
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/client/Tearleads.js +3 -0
- package/client/Tearleads.js.map +1 -1
- package/client/userIdentities.d.ts +11 -1
- package/client/userIdentities.js +26 -8
- package/client/userIdentities.js.map +1 -1
- package/client/workflowRuntime.d.ts +2 -1
- package/client/workflowRuntime.js +1 -0
- package/client/workflowRuntime.js.map +1 -1
- package/data/persistence/container-contents/containerContentsPersistence.js +2 -3
- package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerCreateIntentSettlement.js +16 -16
- package/data/persistence/container-contents/containerCreateIntentSettlement.js.map +1 -1
- package/data/persistence/container-contents/containerDeletionPersistence.js +5 -11
- package/data/persistence/container-contents/containerDeletionPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerDocumentReassignment.js +13 -13
- package/data/persistence/container-contents/containerDocumentReassignment.js.map +1 -1
- package/data/persistence/container-contents/containerHydrationPersistence.js +7 -4
- package/data/persistence/container-contents/containerHydrationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerIntentPersistence.js +43 -42
- package/data/persistence/container-contents/containerIntentPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js +15 -20
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMoveAbandonPersistence.js +1 -6
- package/data/persistence/container-contents/containerMoveAbandonPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMoveIntentRows.js +9 -8
- package/data/persistence/container-contents/containerMoveIntentRows.js.map +1 -1
- package/data/persistence/container-contents/containerReconcilePersistence.js +4 -8
- package/data/persistence/container-contents/containerReconcilePersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRecoveryPersistence.js +20 -19
- package/data/persistence/container-contents/containerRecoveryPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRemovalWork.js +10 -10
- package/data/persistence/container-contents/containerRemovalWork.js.map +1 -1
- package/data/persistence/container-contents/containerStructuralRepair.js +21 -44
- package/data/persistence/container-contents/containerStructuralRepair.js.map +1 -1
- package/data/persistence/container-contents/documentLinkRemovalRepair.js +12 -11
- package/data/persistence/container-contents/documentLinkRemovalRepair.js.map +1 -1
- package/data/persistence/container-contents/documentMoveIntentPersistence.js +53 -28
- package/data/persistence/container-contents/documentMoveIntentPersistence.js.map +1 -1
- package/data/persistence/container-contents/documentPlacementIntentEnqueue.js +9 -8
- package/data/persistence/container-contents/documentPlacementIntentEnqueue.js.map +1 -1
- package/data/persistence/container-contents/documentPurgePlacement.js +6 -6
- package/data/persistence/container-contents/documentPurgePlacement.js.map +1 -1
- package/data/persistence/container-contents/dormantContainerMetadata.js +1 -5
- package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
- package/data/persistence/container-contents/pendingContainerCreate.js +5 -5
- package/data/persistence/container-contents/pendingContainerCreate.js.map +1 -1
- package/data/persistence/containers/containerPersistence.js +10 -27
- package/data/persistence/containers/containerPersistence.js.map +1 -1
- package/data/persistence/containers/documentContainerProjectionPersistence.js +2 -2
- package/data/persistence/containers/documentContainerProjectionPersistence.js.map +1 -1
- package/data/persistence/containers/documentPlacement.js +10 -10
- package/data/persistence/containers/documentPlacement.js.map +1 -1
- package/data/persistence/documents/internal/discardDocument.js +5 -5
- package/data/persistence/documents/internal/discardDocument.js.map +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js +7 -9
- package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js +6 -8
- package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/ensureDocumentsSchema.js +2 -2
- package/data/persistence/documents/internal/ensureDocumentsSchema.js.map +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js +3 -22
- package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
- package/data/persistence/organizations/organizationDataUsagePersistence.js +31 -64
- package/data/persistence/organizations/organizationDataUsagePersistence.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelPurge.js +1 -5
- package/data/persistence/organizations/organizationReadModelPurge.js.map +1 -1
- package/data/persistence/principalCurrentAcknowledgementPersistence.js +24 -17
- package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -1
- package/data/persistence/principalHistoryIncompleteRetention.js +3 -9
- package/data/persistence/principalHistoryIncompleteRetention.js.map +1 -1
- package/data/persistence/principalHistoryStagePersistence.d.ts +3 -9
- package/data/persistence/principalHistoryStagePersistence.js +15 -25
- package/data/persistence/principalHistoryStagePersistence.js.map +1 -1
- package/data/persistence/principalHistoryStageRetention.js +16 -15
- package/data/persistence/principalHistoryStageRetention.js.map +1 -1
- package/data/persistence/principalHistoryUnpublishedRetention.js +6 -13
- package/data/persistence/principalHistoryUnpublishedRetention.js.map +1 -1
- package/data/sqlite/containerSchema.d.ts +84 -180
- package/data/sqlite/containerSchema.js +14 -23
- package/data/sqlite/containerSchema.js.map +1 -1
- package/data/sqlite/documentPlacementIntentSchema.js +3 -50
- package/data/sqlite/documentPlacementIntentSchema.js.map +1 -1
- package/data/sqlite/documentSyncFailurePersistence.d.ts +16 -6
- package/data/sqlite/documentSyncFailurePersistence.js +44 -54
- package/data/sqlite/documentSyncFailurePersistence.js.map +1 -1
- package/data/sqlite/{documentPlacementIntentSchema.d.ts → localIntentSchema.d.ts} +162 -88
- package/data/sqlite/localIntentSchema.js +90 -0
- package/data/sqlite/localIntentSchema.js.map +1 -0
- package/data/sqlite/organizationDataUsageSchema.js +11 -17
- package/data/sqlite/organizationDataUsageSchema.js.map +1 -1
- package/data/sqlite/principalHistoryRetentionSchema.js +0 -15
- package/data/sqlite/principalHistoryRetentionSchema.js.map +1 -1
- package/data/sqlite/principalHistoryStageSchema.d.ts +44 -2
- package/data/sqlite/principalHistoryStageSchema.js +14 -2
- package/data/sqlite/principalHistoryStageSchema.js.map +1 -1
- package/data/sqlite/schema.d.ts +947 -2112
- package/data/sqlite/schema.js +26 -134
- package/data/sqlite/schema.js.map +1 -1
- package/data/trustedUserIdentity/identityLink.d.ts +12 -0
- package/data/trustedUserIdentity/identityLink.js +117 -0
- package/data/trustedUserIdentity/identityLink.js.map +1 -0
- package/data/trustedUserIdentity/index.d.ts +2 -1
- package/data/trustedUserIdentity/index.js +1 -0
- package/data/trustedUserIdentity/index.js.map +1 -1
- package/data/trustedUserIdentity/service.js +48 -2
- package/data/trustedUserIdentity/service.js.map +1 -1
- package/data/trustedUserIdentity/types.d.ts +3 -0
- package/data/trustedUserIdentity/types.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/documentPriming.js +6 -10
- package/workflows/container-contents/documentPriming.js.map +1 -1
- package/workflows/container-contents/documentQueries/sql.js +11 -10
- package/workflows/container-contents/documentQueries/sql.js.map +1 -1
- package/workflows/container-contents/documentQueries.js +2 -2
- package/workflows/container-contents/documentQueries.js.map +1 -1
- package/workflows/container-contents/pendingDownloads.js +2 -5
- package/workflows/container-contents/pendingDownloads.js.map +1 -1
- package/workflows/container-contents/pendingWrites/deferredTails.js +3 -11
- package/workflows/container-contents/pendingWrites/deferredTails.js.map +1 -1
- package/workflows/container-contents/pendingWrites/sources.js +56 -80
- package/workflows/container-contents/pendingWrites/sources.js.map +1 -1
- package/workflows/container-contents/pendingWrites.js +6 -4
- package/workflows/container-contents/pendingWrites.js.map +1 -1
- package/workflows/container-contents/remoteContainerState.js +2 -1
- package/workflows/container-contents/remoteContainerState.js.map +1 -1
- package/workflows/sync/remoteReset.js +16 -23
- package/workflows/sync/remoteReset.js.map +1 -1
- package/workflows/sync/remoteResetPrincipalScope.js +1 -2
- package/workflows/sync/remoteResetPrincipalScope.js.map +1 -1
- package/workflows/sync/remoteResetScope.js +15 -8
- package/workflows/sync/remoteResetScope.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.js","sourceRoot":"","sources":["sql.ts"],"names":[],"mappings":"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","sourcesContent":["import { getOrphanedDocumentWhereSql } from \"../orphanedDocumentSql\";\nimport { hydratedProjectionSql } from \"./hydrationSql\";\nimport type { ContainerItemSort } from \"./types\";\n\n// Keep each IN clause below SQLite's historical 999 bind-parameter limit.\nconst CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE = 500;\nconst MAX_CONTAINER_ITEM_WINDOW_LIMIT = 200;\nconst MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT = 200;\n\nexport function listContainerContentsSqlIdBatches(\n values: ReadonlyArray<string>,\n): ReadonlyArray<ReadonlyArray<string>> {\n const batches: string[][] = [];\n\n for (\n let index = 0;\n index < values.length;\n index += CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE\n ) {\n batches.push(\n values.slice(index, index + CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE),\n );\n }\n\n return batches;\n}\n\nexport function clampContainerItemWindowValue(value: number): number {\n return Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n}\n\nexport function getContainerItemWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_ITEM_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerDocumentSidebarWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerContentsContainerItemOrderBy(\n sort: ContainerItemSort,\n): string {\n const direction = sort.direction === \"desc\" ? \"DESC\" : \"ASC\";\n\n if (sort.key === \"type\") {\n return `type_sort COLLATE NOCASE ${direction}, name COLLATE NOCASE ASC, item_kind_sort ASC, item_id ASC`;\n }\n\n if (sort.key === \"created\") {\n return `created_at IS NULL ASC, created_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"modified\") {\n return `updated_at IS NULL ASC, updated_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"name\") {\n return `item_kind_sort ASC, name COLLATE NOCASE ${direction}, type_sort COLLATE NOCASE ASC, item_id ASC`;\n }\n\n return \"item_kind_sort ASC, name COLLATE NOCASE ASC, type_sort COLLATE NOCASE ASC, item_id ASC\";\n}\n\nexport function getContainerContentsDocumentPendingStateCtes(): string {\n return `\n document_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'documents' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n document_pending_attachment_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_attachment_count,\n COALESCE(SUM(byte_length), 0) AS pending_attachment_bytes\n FROM document_pending_attachments\n GROUP BY local_id\n )\n `;\n}\n\ninterface ContainerSystemFilterCounts {\n visibleForeignSystemContainerNameCount: number;\n visibleSystemSlotCount: number;\n}\n\nexport function getContainerDisplayNameSql(aliases: {\n containerAlias: string;\n projectionAlias: string;\n}): string {\n return `COALESCE(${aliases.projectionAlias}.display_name, CASE WHEN ${aliases.containerAlias}.parent_id IS NULL THEN '/' ELSE 'Untitled' END)`;\n}\n\n/**\n * Display attribution for an object reached through a container: the\n * container's organization when attached, else the projection row's own.\n */\nexport function getContainerOrganizationAttributionSql(aliases: {\n containerAlias: string;\n projectionAlias: string;\n}): string {\n return `COALESCE(NULLIF(${aliases.containerAlias}.organization_id, ''), NULLIF(${aliases.projectionAlias}.organization_id, ''))`;\n}\n\nfunction getContainerContentsContainerSystemSlotFilter(\n counts: ContainerSystemFilterCounts,\n): string {\n const clauses = [\"c.system_slot IS NULL\"];\n\n if (counts.visibleSystemSlotCount > 0) {\n const visibleSystemSlotBindMarkers = Array.from(\n { length: counts.visibleSystemSlotCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(`c.system_slot IN (${visibleSystemSlotBindMarkers})`);\n }\n\n if (counts.visibleForeignSystemContainerNameCount > 0) {\n const visibleSystemNameBindMarkers = Array.from(\n { length: counts.visibleForeignSystemContainerNameCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(\n `(c.organization_id != '' AND c.organization_id != ? AND ${getContainerDisplayNameSql({ containerAlias: \"c\", projectionAlias: \"cp\" })} IN (${visibleSystemNameBindMarkers}))`,\n );\n }\n\n return `(${clauses.join(\" OR \")})`;\n}\n\n/**\n * A `(document, container)` placement under a tombstone hold is hidden from\n * container views: the server said the document left the container, but the\n * signed head that would prove it is not yet available, so the row is kept\n * and hidden rather than deleted (`container_document_tombstone_holds`).\n */\nfunction getHeldPlacementExclusionSql(\n documentIdSql: string,\n containerIdSql: string,\n): string {\n return `\n AND NOT EXISTS (\n SELECT 1\n FROM container_document_tombstone_holds hold\n WHERE hold.document_id = ${documentIdSql}\n AND hold.container_id = ${containerIdSql}\n AND hold.hidden = 1\n )`;\n}\n\nexport function getContainerContentsContainerItemsBaseSql(\n visibleSystemSlotCount = 0,\n visibleForeignSystemContainerNameCount = 0,\n): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_metadata_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'container-metadata' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n pending_container_create_intents AS (\n SELECT\n container_id,\n MAX(last_error) AS last_error\n FROM container_create_intents\n WHERE intent_type = 'container.create'\n AND sync_status = 'pending'\n GROUP BY container_id\n ),\n container_items AS (\n SELECT\n 'container' AS item_kind,\n 0 AS item_kind_sort,\n c.id AS item_id,\n NULL AS document_id,\n NULL AS document_kind,\n c.metadata_document_id AS metadata_document_id,\n c.local_updated_at AS local_updated_at,\n c.server_created_at AS server_created_at,\n c.server_updated_at AS server_updated_at,\n cp.icon AS icon,\n COALESCE(container_updates.pending_update_count, 0) AS pending_update_count,\n 0 AS pending_attachment_count,\n 0 AS pending_attachment_bytes,\n create_intent.last_error AS sync_last_error,\n ${getContainerDisplayNameSql({ containerAlias: \"c\", projectionAlias: \"cp\" })} AS name,\n 'folder' AS type_sort,\n COALESCE(c.server_created_at, c.local_created_at) AS created_at,\n COALESCE(c.server_updated_at, c.local_updated_at) AS updated_at\n FROM containers c\n LEFT JOIN container_projection cp ON cp.container_id = c.id\n LEFT JOIN container_metadata_pending_update_counts container_updates\n ON container_updates.local_id = c.id\n LEFT JOIN pending_container_create_intents create_intent\n ON create_intent.container_id = c.id\n WHERE c.parent_id = ?\n AND ${hydratedProjectionSql(\"c.id\", \"container-metadata\")}\n AND ${getContainerContentsContainerSystemSlotFilter({\n visibleForeignSystemContainerNameCount,\n visibleSystemSlotCount,\n })}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_items\n `;\n}\n\nexport function getContainerContentsDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_documents AS (\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n linked.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_documents\n `;\n}\n\nexport function getOrphanedDocumentItemsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n orphaned_document_items AS (\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n )\n SELECT *\n FROM orphaned_document_items\n `;\n}\n\nexport function getOrphanedDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n `;\n}\n\nexport function getOrphanedDocumentExistsSql(): string {\n return `\n SELECT 1\n FROM document_projection d\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n LIMIT 1\n `;\n}\n\nexport function getContainerContentsContainerDocumentSidebarOrderBy(): string {\n return \"updated_at IS NULL ASC, updated_at DESC, title COLLATE NOCASE ASC, local_id ASC\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["sql.ts"],"names":[],"mappings":"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","sourcesContent":["import { LOCAL_INTENT_LANES } from \"../../../data/sqlite/schema\";\nimport { getOrphanedDocumentWhereSql } from \"../orphanedDocumentSql\";\nimport { hydratedProjectionSql } from \"./hydrationSql\";\nimport type { ContainerItemSort } from \"./types\";\n\n// Keep each IN clause below SQLite's historical 999 bind-parameter limit.\nconst CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE = 500;\nconst MAX_CONTAINER_ITEM_WINDOW_LIMIT = 200;\nconst MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT = 200;\n\nexport function listContainerContentsSqlIdBatches(\n values: ReadonlyArray<string>,\n): ReadonlyArray<ReadonlyArray<string>> {\n const batches: string[][] = [];\n\n for (\n let index = 0;\n index < values.length;\n index += CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE\n ) {\n batches.push(\n values.slice(index, index + CONTAINER_DOCUMENT_SQL_ID_BATCH_SIZE),\n );\n }\n\n return batches;\n}\n\nexport function clampContainerItemWindowValue(value: number): number {\n return Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;\n}\n\nexport function getContainerItemWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_ITEM_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerDocumentSidebarWindowLimit(limit: number): number {\n return Math.min(\n MAX_CONTAINER_DOCUMENT_SIDEBAR_WINDOW_LIMIT,\n clampContainerItemWindowValue(limit),\n );\n}\n\nexport function getContainerContentsContainerItemOrderBy(\n sort: ContainerItemSort,\n): string {\n const direction = sort.direction === \"desc\" ? \"DESC\" : \"ASC\";\n\n if (sort.key === \"type\") {\n return `type_sort COLLATE NOCASE ${direction}, name COLLATE NOCASE ASC, item_kind_sort ASC, item_id ASC`;\n }\n\n if (sort.key === \"created\") {\n return `created_at IS NULL ASC, created_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"modified\") {\n return `updated_at IS NULL ASC, updated_at ${direction}, name COLLATE NOCASE ASC, item_id ASC`;\n }\n\n if (sort.key === \"name\") {\n return `item_kind_sort ASC, name COLLATE NOCASE ${direction}, type_sort COLLATE NOCASE ASC, item_id ASC`;\n }\n\n return \"item_kind_sort ASC, name COLLATE NOCASE ASC, type_sort COLLATE NOCASE ASC, item_id ASC\";\n}\n\nexport function getContainerContentsDocumentPendingStateCtes(): string {\n return `\n document_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'documents' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n document_pending_attachment_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_attachment_count,\n COALESCE(SUM(byte_length), 0) AS pending_attachment_bytes\n FROM document_pending_attachments\n GROUP BY local_id\n )\n `;\n}\n\ninterface ContainerSystemFilterCounts {\n visibleForeignSystemContainerNameCount: number;\n visibleSystemSlotCount: number;\n}\n\nexport function getContainerDisplayNameSql(containerAlias: string): string {\n return `COALESCE(${containerAlias}.display_name, CASE WHEN ${containerAlias}.parent_id IS NULL THEN '/' ELSE 'Untitled' END)`;\n}\n\n/**\n * Display attribution for an object reached through a container: the\n * container's organization when attached, else the projection row's own.\n */\nexport function getContainerOrganizationAttributionSql(aliases: {\n containerAlias: string;\n projectionAlias: string;\n}): string {\n return `COALESCE(NULLIF(${aliases.containerAlias}.organization_id, ''), NULLIF(${aliases.projectionAlias}.organization_id, ''))`;\n}\n\nfunction getContainerContentsContainerSystemSlotFilter(\n counts: ContainerSystemFilterCounts,\n): string {\n const clauses = [\"c.system_slot IS NULL\"];\n\n if (counts.visibleSystemSlotCount > 0) {\n const visibleSystemSlotBindMarkers = Array.from(\n { length: counts.visibleSystemSlotCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(`c.system_slot IN (${visibleSystemSlotBindMarkers})`);\n }\n\n if (counts.visibleForeignSystemContainerNameCount > 0) {\n const visibleSystemNameBindMarkers = Array.from(\n { length: counts.visibleForeignSystemContainerNameCount },\n () => \"?\",\n ).join(\", \");\n clauses.push(\n `(c.organization_id != '' AND c.organization_id != ? AND ${getContainerDisplayNameSql(\"c\")} IN (${visibleSystemNameBindMarkers}))`,\n );\n }\n\n return `(${clauses.join(\" OR \")})`;\n}\n\n/**\n * A `(document, container)` placement under a tombstone hold is hidden from\n * container views: the server said the document left the container, but the\n * signed head that would prove it is not yet available, so the row is kept\n * and hidden rather than deleted (`container_document_tombstone_holds`).\n */\nfunction getHeldPlacementExclusionSql(\n documentIdSql: string,\n containerIdSql: string,\n): string {\n return `\n AND NOT EXISTS (\n SELECT 1\n FROM container_document_tombstone_holds hold\n WHERE hold.document_id = ${documentIdSql}\n AND hold.container_id = ${containerIdSql}\n AND hold.hidden = 1\n )`;\n}\n\nexport function getContainerContentsContainerItemsBaseSql(\n visibleSystemSlotCount = 0,\n visibleForeignSystemContainerNameCount = 0,\n): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_metadata_pending_update_counts AS (\n SELECT\n local_id,\n COUNT(*) AS pending_update_count\n FROM document_history_updates\n WHERE app_kind = 'container-metadata' AND update_id IS NOT NULL\n GROUP BY local_id\n ),\n pending_container_create_intents AS (\n SELECT\n subject_id AS container_id,\n MAX(last_error) AS last_error\n FROM local_intents\n WHERE lane = '${LOCAL_INTENT_LANES.containerCreate}'\n AND intent_type = 'container.create'\n AND sync_status = 'pending'\n GROUP BY subject_id\n ),\n container_items AS (\n SELECT\n 'container' AS item_kind,\n 0 AS item_kind_sort,\n c.id AS item_id,\n NULL AS document_id,\n NULL AS document_kind,\n c.metadata_document_id AS metadata_document_id,\n c.local_updated_at AS local_updated_at,\n c.server_created_at AS server_created_at,\n c.server_updated_at AS server_updated_at,\n c.icon AS icon,\n COALESCE(container_updates.pending_update_count, 0) AS pending_update_count,\n 0 AS pending_attachment_count,\n 0 AS pending_attachment_bytes,\n create_intent.last_error AS sync_last_error,\n ${getContainerDisplayNameSql(\"c\")} AS name,\n 'folder' AS type_sort,\n COALESCE(c.server_created_at, c.local_created_at) AS created_at,\n COALESCE(c.server_updated_at, c.local_updated_at) AS updated_at\n FROM containers c\n LEFT JOIN container_metadata_pending_update_counts container_updates\n ON container_updates.local_id = c.id\n LEFT JOIN pending_container_create_intents create_intent\n ON create_intent.container_id = c.id\n WHERE c.parent_id = ?\n AND ${hydratedProjectionSql(\"c.id\", \"container-metadata\")}\n AND ${getContainerContentsContainerSystemSlotFilter({\n visibleForeignSystemContainerNameCount,\n visibleSystemSlotCount,\n })}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_items\n `;\n}\n\nexport function getContainerContentsDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n container_documents AS (\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND d.container_id = ?${getHeldPlacementExclusionSql(\"d.document_id\", \"d.container_id\")}\n\n UNION ALL\n\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n linked.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_container_projection linked\n INNER JOIN document_projection d ON d.document_id = linked.document_id\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND linked.container_id = ?\n AND (\n d.container_id IS NULL\n OR d.container_id != linked.container_id\n )${getHeldPlacementExclusionSql(\"linked.document_id\", \"linked.container_id\")}\n )\n SELECT *\n FROM container_documents\n `;\n}\n\nexport function getOrphanedDocumentItemsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()},\n orphaned_document_items AS (\n SELECT\n 'document' AS item_kind,\n 1 AS item_kind_sort,\n d.local_id AS item_id,\n d.document_id AS document_id,\n d.document_kind AS document_kind,\n NULL AS metadata_document_id,\n NULL AS local_updated_at,\n NULL AS server_created_at,\n NULL AS server_updated_at,\n NULL AS icon,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error,\n d.title AS name,\n d.document_kind AS type_sort,\n d.updated_at AS created_at,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n )\n SELECT *\n FROM orphaned_document_items\n `;\n}\n\nexport function getOrphanedDocumentRowsBaseSql(): string {\n return `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n d.title AS title,\n d.updated_at AS updated_at\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n `;\n}\n\nexport function getOrphanedDocumentExistsSql(): string {\n return `\n SELECT 1\n FROM document_projection d\n WHERE ${hydratedProjectionSql(\"d.local_id\", \"documents\")}\n AND ${getOrphanedDocumentWhereSql({\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n })}\n LIMIT 1\n `;\n}\n\nexport function getContainerContentsContainerDocumentSidebarOrderBy(): string {\n return \"updated_at IS NULL ASC, updated_at DESC, title COLLATE NOCASE ASC, local_id ASC\";\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { ensureContainerTables } from "../../data/persistence/containers/contain
|
|
|
3
3
|
import { containerContentsSyncLane, sqlContainerSyncWatermarkPersistence, } from "../../data/persistence/containers/containerSyncWatermarkPersistence.js";
|
|
4
4
|
import { sqlDocumentContainerProjectionPersistence } from "../../data/persistence/containers/documentContainerProjectionPersistence.js";
|
|
5
5
|
import { applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones, sqlDocumentsPersistence, upsertDiscoveredDocuments, } from "../../data/persistence/documents/documentsPersistence.js";
|
|
6
|
-
import {
|
|
6
|
+
import { localIntentTables } from "../../data/sqlite/schema.js";
|
|
7
7
|
import { ensureSqlTables } from "../../data/sqlite/sqlSchema.js";
|
|
8
8
|
import { hydratedProjectionSql } from "./documentQueries/hydrationSql.js";
|
|
9
9
|
import { mapContainerContentsDocumentSummaryRow, mapContainerContentsDocumentSyncStateRow, mapContainerDocumentSidebarRow, mapContainerItemRow, readContainerContentsContainerItemCount, } from "./documentQueries/rows.js";
|
|
@@ -15,7 +15,7 @@ import { listPendingWrites, resetPendingWriteRetryState, } from "./pendingWrites
|
|
|
15
15
|
async function listContainerItemWindow(execSql, input) {
|
|
16
16
|
await ensureContainerTables(execSql);
|
|
17
17
|
await sqlDocumentsPersistence.ensureSchema(execSql);
|
|
18
|
-
await ensureSqlTables(execSql,
|
|
18
|
+
await ensureSqlTables(execSql, localIntentTables);
|
|
19
19
|
const limit = getContainerItemWindowLimit(input.limit);
|
|
20
20
|
const offset = clampContainerItemWindowValue(input.offset);
|
|
21
21
|
const visibleSystemSlots = Array.from(new Set(input.visibleSystemSlots ?? []));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentQueries.js","sourceRoot":"","sources":["documentQueries.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { SyncWatermark } from \"@tearleads/validators/response\";\nimport type {\n DiscoveredDocumentInput,\n DocumentSummary,\n} from \"../../data/documents/documentSummary\";\nimport {\n hasRetainedContainerMetadata,\n listRecoveryFolderMoveIds,\n} from \"../../data/persistence/container-contents/containerRecoveryPersistence\";\nimport { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport {\n containerContentsSyncLane,\n sqlContainerSyncWatermarkPersistence,\n} from \"../../data/persistence/containers/containerSyncWatermarkPersistence\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport {\n applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones,\n sqlDocumentsPersistence,\n upsertDiscoveredDocuments,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport { containerCreateIntentTables } from \"../../data/sqlite/schema\";\nimport { type ExecSql, ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport { hydratedProjectionSql } from \"./documentQueries/hydrationSql\";\nimport {\n mapContainerContentsDocumentSummaryRow,\n mapContainerContentsDocumentSyncStateRow,\n mapContainerDocumentSidebarRow,\n mapContainerItemRow,\n readContainerContentsContainerItemCount,\n} from \"./documentQueries/rows\";\nimport {\n clampContainerItemWindowValue,\n getContainerContentsContainerDocumentSidebarOrderBy,\n getContainerContentsContainerItemOrderBy,\n getContainerContentsContainerItemsBaseSql,\n getContainerContentsDocumentPendingStateCtes,\n getContainerContentsDocumentRowsBaseSql,\n getContainerDocumentSidebarWindowLimit,\n getContainerItemWindowLimit,\n getOrphanedDocumentExistsSql,\n getOrphanedDocumentItemsBaseSql,\n getOrphanedDocumentRowsBaseSql,\n listContainerContentsSqlIdBatches,\n} from \"./documentQueries/sql\";\nimport type {\n ContainerDocumentLinkInput,\n ContainerDocumentQueriesRuntime,\n ContainerDocumentSidebarWindow,\n ContainerDocumentTombstone,\n ContainerItemSort,\n ContainerItemWindow,\n} from \"./documentQueries/types\";\nimport {\n createFolderRecoveryQueries,\n type RecoveryFolder,\n} from \"./folderRecovery\";\nimport {\n getOrphanedDocumentQueryBind,\n getOrphanedDocumentWhereSql,\n} from \"./orphanedDocumentSql\";\nimport {\n listPendingDownloads,\n type PendingDownloadQueueItem,\n} from \"./pendingDownloads\";\nimport {\n listPendingWrites,\n type PendingWriteQueueItem,\n resetPendingWriteRetryState,\n} from \"./pendingWrites\";\nimport type { ContainerDocumentObjectSyncState } from \"./syncState\";\n\nexport type {\n ContainerDocumentLinkInput,\n ContainerDocumentSidebarRow,\n ContainerDocumentTombstone,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n} from \"./documentQueries/types\";\n\ninterface ListContainerItemWindowInput {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n sort: ContainerItemSort;\n visibleForeignSystemContainerNames?: ReadonlyArray<string> | undefined;\n visibleSystemSlots?: ReadonlyArray<ContainerSystemSlot> | undefined;\n}\n\nexport interface ContainerDocumentQueries {\n listRecoveryFolderMoveIds(input: {\n currentOrganizationId: string | null;\n }): Promise<string[]>;\n listRecoveryFolders(input: {\n currentOrganizationId: string | null;\n }): Promise<RecoveryFolder[]>;\n discardRecoveryFolder(\n input: Pick<RecoveryFolder, \"containerId\" | \"organizationId\" | \"revision\">,\n ): Promise<boolean>;\n applyContainerDocumentTombstones(\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n hasOrphanedDocuments(input: {\n currentOrganizationId: string | null;\n }): Promise<boolean>;\n listContainerDocumentSidebarWindow(input: {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n }): Promise<ContainerDocumentSidebarWindow>;\n listContainerItemWindow(\n input: ListContainerItemWindowInput,\n ): Promise<ContainerItemWindow>;\n loadDocumentSyncState(\n localId: string,\n ): Promise<ContainerDocumentObjectSyncState | null>;\n loadDocumentSummary(\n localId: string,\n options?: { requireHydrated?: boolean },\n ): Promise<DocumentSummary | null>;\n loadOrphanedDocumentSummary(input: {\n requireHydrated?: boolean;\n currentOrganizationId: string | null;\n localId: string;\n }): Promise<DocumentSummary | null>;\n loadContainerDocumentWatermark(\n containerId: string,\n ): Promise<SyncWatermark | null>;\n listLinkedContainerIdsByDocumentIds(\n documentIds: ReadonlyArray<string>,\n ): Promise<ReadonlyMap<string, ReadonlyArray<string>>>;\n listPendingDownloads(): Promise<ReadonlyArray<PendingDownloadQueueItem>>;\n listPendingWrites(): Promise<ReadonlyArray<PendingWriteQueueItem>>;\n retryPendingWriteItem(input: {\n localId: string;\n namespace: string | null;\n objectKind: PendingWriteQueueItem[\"objectKind\"];\n }): Promise<void>;\n replaceDocumentLinksBatch(\n inputs: ReadonlyArray<ContainerDocumentLinkInput>,\n ): Promise<void>;\n saveContainerDocumentWatermark(\n containerId: string,\n watermark: SyncWatermark,\n ): Promise<void>;\n upsertDiscoveredDocuments(\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n}\n\nasync function listContainerItemWindow(\n execSql: ExecSql,\n input: ListContainerItemWindowInput,\n): Promise<ContainerItemWindow> {\n await ensureContainerTables(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, containerCreateIntentTables);\n\n const limit = getContainerItemWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const visibleSystemSlots = Array.from(\n new Set(input.visibleSystemSlots ?? []),\n );\n const currentOrganizationId = input.currentOrganizationId || null;\n const visibleForeignSystemContainerNames = currentOrganizationId\n ? Array.from(new Set(input.visibleForeignSystemContainerNames ?? []))\n : [];\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [\n input.containerId,\n ...visibleSystemSlots,\n ...(visibleForeignSystemContainerNames.length > 0\n ? [currentOrganizationId, ...visibleForeignSystemContainerNames]\n : []),\n input.containerId,\n input.containerId,\n ];\n const baseSql = orphaned\n ? getOrphanedDocumentItemsBaseSql()\n : getContainerContentsContainerItemsBaseSql(\n visibleSystemSlots.length,\n visibleForeignSystemContainerNames.length,\n );\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerItemOrderBy(input.sort)} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map((row) => mapContainerItemRow(input.containerId, row)),\n totalCount,\n };\n}\n\nasync function hasOrphanedDocuments(\n execSql: ExecSql,\n currentOrganizationId: string | null,\n): Promise<boolean> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n getOrphanedDocumentExistsSql(),\n getOrphanedDocumentQueryBind(currentOrganizationId),\n );\n return (\n rows.length > 0 ||\n (await hasRetainedContainerMetadata(execSql, currentOrganizationId)) ||\n (await listRecoveryFolderMoveIds(execSql, currentOrganizationId)).length > 0\n );\n}\n\nasync function listContainerDocumentSidebarWindow(\n execSql: ExecSql,\n input: {\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n },\n): Promise<ContainerDocumentSidebarWindow> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const limit = getContainerDocumentSidebarWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [input.containerId, input.containerId];\n const baseSql = orphaned\n ? getOrphanedDocumentRowsBaseSql()\n : getContainerContentsDocumentRowsBaseSql();\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerDocumentSidebarOrderBy()} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map(mapContainerDocumentSidebarRow),\n totalCount,\n };\n}\n\nasync function queryContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n scope: { bind: ReadonlyArray<string | null>; whereSql: string },\n): Promise<DocumentSummary | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n d.title AS title,\n d.updated_at AS updated_at,\n stored.access_state_hash AS access_state_hash,\n stored.effective_access_level AS effective_access_level\n FROM document_projection d\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = d.local_id\n WHERE d.local_id = ?\n ${scope.whereSql}\n LIMIT 1\n `,\n [localId, ...scope.bind],\n );\n\n return mapContainerContentsDocumentSummaryRow(rows[0] ?? {});\n}\n\nfunction loadContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: [],\n whereSql: requireHydrated\n ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}`\n : \"\",\n });\n}\n\nfunction loadContainerContentsOrphanedDocumentSummary(\n execSql: ExecSql,\n localId: string,\n currentOrganizationId: string | null,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: getOrphanedDocumentQueryBind(currentOrganizationId),\n whereSql: `${requireHydrated ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}` : \"\"} AND ${getOrphanedDocumentWhereSql(\n {\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n },\n )}`,\n });\n}\n\nasync function loadContainerContentsDocumentSyncState(\n execSql: ExecSql,\n localId: string,\n): Promise<ContainerDocumentObjectSyncState | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.document_id AS document_id,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE d.local_id = ?\n LIMIT 1\n `,\n [localId],\n );\n const [row] = rows;\n if (!row) {\n return null;\n }\n\n return mapContainerContentsDocumentSyncStateRow(row);\n}\n\nasync function listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql: ExecSql,\n documentIds: ReadonlyArray<string>,\n): Promise<ReadonlyMap<string, ReadonlyArray<string>>> {\n const uniqueDocumentIds = Array.from(new Set(documentIds));\n if (uniqueDocumentIds.length === 0) {\n return new Map();\n }\n\n const linkedContainerIdsByDocumentId = new Map<string, string[]>();\n for (const documentId of uniqueDocumentIds) {\n linkedContainerIdsByDocumentId.set(documentId, []);\n }\n\n for (const documentIdBatch of listContainerContentsSqlIdBatches(\n uniqueDocumentIds,\n )) {\n const batchLinkedContainerIdsByDocumentId =\n await sqlDocumentContainerProjectionPersistence.listLinkedContainerIdsByDocumentIds(\n execSql,\n documentIdBatch,\n );\n for (const [\n documentId,\n linkedContainerIds,\n ] of batchLinkedContainerIdsByDocumentId.entries()) {\n linkedContainerIdsByDocumentId.set(\n documentId,\n Array.from(linkedContainerIds),\n );\n }\n }\n\n return linkedContainerIdsByDocumentId;\n}\n\nexport function createContainerDocumentQueriesFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): ContainerDocumentQueries {\n const execSql = runtime.infra.execSql;\n return {\n ...createFolderRecoveryQueries(execSql),\n applyContainerDocumentTombstones(tombstones) {\n return applyPersistedContainerDocumentTombstones(execSql, tombstones);\n },\n hasOrphanedDocuments({ currentOrganizationId }) {\n return hasOrphanedDocuments(execSql, currentOrganizationId);\n },\n listContainerDocumentSidebarWindow(input) {\n return listContainerDocumentSidebarWindow(execSql, input);\n },\n listContainerItemWindow(input) {\n return listContainerItemWindow(execSql, input);\n },\n loadDocumentSyncState(localId) {\n return loadContainerContentsDocumentSyncState(execSql, localId);\n },\n loadDocumentSummary(localId, options) {\n return loadContainerContentsDocumentSummary(\n execSql,\n localId,\n options?.requireHydrated ?? false,\n );\n },\n loadOrphanedDocumentSummary({\n currentOrganizationId,\n localId,\n requireHydrated = false,\n }) {\n return loadContainerContentsOrphanedDocumentSummary(\n execSql,\n localId,\n currentOrganizationId,\n requireHydrated,\n );\n },\n loadContainerDocumentWatermark(containerId) {\n return sqlContainerSyncWatermarkPersistence.loadWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n );\n },\n listLinkedContainerIdsByDocumentIds(documentIds) {\n return listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql,\n documentIds,\n );\n },\n listPendingDownloads() {\n return listPendingDownloads(execSql);\n },\n listPendingWrites() {\n return listPendingWrites(execSql);\n },\n retryPendingWriteItem(input) {\n return resetPendingWriteRetryState(execSql, input);\n },\n replaceDocumentLinksBatch(inputs) {\n return sqlDocumentContainerProjectionPersistence.replaceDocumentLinksBatch(\n execSql,\n inputs,\n );\n },\n async saveContainerDocumentWatermark(containerId, watermark) {\n await sqlContainerSyncWatermarkPersistence.saveWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n watermark,\n );\n },\n upsertDiscoveredDocuments(inputs) {\n return upsertDiscoveredDocuments(execSql, inputs);\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentQueries.js","sourceRoot":"","sources":["documentQueries.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { SyncWatermark } from \"@tearleads/validators/response\";\nimport type {\n DiscoveredDocumentInput,\n DocumentSummary,\n} from \"../../data/documents/documentSummary\";\nimport {\n hasRetainedContainerMetadata,\n listRecoveryFolderMoveIds,\n} from \"../../data/persistence/container-contents/containerRecoveryPersistence\";\nimport { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport {\n containerContentsSyncLane,\n sqlContainerSyncWatermarkPersistence,\n} from \"../../data/persistence/containers/containerSyncWatermarkPersistence\";\nimport { sqlDocumentContainerProjectionPersistence } from \"../../data/persistence/containers/documentContainerProjectionPersistence\";\nimport {\n applyContainerDocumentTombstones as applyPersistedContainerDocumentTombstones,\n sqlDocumentsPersistence,\n upsertDiscoveredDocuments,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport { localIntentTables } from \"../../data/sqlite/schema\";\nimport { type ExecSql, ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport { hydratedProjectionSql } from \"./documentQueries/hydrationSql\";\nimport {\n mapContainerContentsDocumentSummaryRow,\n mapContainerContentsDocumentSyncStateRow,\n mapContainerDocumentSidebarRow,\n mapContainerItemRow,\n readContainerContentsContainerItemCount,\n} from \"./documentQueries/rows\";\nimport {\n clampContainerItemWindowValue,\n getContainerContentsContainerDocumentSidebarOrderBy,\n getContainerContentsContainerItemOrderBy,\n getContainerContentsContainerItemsBaseSql,\n getContainerContentsDocumentPendingStateCtes,\n getContainerContentsDocumentRowsBaseSql,\n getContainerDocumentSidebarWindowLimit,\n getContainerItemWindowLimit,\n getOrphanedDocumentExistsSql,\n getOrphanedDocumentItemsBaseSql,\n getOrphanedDocumentRowsBaseSql,\n listContainerContentsSqlIdBatches,\n} from \"./documentQueries/sql\";\nimport type {\n ContainerDocumentLinkInput,\n ContainerDocumentQueriesRuntime,\n ContainerDocumentSidebarWindow,\n ContainerDocumentTombstone,\n ContainerItemSort,\n ContainerItemWindow,\n} from \"./documentQueries/types\";\nimport {\n createFolderRecoveryQueries,\n type RecoveryFolder,\n} from \"./folderRecovery\";\nimport {\n getOrphanedDocumentQueryBind,\n getOrphanedDocumentWhereSql,\n} from \"./orphanedDocumentSql\";\nimport {\n listPendingDownloads,\n type PendingDownloadQueueItem,\n} from \"./pendingDownloads\";\nimport {\n listPendingWrites,\n type PendingWriteQueueItem,\n resetPendingWriteRetryState,\n} from \"./pendingWrites\";\nimport type { ContainerDocumentObjectSyncState } from \"./syncState\";\n\nexport type {\n ContainerDocumentLinkInput,\n ContainerDocumentSidebarRow,\n ContainerDocumentTombstone,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n} from \"./documentQueries/types\";\n\ninterface ListContainerItemWindowInput {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n sort: ContainerItemSort;\n visibleForeignSystemContainerNames?: ReadonlyArray<string> | undefined;\n visibleSystemSlots?: ReadonlyArray<ContainerSystemSlot> | undefined;\n}\n\nexport interface ContainerDocumentQueries {\n listRecoveryFolderMoveIds(input: {\n currentOrganizationId: string | null;\n }): Promise<string[]>;\n listRecoveryFolders(input: {\n currentOrganizationId: string | null;\n }): Promise<RecoveryFolder[]>;\n discardRecoveryFolder(\n input: Pick<RecoveryFolder, \"containerId\" | \"organizationId\" | \"revision\">,\n ): Promise<boolean>;\n applyContainerDocumentTombstones(\n tombstones: ReadonlyArray<ContainerDocumentTombstone>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n hasOrphanedDocuments(input: {\n currentOrganizationId: string | null;\n }): Promise<boolean>;\n listContainerDocumentSidebarWindow(input: {\n /** Null selects the virtual orphaned-documents recovery collection. */\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n }): Promise<ContainerDocumentSidebarWindow>;\n listContainerItemWindow(\n input: ListContainerItemWindowInput,\n ): Promise<ContainerItemWindow>;\n loadDocumentSyncState(\n localId: string,\n ): Promise<ContainerDocumentObjectSyncState | null>;\n loadDocumentSummary(\n localId: string,\n options?: { requireHydrated?: boolean },\n ): Promise<DocumentSummary | null>;\n loadOrphanedDocumentSummary(input: {\n requireHydrated?: boolean;\n currentOrganizationId: string | null;\n localId: string;\n }): Promise<DocumentSummary | null>;\n loadContainerDocumentWatermark(\n containerId: string,\n ): Promise<SyncWatermark | null>;\n listLinkedContainerIdsByDocumentIds(\n documentIds: ReadonlyArray<string>,\n ): Promise<ReadonlyMap<string, ReadonlyArray<string>>>;\n listPendingDownloads(): Promise<ReadonlyArray<PendingDownloadQueueItem>>;\n listPendingWrites(): Promise<ReadonlyArray<PendingWriteQueueItem>>;\n retryPendingWriteItem(input: {\n localId: string;\n namespace: string | null;\n objectKind: PendingWriteQueueItem[\"objectKind\"];\n }): Promise<void>;\n replaceDocumentLinksBatch(\n inputs: ReadonlyArray<ContainerDocumentLinkInput>,\n ): Promise<void>;\n saveContainerDocumentWatermark(\n containerId: string,\n watermark: SyncWatermark,\n ): Promise<void>;\n upsertDiscoveredDocuments(\n inputs: ReadonlyArray<DiscoveredDocumentInput>,\n ): Promise<ReadonlyArray<DocumentSummary>>;\n}\n\nasync function listContainerItemWindow(\n execSql: ExecSql,\n input: ListContainerItemWindowInput,\n): Promise<ContainerItemWindow> {\n await ensureContainerTables(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n await ensureSqlTables(execSql, localIntentTables);\n\n const limit = getContainerItemWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const visibleSystemSlots = Array.from(\n new Set(input.visibleSystemSlots ?? []),\n );\n const currentOrganizationId = input.currentOrganizationId || null;\n const visibleForeignSystemContainerNames = currentOrganizationId\n ? Array.from(new Set(input.visibleForeignSystemContainerNames ?? []))\n : [];\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [\n input.containerId,\n ...visibleSystemSlots,\n ...(visibleForeignSystemContainerNames.length > 0\n ? [currentOrganizationId, ...visibleForeignSystemContainerNames]\n : []),\n input.containerId,\n input.containerId,\n ];\n const baseSql = orphaned\n ? getOrphanedDocumentItemsBaseSql()\n : getContainerContentsContainerItemsBaseSql(\n visibleSystemSlots.length,\n visibleForeignSystemContainerNames.length,\n );\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerItemOrderBy(input.sort)} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map((row) => mapContainerItemRow(input.containerId, row)),\n totalCount,\n };\n}\n\nasync function hasOrphanedDocuments(\n execSql: ExecSql,\n currentOrganizationId: string | null,\n): Promise<boolean> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const rows = await execSql(\n getOrphanedDocumentExistsSql(),\n getOrphanedDocumentQueryBind(currentOrganizationId),\n );\n return (\n rows.length > 0 ||\n (await hasRetainedContainerMetadata(execSql, currentOrganizationId)) ||\n (await listRecoveryFolderMoveIds(execSql, currentOrganizationId)).length > 0\n );\n}\n\nasync function listContainerDocumentSidebarWindow(\n execSql: ExecSql,\n input: {\n containerId: string | null;\n currentOrganizationId?: string | null | undefined;\n limit: number;\n offset: number;\n },\n): Promise<ContainerDocumentSidebarWindow> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const limit = getContainerDocumentSidebarWindowLimit(input.limit);\n const offset = clampContainerItemWindowValue(input.offset);\n const orphaned = input.containerId === null;\n const bind = orphaned\n ? getOrphanedDocumentQueryBind(input.currentOrganizationId)\n : [input.containerId, input.containerId];\n const baseSql = orphaned\n ? getOrphanedDocumentRowsBaseSql()\n : getContainerContentsDocumentRowsBaseSql();\n const countRows = await execSql(\n `SELECT COUNT(*) AS total_count FROM (${baseSql})`,\n bind,\n );\n const totalCount = readContainerContentsContainerItemCount(\n countRows[0] ?? {},\n );\n\n if (limit === 0 || offset >= totalCount) {\n return { rows: [], totalCount };\n }\n\n const rows = await execSql(\n `${baseSql} ORDER BY ${getContainerContentsContainerDocumentSidebarOrderBy()} LIMIT ? OFFSET ?`,\n [...bind, limit, offset],\n );\n\n return {\n rows: rows.map(mapContainerDocumentSidebarRow),\n totalCount,\n };\n}\n\nasync function queryContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n scope: { bind: ReadonlyArray<string | null>; whereSql: string },\n): Promise<DocumentSummary | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n SELECT\n d.local_id AS local_id,\n d.document_id AS document_id,\n d.container_id AS container_id,\n d.document_kind AS document_kind,\n d.title AS title,\n d.updated_at AS updated_at,\n stored.access_state_hash AS access_state_hash,\n stored.effective_access_level AS effective_access_level\n FROM document_projection d\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = d.local_id\n WHERE d.local_id = ?\n ${scope.whereSql}\n LIMIT 1\n `,\n [localId, ...scope.bind],\n );\n\n return mapContainerContentsDocumentSummaryRow(rows[0] ?? {});\n}\n\nfunction loadContainerContentsDocumentSummary(\n execSql: ExecSql,\n localId: string,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: [],\n whereSql: requireHydrated\n ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}`\n : \"\",\n });\n}\n\nfunction loadContainerContentsOrphanedDocumentSummary(\n execSql: ExecSql,\n localId: string,\n currentOrganizationId: string | null,\n requireHydrated: boolean,\n): Promise<DocumentSummary | null> {\n return queryContainerContentsDocumentSummary(execSql, localId, {\n bind: getOrphanedDocumentQueryBind(currentOrganizationId),\n whereSql: `${requireHydrated ? `AND ${hydratedProjectionSql(\"d.local_id\", \"documents\")}` : \"\"} AND ${getOrphanedDocumentWhereSql(\n {\n documentIdSql: \"d.document_id\",\n projectionAlias: \"d\",\n },\n )}`,\n });\n}\n\nasync function loadContainerContentsDocumentSyncState(\n execSql: ExecSql,\n localId: string,\n): Promise<ContainerDocumentObjectSyncState | null> {\n await sqlDocumentsPersistence.ensureSchema(execSql);\n\n const rows = await execSql(\n `\n WITH ${getContainerContentsDocumentPendingStateCtes()}\n SELECT\n d.document_id AS document_id,\n COALESCE(document_updates.pending_update_count, 0) AS pending_update_count,\n COALESCE(document_attachments.pending_attachment_count, 0) AS pending_attachment_count,\n COALESCE(document_attachments.pending_attachment_bytes, 0) AS pending_attachment_bytes,\n NULL AS sync_last_error\n FROM document_projection d\n LEFT JOIN document_pending_update_counts document_updates\n ON document_updates.local_id = d.local_id\n LEFT JOIN document_pending_attachment_counts document_attachments\n ON document_attachments.local_id = d.local_id\n WHERE d.local_id = ?\n LIMIT 1\n `,\n [localId],\n );\n const [row] = rows;\n if (!row) {\n return null;\n }\n\n return mapContainerContentsDocumentSyncStateRow(row);\n}\n\nasync function listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql: ExecSql,\n documentIds: ReadonlyArray<string>,\n): Promise<ReadonlyMap<string, ReadonlyArray<string>>> {\n const uniqueDocumentIds = Array.from(new Set(documentIds));\n if (uniqueDocumentIds.length === 0) {\n return new Map();\n }\n\n const linkedContainerIdsByDocumentId = new Map<string, string[]>();\n for (const documentId of uniqueDocumentIds) {\n linkedContainerIdsByDocumentId.set(documentId, []);\n }\n\n for (const documentIdBatch of listContainerContentsSqlIdBatches(\n uniqueDocumentIds,\n )) {\n const batchLinkedContainerIdsByDocumentId =\n await sqlDocumentContainerProjectionPersistence.listLinkedContainerIdsByDocumentIds(\n execSql,\n documentIdBatch,\n );\n for (const [\n documentId,\n linkedContainerIds,\n ] of batchLinkedContainerIdsByDocumentId.entries()) {\n linkedContainerIdsByDocumentId.set(\n documentId,\n Array.from(linkedContainerIds),\n );\n }\n }\n\n return linkedContainerIdsByDocumentId;\n}\n\nexport function createContainerDocumentQueriesFromRuntime(\n runtime: ContainerDocumentQueriesRuntime,\n): ContainerDocumentQueries {\n const execSql = runtime.infra.execSql;\n return {\n ...createFolderRecoveryQueries(execSql),\n applyContainerDocumentTombstones(tombstones) {\n return applyPersistedContainerDocumentTombstones(execSql, tombstones);\n },\n hasOrphanedDocuments({ currentOrganizationId }) {\n return hasOrphanedDocuments(execSql, currentOrganizationId);\n },\n listContainerDocumentSidebarWindow(input) {\n return listContainerDocumentSidebarWindow(execSql, input);\n },\n listContainerItemWindow(input) {\n return listContainerItemWindow(execSql, input);\n },\n loadDocumentSyncState(localId) {\n return loadContainerContentsDocumentSyncState(execSql, localId);\n },\n loadDocumentSummary(localId, options) {\n return loadContainerContentsDocumentSummary(\n execSql,\n localId,\n options?.requireHydrated ?? false,\n );\n },\n loadOrphanedDocumentSummary({\n currentOrganizationId,\n localId,\n requireHydrated = false,\n }) {\n return loadContainerContentsOrphanedDocumentSummary(\n execSql,\n localId,\n currentOrganizationId,\n requireHydrated,\n );\n },\n loadContainerDocumentWatermark(containerId) {\n return sqlContainerSyncWatermarkPersistence.loadWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n );\n },\n listLinkedContainerIdsByDocumentIds(documentIds) {\n return listContainerContentsLinkedContainerIdsByDocumentIds(\n execSql,\n documentIds,\n );\n },\n listPendingDownloads() {\n return listPendingDownloads(execSql);\n },\n listPendingWrites() {\n return listPendingWrites(execSql);\n },\n retryPendingWriteItem(input) {\n return resetPendingWriteRetryState(execSql, input);\n },\n replaceDocumentLinksBatch(inputs) {\n return sqlDocumentContainerProjectionPersistence.replaceDocumentLinksBatch(\n execSql,\n inputs,\n );\n },\n async saveContainerDocumentWatermark(containerId, watermark) {\n await sqlContainerSyncWatermarkPersistence.saveWatermark(\n execSql,\n containerContentsSyncLane(containerId),\n watermark,\n );\n },\n upsertDiscoveredDocuments(inputs) {\n return upsertDiscoveredDocuments(execSql, inputs);\n },\n };\n}\n"]}
|
|
@@ -9,18 +9,15 @@ export async function listPendingDownloads(execSql) {
|
|
|
9
9
|
SELECT stored.local_id, stored.document_id, stored.app_kind,
|
|
10
10
|
CASE WHEN ${emptyContentFrontierSql("stored")} THEN NULL
|
|
11
11
|
WHEN stored.app_kind = 'documents' THEN d.title
|
|
12
|
-
ELSE
|
|
12
|
+
ELSE folder.display_name END AS title,
|
|
13
13
|
CASE WHEN ${emptyContentFrontierSql("stored")} THEN 'initial'
|
|
14
14
|
ELSE 'continuation' END AS reason,
|
|
15
|
-
|
|
15
|
+
stored.sync_failure_message AS last_error
|
|
16
16
|
FROM documents stored
|
|
17
17
|
LEFT JOIN document_projection d ON stored.app_kind = 'documents'
|
|
18
18
|
AND d.local_id = stored.local_id
|
|
19
19
|
LEFT JOIN containers folder ON stored.app_kind = 'container-metadata'
|
|
20
20
|
AND folder.id = stored.local_id
|
|
21
|
-
LEFT JOIN container_projection c ON c.container_id = folder.id
|
|
22
|
-
LEFT JOIN document_sync_failures failure ON failure.app_kind = stored.app_kind
|
|
23
|
-
AND failure.local_id = stored.local_id
|
|
24
21
|
WHERE stored.document_id IS NOT NULL
|
|
25
22
|
AND (${emptyContentFrontierSql("stored")} OR stored.pull_continuation IS NOT NULL)
|
|
26
23
|
AND ((stored.app_kind = 'documents' AND d.local_id IS NOT NULL)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pendingDownloads.js","sourceRoot":"","sources":["pendingDownloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wDAAwD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAEhG,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAYzE,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB;IAEhB,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,uBAAuB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;;kBAEX,uBAAuB,CAAC,QAAQ,CAAC;;;kBAGjC,uBAAuB,CAAC,QAAQ,CAAC
|
|
1
|
+
{"version":3,"file":"pendingDownloads.js","sourceRoot":"","sources":["pendingDownloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wDAAwD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAEhG,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAYzE,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB;IAEhB,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,uBAAuB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;;kBAEX,uBAAuB,CAAC,QAAQ,CAAC;;;kBAGjC,uBAAuB,CAAC,QAAQ,CAAC;;;;;;;;;aAStC,uBAAuB,CAAC,QAAQ,CAAC;;;;GAI3C,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,MAAM,EACJ,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,UAAU,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,EACL,MAAM,EACN,UAAU,EAAE,SAAS,GACtB,GAAG,GAAG,CAAC;QACR,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,UAAU,KAAK,QAAQ;YAC/D,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAA6B;YACrC,OAAO;YACP,UAAU;YACV,UAAU,EAAE,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW;YAC9D,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;YAC/C,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc;YACzD,SAAS,EAAE,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;SAC5D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ensureContainerTables } from \"../../data/persistence/containers/containerPersistence\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { emptyContentFrontierSql } from \"./documentQueries/hydrationSql\";\n\nexport interface PendingDownloadQueueItem {\n localId: string;\n documentId: string;\n objectKind: \"document\" | \"container\";\n /** Null until content supplies a reliable title and type. */\n title: string | null;\n reason: \"initial\" | \"continuation\";\n lastError: string | null;\n}\n\n/** Durable, already-discovered content pulls, including folder metadata. */\nexport async function listPendingDownloads(\n execSql: ExecSql,\n): Promise<ReadonlyArray<PendingDownloadQueueItem>> {\n await ensureContainerTables(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n const rows = await execSql(`\n SELECT stored.local_id, stored.document_id, stored.app_kind,\n CASE WHEN ${emptyContentFrontierSql(\"stored\")} THEN NULL\n WHEN stored.app_kind = 'documents' THEN d.title\n ELSE folder.display_name END AS title,\n CASE WHEN ${emptyContentFrontierSql(\"stored\")} THEN 'initial'\n ELSE 'continuation' END AS reason,\n stored.sync_failure_message AS last_error\n FROM documents stored\n LEFT JOIN document_projection d ON stored.app_kind = 'documents'\n AND d.local_id = stored.local_id\n LEFT JOIN containers folder ON stored.app_kind = 'container-metadata'\n AND folder.id = stored.local_id\n WHERE stored.document_id IS NOT NULL\n AND (${emptyContentFrontierSql(\"stored\")} OR stored.pull_continuation IS NOT NULL)\n AND ((stored.app_kind = 'documents' AND d.local_id IS NOT NULL)\n OR (stored.app_kind = 'container-metadata' AND folder.id IS NOT NULL))\n ORDER BY stored.updated_at, stored.app_kind, stored.local_id\n `);\n return rows.flatMap((row) => {\n const {\n local_id: localId,\n document_id: documentId,\n app_kind: appKind,\n title,\n reason,\n last_error: lastError,\n } = row;\n if (typeof localId !== \"string\" || typeof documentId !== \"string\")\n return [];\n const item: PendingDownloadQueueItem = {\n localId,\n documentId,\n objectKind: appKind === \"documents\" ? \"document\" : \"container\",\n title: typeof title === \"string\" ? title : null,\n reason: reason === \"initial\" ? \"initial\" : \"continuation\",\n lastError: typeof lastError === \"string\" ? lastError : null,\n };\n return [item];\n });\n}\n"]}
|
|
@@ -32,14 +32,11 @@ const DEFERRED_TAIL_CANDIDATE_SQL = `
|
|
|
32
32
|
WHEN metadata_container.server_created_at IS NULL THEN NULL
|
|
33
33
|
ELSE metadata_container.id
|
|
34
34
|
END AS container_remote_id,
|
|
35
|
-
${getContainerDisplayNameSql(
|
|
36
|
-
containerAlias: "metadata_container",
|
|
37
|
-
projectionAlias: "container_projection",
|
|
38
|
-
})} AS container_name,
|
|
35
|
+
${getContainerDisplayNameSql("metadata_container")} AS container_name,
|
|
39
36
|
metadata_container.id AS metadata_container_id,
|
|
40
37
|
NULLIF(metadata_container.organization_id, '') AS metadata_organization_id,
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
stored.sync_failure_message AS failure_message,
|
|
39
|
+
stored.sync_failure_attempted_at AS failure_attempted_at
|
|
43
40
|
FROM documents stored
|
|
44
41
|
LEFT JOIN document_projection
|
|
45
42
|
ON stored.app_kind = 'documents'
|
|
@@ -49,11 +46,6 @@ const DEFERRED_TAIL_CANDIDATE_SQL = `
|
|
|
49
46
|
LEFT JOIN containers metadata_container
|
|
50
47
|
ON stored.app_kind = 'container-metadata'
|
|
51
48
|
AND metadata_container.id = stored.local_id
|
|
52
|
-
LEFT JOIN container_projection
|
|
53
|
-
ON container_projection.container_id = metadata_container.id
|
|
54
|
-
LEFT JOIN document_sync_failures failure
|
|
55
|
-
ON failure.app_kind = stored.app_kind
|
|
56
|
-
AND failure.local_id = stored.local_id
|
|
57
49
|
WHERE stored.snapshot_end_version <> ''
|
|
58
50
|
-- Dormant retained metadata (row 4, access_revoked) has no containers
|
|
59
51
|
-- row; keep it out of deferred-tail candidates until re-attach, matching
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deferredTails.js","sourceRoot":"","sources":["deferredTails.ts"],"names":[],"mappings":"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","sourcesContent":["import { mergeVersionVectors, satisfiesVersionVector } from \"@tearleads/loro\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n getContainerDisplayNameSql,\n getContainerOrganizationAttributionSql,\n} from \"../documentQueries/sql\";\nimport type { PendingWriteQueueObjectKind } from \"../pendingWritesTypes\";\nimport type { PendingWriteCandidate } from \"./aggregation\";\nimport { readString } from \"./rowReaders\";\n\n// Deliberately never loads document content: the diagnostic listing runs\n// repeatedly while sync drains, and materializing every content blob would\n// make the scan O(total document content). `snapshot_end_version` is the\n// write-time-derived end version vector of the persisted content.\nconst DEFERRED_TAIL_CANDIDATE_SQL = `\n SELECT\n stored.app_kind AS app_kind,\n stored.local_id AS local_id,\n stored.document_id AS stored_remote_id,\n stored.snapshot_end_version AS snapshot_end_version,\n stored.pending_base_version AS pending_base_version,\n stored.updated_at AS updated_at,\n (\n SELECT pending.partial_end_version_vector\n FROM document_history_updates pending\n WHERE pending.app_kind = stored.app_kind\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n ORDER BY pending.created_at DESC, pending.rowid DESC\n LIMIT 1\n ) AS latest_pending_end_version,\n document_projection.title AS document_name,\n document_projection.container_id AS document_container_id,\n ${getContainerOrganizationAttributionSql({\n containerAlias: \"document_container\",\n projectionAlias: \"document_projection\",\n })} AS document_organization_id,\n CASE\n WHEN metadata_container.server_created_at IS NULL THEN NULL\n ELSE metadata_container.id\n END AS container_remote_id,\n ${getContainerDisplayNameSql({\n containerAlias: \"metadata_container\",\n projectionAlias: \"container_projection\",\n })} AS container_name,\n metadata_container.id AS metadata_container_id,\n NULLIF(metadata_container.organization_id, '') AS metadata_organization_id,\n failure.message AS failure_message,\n failure.attempted_at AS failure_attempted_at\n FROM documents stored\n LEFT JOIN document_projection\n ON stored.app_kind = 'documents'\n AND document_projection.local_id = stored.local_id\n LEFT JOIN containers document_container\n ON document_container.id = document_projection.container_id\n LEFT JOIN containers metadata_container\n ON stored.app_kind = 'container-metadata'\n AND metadata_container.id = stored.local_id\n LEFT JOIN container_projection\n ON container_projection.container_id = metadata_container.id\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = stored.app_kind\n AND failure.local_id = stored.local_id\n WHERE stored.snapshot_end_version <> ''\n -- Dormant retained metadata (row 4, access_revoked) has no containers\n -- row; keep it out of deferred-tail candidates until re-attach, matching\n -- the pending-write sources guard.\n AND (stored.app_kind <> 'container-metadata'\n OR metadata_container.id IS NOT NULL)\n AND (\n stored.pending_base_version IS NOT NULL\n OR EXISTS (\n SELECT 1\n FROM document_history_updates pending\n WHERE pending.app_kind = stored.app_kind\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n )\n )\n`;\n\nfunction hasUncoveredTail(input: {\n currentVersion: string;\n latestPendingEndVersion: string | null;\n pendingBaseVersion: string | null;\n}): boolean {\n const coverageVersions = [\n input.latestPendingEndVersion,\n input.pendingBaseVersion,\n ].filter((value): value is string => value !== null);\n const validCoverageVersions: string[] = [];\n for (const coverageVersion of coverageVersions) {\n try {\n validCoverageVersions.push(mergeVersionVectors([coverageVersion]));\n } catch {\n // Corrupt coverage must not make the diagnostic claim an uncovered write.\n return false;\n }\n }\n if (validCoverageVersions.length === 0) {\n return false;\n }\n\n try {\n const mergedCoverage = mergeVersionVectors(validCoverageVersions);\n return !satisfiesVersionVector(mergedCoverage, input.currentVersion);\n } catch {\n // Corrupt coverage must not make the diagnostic claim an uncovered write.\n return false;\n }\n}\n\nfunction getObjectKind(appKind: string): PendingWriteQueueObjectKind {\n if (appKind === \"documents\") return \"document\";\n if (appKind === \"container-metadata\") return \"container\";\n return \"unknown\";\n}\n\nfunction mapDeferredTailCandidate(\n row: Record<string, unknown>,\n): PendingWriteCandidate | null {\n const appKind = readString(row, \"app_kind\");\n const localId = readString(row, \"local_id\");\n const currentVersion = readString(row, \"snapshot_end_version\");\n if (!appKind || !localId || !currentVersion) {\n return null;\n }\n if (\n !hasUncoveredTail({\n currentVersion,\n latestPendingEndVersion: readString(row, \"latest_pending_end_version\"),\n pendingBaseVersion: readString(row, \"pending_base_version\"),\n })\n ) {\n return null;\n }\n\n const objectKind = getObjectKind(appKind);\n const updatedAt = readString(row, \"updated_at\");\n return {\n byteLength: 0,\n containerId:\n objectKind === \"container\"\n ? readString(row, \"metadata_container_id\")\n : objectKind === \"document\"\n ? readString(row, \"document_container_id\")\n : null,\n count: 1,\n createdAt: updatedAt,\n inclusion: \"always\",\n kind: \"deferred-update\",\n // Carry the scope's recorded sync failure so a covering deferred-update\n // candidate never hides the diagnostic a suppressed failure-only item\n // would have shown.\n lastAttemptedAt: readString(row, \"failure_attempted_at\"),\n lastError: readString(row, \"failure_message\"),\n localId,\n name:\n objectKind === \"container\"\n ? readString(row, \"container_name\")\n : objectKind === \"document\"\n ? readString(row, \"document_name\")\n : null,\n namespace: objectKind === \"unknown\" ? appKind : null,\n objectKind,\n organizationId:\n objectKind === \"container\"\n ? readString(row, \"metadata_organization_id\")\n : objectKind === \"document\"\n ? readString(row, \"document_organization_id\")\n : null,\n remoteId:\n objectKind === \"container\"\n ? readString(row, \"container_remote_id\")\n : readString(row, \"stored_remote_id\"),\n status: \"pending\",\n targetContainerId: null,\n updatedAt,\n };\n}\n\nexport async function listDeferredPendingWriteCandidates(\n execSql: ExecSql,\n): Promise<PendingWriteCandidate[]> {\n const rows = await execSql(DEFERRED_TAIL_CANDIDATE_SQL);\n return rows.flatMap((row) => {\n const candidate = mapDeferredTailCandidate(row);\n return candidate ? [candidate] : [];\n });\n}\n\nconst DEFERRED_TAIL_SCOPE_SQL = `\n SELECT\n stored.snapshot_end_version AS snapshot_end_version,\n stored.pending_base_version AS pending_base_version,\n (\n SELECT pending.partial_end_version_vector\n FROM document_history_updates pending\n WHERE pending.app_kind = stored.app_kind\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n ORDER BY pending.created_at DESC, pending.rowid DESC\n LIMIT 1\n ) AS latest_pending_end_version\n FROM documents stored\n WHERE stored.app_kind = ? AND stored.local_id = ?\n AND stored.snapshot_end_version <> ''\n -- Dormant retained metadata (row 4, access_revoked) has no containers\n -- row; it is not queued work until re-attach, matching the candidate\n -- scan's guard.\n AND (stored.app_kind <> 'container-metadata'\n OR EXISTS (SELECT 1 FROM containers WHERE containers.id = stored.local_id))\n LIMIT 1\n`;\n\n/**\n * Whether this one scope has a deferred write: durable-tail content ahead of\n * its covered frontier, possibly with no queued update rows at all. The same\n * coverage check as the candidate scan, narrowed to a single scope, so\n * \"queued work\" classifications agree with the item the panel rendered.\n */\nexport async function hasDeferredTailScopeWork(\n execSql: ExecSql,\n scope: { appKind: string; localId: string },\n): Promise<boolean> {\n const rows = await execSql(DEFERRED_TAIL_SCOPE_SQL, [\n scope.appKind,\n scope.localId,\n ]);\n const row = rows[0];\n if (!row) {\n return false;\n }\n const currentVersion = readString(row, \"snapshot_end_version\");\n if (!currentVersion) {\n return false;\n }\n return hasUncoveredTail({\n currentVersion,\n latestPendingEndVersion: readString(row, \"latest_pending_end_version\"),\n pendingBaseVersion: readString(row, \"pending_base_version\"),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"deferredTails.js","sourceRoot":"","sources":["deferredTails.ts"],"names":[],"mappings":"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","sourcesContent":["import { mergeVersionVectors, satisfiesVersionVector } from \"@tearleads/loro\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n getContainerDisplayNameSql,\n getContainerOrganizationAttributionSql,\n} from \"../documentQueries/sql\";\nimport type { PendingWriteQueueObjectKind } from \"../pendingWritesTypes\";\nimport type { PendingWriteCandidate } from \"./aggregation\";\nimport { readString } from \"./rowReaders\";\n\n// Deliberately never loads document content: the diagnostic listing runs\n// repeatedly while sync drains, and materializing every content blob would\n// make the scan O(total document content). `snapshot_end_version` is the\n// write-time-derived end version vector of the persisted content.\nconst DEFERRED_TAIL_CANDIDATE_SQL = `\n SELECT\n stored.app_kind AS app_kind,\n stored.local_id AS local_id,\n stored.document_id AS stored_remote_id,\n stored.snapshot_end_version AS snapshot_end_version,\n stored.pending_base_version AS pending_base_version,\n stored.updated_at AS updated_at,\n (\n SELECT pending.partial_end_version_vector\n FROM document_history_updates pending\n WHERE pending.app_kind = stored.app_kind\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n ORDER BY pending.created_at DESC, pending.rowid DESC\n LIMIT 1\n ) AS latest_pending_end_version,\n document_projection.title AS document_name,\n document_projection.container_id AS document_container_id,\n ${getContainerOrganizationAttributionSql({\n containerAlias: \"document_container\",\n projectionAlias: \"document_projection\",\n })} AS document_organization_id,\n CASE\n WHEN metadata_container.server_created_at IS NULL THEN NULL\n ELSE metadata_container.id\n END AS container_remote_id,\n ${getContainerDisplayNameSql(\"metadata_container\")} AS container_name,\n metadata_container.id AS metadata_container_id,\n NULLIF(metadata_container.organization_id, '') AS metadata_organization_id,\n stored.sync_failure_message AS failure_message,\n stored.sync_failure_attempted_at AS failure_attempted_at\n FROM documents stored\n LEFT JOIN document_projection\n ON stored.app_kind = 'documents'\n AND document_projection.local_id = stored.local_id\n LEFT JOIN containers document_container\n ON document_container.id = document_projection.container_id\n LEFT JOIN containers metadata_container\n ON stored.app_kind = 'container-metadata'\n AND metadata_container.id = stored.local_id\n WHERE stored.snapshot_end_version <> ''\n -- Dormant retained metadata (row 4, access_revoked) has no containers\n -- row; keep it out of deferred-tail candidates until re-attach, matching\n -- the pending-write sources guard.\n AND (stored.app_kind <> 'container-metadata'\n OR metadata_container.id IS NOT NULL)\n AND (\n stored.pending_base_version IS NOT NULL\n OR EXISTS (\n SELECT 1\n FROM document_history_updates pending\n WHERE pending.app_kind = stored.app_kind\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n )\n )\n`;\n\nfunction hasUncoveredTail(input: {\n currentVersion: string;\n latestPendingEndVersion: string | null;\n pendingBaseVersion: string | null;\n}): boolean {\n const coverageVersions = [\n input.latestPendingEndVersion,\n input.pendingBaseVersion,\n ].filter((value): value is string => value !== null);\n const validCoverageVersions: string[] = [];\n for (const coverageVersion of coverageVersions) {\n try {\n validCoverageVersions.push(mergeVersionVectors([coverageVersion]));\n } catch {\n // Corrupt coverage must not make the diagnostic claim an uncovered write.\n return false;\n }\n }\n if (validCoverageVersions.length === 0) {\n return false;\n }\n\n try {\n const mergedCoverage = mergeVersionVectors(validCoverageVersions);\n return !satisfiesVersionVector(mergedCoverage, input.currentVersion);\n } catch {\n // Corrupt coverage must not make the diagnostic claim an uncovered write.\n return false;\n }\n}\n\nfunction getObjectKind(appKind: string): PendingWriteQueueObjectKind {\n if (appKind === \"documents\") return \"document\";\n if (appKind === \"container-metadata\") return \"container\";\n return \"unknown\";\n}\n\nfunction mapDeferredTailCandidate(\n row: Record<string, unknown>,\n): PendingWriteCandidate | null {\n const appKind = readString(row, \"app_kind\");\n const localId = readString(row, \"local_id\");\n const currentVersion = readString(row, \"snapshot_end_version\");\n if (!appKind || !localId || !currentVersion) {\n return null;\n }\n if (\n !hasUncoveredTail({\n currentVersion,\n latestPendingEndVersion: readString(row, \"latest_pending_end_version\"),\n pendingBaseVersion: readString(row, \"pending_base_version\"),\n })\n ) {\n return null;\n }\n\n const objectKind = getObjectKind(appKind);\n const updatedAt = readString(row, \"updated_at\");\n return {\n byteLength: 0,\n containerId:\n objectKind === \"container\"\n ? readString(row, \"metadata_container_id\")\n : objectKind === \"document\"\n ? readString(row, \"document_container_id\")\n : null,\n count: 1,\n createdAt: updatedAt,\n inclusion: \"always\",\n kind: \"deferred-update\",\n // Carry the scope's recorded sync failure so a covering deferred-update\n // candidate never hides the diagnostic a suppressed failure-only item\n // would have shown.\n lastAttemptedAt: readString(row, \"failure_attempted_at\"),\n lastError: readString(row, \"failure_message\"),\n localId,\n name:\n objectKind === \"container\"\n ? readString(row, \"container_name\")\n : objectKind === \"document\"\n ? readString(row, \"document_name\")\n : null,\n namespace: objectKind === \"unknown\" ? appKind : null,\n objectKind,\n organizationId:\n objectKind === \"container\"\n ? readString(row, \"metadata_organization_id\")\n : objectKind === \"document\"\n ? readString(row, \"document_organization_id\")\n : null,\n remoteId:\n objectKind === \"container\"\n ? readString(row, \"container_remote_id\")\n : readString(row, \"stored_remote_id\"),\n status: \"pending\",\n targetContainerId: null,\n updatedAt,\n };\n}\n\nexport async function listDeferredPendingWriteCandidates(\n execSql: ExecSql,\n): Promise<PendingWriteCandidate[]> {\n const rows = await execSql(DEFERRED_TAIL_CANDIDATE_SQL);\n return rows.flatMap((row) => {\n const candidate = mapDeferredTailCandidate(row);\n return candidate ? [candidate] : [];\n });\n}\n\nconst DEFERRED_TAIL_SCOPE_SQL = `\n SELECT\n stored.snapshot_end_version AS snapshot_end_version,\n stored.pending_base_version AS pending_base_version,\n (\n SELECT pending.partial_end_version_vector\n FROM document_history_updates pending\n WHERE pending.app_kind = stored.app_kind\n AND pending.local_id = stored.local_id\n AND pending.update_id IS NOT NULL\n ORDER BY pending.created_at DESC, pending.rowid DESC\n LIMIT 1\n ) AS latest_pending_end_version\n FROM documents stored\n WHERE stored.app_kind = ? AND stored.local_id = ?\n AND stored.snapshot_end_version <> ''\n -- Dormant retained metadata (row 4, access_revoked) has no containers\n -- row; it is not queued work until re-attach, matching the candidate\n -- scan's guard.\n AND (stored.app_kind <> 'container-metadata'\n OR EXISTS (SELECT 1 FROM containers WHERE containers.id = stored.local_id))\n LIMIT 1\n`;\n\n/**\n * Whether this one scope has a deferred write: durable-tail content ahead of\n * its covered frontier, possibly with no queued update rows at all. The same\n * coverage check as the candidate scan, narrowed to a single scope, so\n * \"queued work\" classifications agree with the item the panel rendered.\n */\nexport async function hasDeferredTailScopeWork(\n execSql: ExecSql,\n scope: { appKind: string; localId: string },\n): Promise<boolean> {\n const rows = await execSql(DEFERRED_TAIL_SCOPE_SQL, [\n scope.appKind,\n scope.localId,\n ]);\n const row = rows[0];\n if (!row) {\n return false;\n }\n const currentVersion = readString(row, \"snapshot_end_version\");\n if (!currentVersion) {\n return false;\n }\n return hasUncoveredTail({\n currentVersion,\n latestPendingEndVersion: readString(row, \"latest_pending_end_version\"),\n pendingBaseVersion: readString(row, \"pending_base_version\"),\n });\n}\n"]}
|