@tearleads/client-sdk 0.1.43 → 0.1.44
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/containerDocumentDiscovery.js +71 -29
- package/client/containerDocumentDiscovery.js.map +1 -1
- package/client/deviceFirst.js +4 -5
- package/client/deviceFirst.js.map +1 -1
- package/data/persistence/containers/containerSyncWatermarkPersistence.d.ts +11 -3
- package/data/persistence/containers/containerSyncWatermarkPersistence.js +46 -58
- package/data/persistence/containers/containerSyncWatermarkPersistence.js.map +1 -1
- package/data/sqlite/schema.d.ts +34 -134
- package/data/sqlite/schema.js +22 -35
- package/data/sqlite/schema.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +6 -34
- package/internal/api-client/ApiClient.js +8 -10
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/apiRequestRuntime.d.ts +2 -0
- package/internal/api-client/apiRequestRuntime.js +4 -0
- package/internal/api-client/apiRequestRuntime.js.map +1 -1
- package/internal/api-client/requestInternals.js +7 -7
- package/internal/api-client/requestInternals.js.map +1 -1
- package/internal/api-client/routes/containers/reads.d.ts +13 -7
- package/internal/api-client/routes/containers/reads.js +36 -15
- package/internal/api-client/routes/containers/reads.js.map +1 -1
- package/internal/api-client/types.d.ts +1 -5
- package/internal/api-client/types.js.map +1 -1
- package/internal/validators/containerReadRefinements.js +15 -5
- package/internal/validators/containerReadRefinements.js.map +1 -1
- package/internal/validators/containerReadSchemas.d.ts +36 -0
- package/internal/validators/containerReadSchemas.js +64 -1
- package/internal/validators/containerReadSchemas.js.map +1 -1
- package/internal/validators/operation/containerReads.d.ts +118 -182
- package/internal/validators/operation/containerReads.js +20 -54
- package/internal/validators/operation/containerReads.js.map +1 -1
- package/internal/validators/operation/index.d.ts +1 -1
- package/internal/validators/operation/index.js +1 -1
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/registry.d.ts +2 -2
- package/internal/validators/operation/registry.js +2 -2
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/request/containerDocumentLanes.d.ts +23 -0
- package/internal/validators/request/containerDocumentLanes.js +23 -0
- package/internal/validators/request/containerDocumentLanes.js.map +1 -0
- package/internal/validators/request/containerParentLanes.js +5 -35
- package/internal/validators/request/containerParentLanes.js.map +1 -1
- package/internal/validators/request/index.d.ts +1 -0
- package/internal/validators/request/index.js +1 -0
- package/internal/validators/request/index.js.map +1 -1
- package/internal/validators/response/containerDocumentLanes.d.ts +82 -0
- package/internal/validators/response/containerDocumentLanes.js +35 -0
- package/internal/validators/response/containerDocumentLanes.js.map +1 -0
- package/internal/validators/response/containerParentLanes.js +3 -15
- package/internal/validators/response/containerParentLanes.js.map +1 -1
- package/internal/validators/response/index.d.ts +2 -1
- package/internal/validators/response/index.js +1 -1
- package/internal/validators/response/index.js.map +1 -1
- package/package.json +1 -1
- package/sync/reconciliation/knownContainerSweep.js +57 -54
- package/sync/reconciliation/knownContainerSweep.js.map +1 -1
- package/sync/reconciliation/reconcileContainer.js +49 -17
- package/sync/reconciliation/reconcileContainer.js.map +1 -1
- package/sync/reconciliation/service.js +44 -16
- package/sync/reconciliation/service.js.map +1 -1
- package/sync/reconciliation/serviceTypes.d.ts +23 -2
- package/sync/reconciliation/serviceTypes.js.map +1 -1
- package/workflows/container-contents/containerDocumentListing.js +92 -38
- package/workflows/container-contents/containerDocumentListing.js.map +1 -1
- package/workflows/container-contents/containerPersistence.d.ts +8 -2
- package/workflows/container-contents/containerPersistence.js +6 -7
- package/workflows/container-contents/containerPersistence.js.map +1 -1
- package/workflows/container-contents/documentDiscovery.d.ts +3 -3
- package/workflows/container-contents/documentDiscovery.js +24 -96
- package/workflows/container-contents/documentDiscovery.js.map +1 -1
- package/workflows/container-contents/documentDiscoveryApply.js +65 -0
- package/workflows/container-contents/documentDiscoveryApply.js.map +1 -0
- package/workflows/container-contents/documentDiscoveryLanes.js +53 -0
- package/workflows/container-contents/documentDiscoveryLanes.js.map +1 -0
- package/workflows/container-contents/documentDiscoveryTypes.d.ts +25 -19
- package/workflows/container-contents/documentDiscoveryTypes.js.map +1 -1
- package/workflows/container-contents/remoteHydration/laneFetchMarkers.js +11 -17
- package/workflows/container-contents/remoteHydration/laneFetchMarkers.js.map +1 -1
- package/workflows/sync/remoteResetCursorScope.js +10 -18
- package/workflows/sync/remoteResetCursorScope.js.map +1 -1
- package/workflows/sync/remoteResetScope.js +4 -11
- package/workflows/sync/remoteResetScope.js.map +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { and, eq, inArray, or } from "drizzle-orm";
|
|
2
|
-
import {
|
|
2
|
+
import { containerSyncWatermarks } from "../../data/sqlite/schema.js";
|
|
3
3
|
import { remoteResetBatches } from "./remoteResetBatches.js";
|
|
4
4
|
const CONTAINER_DOCUMENTS_LANE = "container_documents";
|
|
5
5
|
const CONTAINER_PARENT_LANE = "container_parent";
|
|
@@ -19,26 +19,18 @@ export function isRemoteResetSyncCursor(input) {
|
|
|
19
19
|
input.containerIds.has(input.row.laneId.slice(PARENT_LANE_PREFIX.length)));
|
|
20
20
|
}
|
|
21
21
|
export async function clearRemoteResetSyncCursors(input) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
// One row per lane holds both the cursor and its freshness marker.
|
|
23
|
+
const table = containerSyncWatermarks;
|
|
24
|
+
await input.tx
|
|
25
|
+
.delete(table)
|
|
26
|
+
.where(and(eq(table.laneKind, CONTAINER_PARENT_LANE), eq(table.laneId, ROOT_LANE_ID)))
|
|
27
|
+
.run();
|
|
28
|
+
for (const containerBatch of remoteResetBatches(input.containerIds)) {
|
|
29
|
+
const parentLaneIds = containerBatch.map((containerId) => `${PARENT_LANE_PREFIX}${containerId}`);
|
|
26
30
|
await input.tx
|
|
27
31
|
.delete(table)
|
|
28
|
-
.where(and(eq(table.laneKind, CONTAINER_PARENT_LANE), eq(table.laneId,
|
|
32
|
+
.where(or(and(eq(table.laneKind, CONTAINER_PARENT_LANE), inArray(table.laneId, parentLaneIds)), and(eq(table.laneKind, CONTAINER_DOCUMENTS_LANE), inArray(table.laneId, containerBatch))))
|
|
29
33
|
.run();
|
|
30
34
|
}
|
|
31
|
-
for (const containerBatch of remoteResetBatches(input.containerIds)) {
|
|
32
|
-
const parentLaneIds = containerBatch.map((containerId) => `${PARENT_LANE_PREFIX}${containerId}`);
|
|
33
|
-
for (const table of [
|
|
34
|
-
containerSyncWatermarks,
|
|
35
|
-
containerSyncLaneChecks,
|
|
36
|
-
]) {
|
|
37
|
-
await input.tx
|
|
38
|
-
.delete(table)
|
|
39
|
-
.where(or(and(eq(table.laneKind, CONTAINER_PARENT_LANE), inArray(table.laneId, parentLaneIds)), and(eq(table.laneKind, CONTAINER_DOCUMENTS_LANE), inArray(table.laneId, containerBatch))))
|
|
40
|
-
.run();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
35
|
}
|
|
44
36
|
//# sourceMappingURL=remoteResetCursorScope.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteResetCursorScope.js","sourceRoot":"","sources":["remoteResetCursorScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,
|
|
1
|
+
{"version":3,"file":"remoteResetCursorScope.js","sourceRoot":"","sources":["remoteResetCursorScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AACvD,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AACjD,6EAA6E;AAC7E,0EAA0E;AAC1E,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAOrC,MAAM,UAAU,uBAAuB,CAAC,KAGvC;IACC,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,KAAK,wBAAwB,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,KAAK,qBAAqB;QAAE,OAAO,KAAK,CAAC;IAC/D,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,CACL,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAC/C,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAC1E,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,KAGjD;IACC,mEAAmE;IACnE,MAAM,KAAK,GAAG,uBAAuB,CAAC;IACtC,MAAM,KAAK,CAAC,EAAE;SACX,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EACzC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAC/B,CACF;SACA,GAAG,EAAE,CAAC;IACT,KAAK,MAAM,cAAc,IAAI,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;QACpE,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CACtC,CAAC,WAAW,EAAE,EAAE,CAAC,GAAG,kBAAkB,GAAG,WAAW,EAAE,CACvD,CAAC;QACF,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CACJ,EAAE,CACA,GAAG,CACD,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EACzC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,CACrC,EACD,GAAG,CACD,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,wBAAwB,CAAC,EAC5C,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CACtC,CACF,CACF;aACA,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC","sourcesContent":["import { and, eq, inArray, or } from \"drizzle-orm\";\nimport { containerSyncWatermarks } from \"../../data/sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport { remoteResetBatches } from \"./remoteResetBatches\";\n\nconst CONTAINER_DOCUMENTS_LANE = \"container_documents\";\nconst CONTAINER_PARENT_LANE = \"container_parent\";\n// The API root feed lists every accessible organization. Its one cursor must\n// reset on any organization's purge; child feeds use globally unique IDs.\nconst ROOT_LANE_ID = \"root\";\nconst PARENT_LANE_PREFIX = \"parent:\";\n\ninterface SyncCursorRow {\n readonly laneId: string;\n readonly laneKind: string;\n}\n\nexport function isRemoteResetSyncCursor(input: {\n containerIds: ReadonlySet<string>;\n row: SyncCursorRow;\n}): boolean {\n if (input.row.laneKind === CONTAINER_DOCUMENTS_LANE) {\n return input.containerIds.has(input.row.laneId);\n }\n if (input.row.laneKind !== CONTAINER_PARENT_LANE) return false;\n if (input.row.laneId === ROOT_LANE_ID) return true;\n return (\n input.row.laneId.startsWith(PARENT_LANE_PREFIX) &&\n input.containerIds.has(input.row.laneId.slice(PARENT_LANE_PREFIX.length))\n );\n}\n\nexport async function clearRemoteResetSyncCursors(input: {\n containerIds: readonly string[];\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n // One row per lane holds both the cursor and its freshness marker.\n const table = containerSyncWatermarks;\n await input.tx\n .delete(table)\n .where(\n and(\n eq(table.laneKind, CONTAINER_PARENT_LANE),\n eq(table.laneId, ROOT_LANE_ID),\n ),\n )\n .run();\n for (const containerBatch of remoteResetBatches(input.containerIds)) {\n const parentLaneIds = containerBatch.map(\n (containerId) => `${PARENT_LANE_PREFIX}${containerId}`,\n );\n await input.tx\n .delete(table)\n .where(\n or(\n and(\n eq(table.laneKind, CONTAINER_PARENT_LANE),\n inArray(table.laneId, parentLaneIds),\n ),\n and(\n eq(table.laneKind, CONTAINER_DOCUMENTS_LANE),\n inArray(table.laneId, containerBatch),\n ),\n ),\n )\n .run();\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { eq } from "drizzle-orm";
|
|
2
|
-
import { containerCreateIntents, containerMoveIntents,
|
|
2
|
+
import { containerCreateIntents, containerMoveIntents, containerSyncWatermarks, containers, documentContainerProjection, documentMoveIntents, documentProjection, documents, dormantContainerMetadata, } from "../../data/sqlite/schema.js";
|
|
3
3
|
import { isRemoteResetSyncCursor } from "./remoteResetCursorScope.js";
|
|
4
4
|
import { loadRemoteResetPrincipalScope, } from "./remoteResetPrincipalScope.js";
|
|
5
5
|
function principalKeyOfRow(row) {
|
|
@@ -83,23 +83,16 @@ async function loadSnapshotCounts(input) {
|
|
|
83
83
|
const principalKeys = principalScope.principalKeys;
|
|
84
84
|
const principalKeySet = new Set(principalKeys.map(principalKeyOfRow));
|
|
85
85
|
const scopedContainerIds = new Set(input.containerIds);
|
|
86
|
-
const
|
|
87
|
-
tx.select().from(containerSyncWatermarks),
|
|
88
|
-
tx.select().from(containerSyncLaneChecks),
|
|
89
|
-
]);
|
|
86
|
+
const syncLanes = await tx.select().from(containerSyncWatermarks);
|
|
90
87
|
return {
|
|
91
88
|
clearedContainerCreateIntentCount: createRows.filter((row) => containerIdSet.has(row.containerId)).length,
|
|
92
89
|
clearedContainerMoveIntentCount: moveRows.filter((row) => containerIdSet.has(row.containerId)).length,
|
|
93
90
|
clearedDocumentMoveIntentCount: docMoves.filter((row) => documentScopeKeys.has(scopeKey({ appKind: "documents", localId: row.localId }))).length,
|
|
94
91
|
clearedPrincipalPolicyCount: principalScope.policyRows.filter((row) => principalKeySet.has(`${row.type}\0${row.id}`)).length,
|
|
95
|
-
clearedSyncCursorCount:
|
|
92
|
+
clearedSyncCursorCount: syncLanes.filter((row) => isRemoteResetSyncCursor({
|
|
96
93
|
containerIds: scopedContainerIds,
|
|
97
94
|
row,
|
|
98
|
-
})).length
|
|
99
|
-
laneChecks.filter((row) => isRemoteResetSyncCursor({
|
|
100
|
-
containerIds: scopedContainerIds,
|
|
101
|
-
row,
|
|
102
|
-
})).length,
|
|
95
|
+
})).length,
|
|
103
96
|
principalKeys,
|
|
104
97
|
};
|
|
105
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteResetScope.js","sourceRoot":"","sources":["remoteResetScope.ts"],"names":[],"mappings":"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","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n containerSyncLaneChecks,\n containerSyncWatermarks,\n containers,\n documentContainerProjection,\n documentMoveIntents,\n documentProjection,\n documents,\n dormantContainerMetadata,\n} from \"../../data/sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport { isRemoteResetSyncCursor } from \"./remoteResetCursorScope\";\nimport type { ResetDocumentScope } from \"./remoteResetPlans\";\nimport {\n loadRemoteResetPrincipalScope,\n type RemoteResetPrincipalKey,\n} from \"./remoteResetPrincipalScope\";\n\nexport interface RemoteResetReplacement {\n readonly organizationId: string;\n readonly rootContainerId: string;\n}\n\nexport interface RemoteResetInput {\n readonly organizationId: string;\n readonly replacement?: RemoteResetReplacement | undefined;\n}\n\nexport interface ResetContainerRow {\n readonly id: string;\n readonly parentId: string | null;\n}\n\nexport interface ResetDocumentRow extends ResetDocumentScope {\n readonly documentId: string | null;\n readonly recoveryDocumentId: string | null;\n}\n\nexport interface RemoteSyncStateSnapshot {\n readonly clearedContainerCreateIntentCount: number;\n readonly clearedContainerMoveIntentCount: number;\n readonly clearedDocumentMoveIntentCount: number;\n readonly clearedPrincipalPolicyCount: number;\n readonly clearedSyncCursorCount: number;\n readonly containerIds: readonly string[];\n readonly containerRows: readonly ResetContainerRow[];\n readonly documentLocalIds: readonly string[];\n readonly documentRows: readonly ResetDocumentRow[];\n readonly oldDocumentIds: readonly string[];\n readonly principalKeys: readonly RemoteResetPrincipalKey[];\n}\n\nfunction principalKeyOfRow(row: {\n readonly principalId: string;\n readonly principalType: string;\n}): string {\n return `${row.principalType}\\0${row.principalId}`;\n}\n\nfunction scopeKey(scope: ResetDocumentScope): string {\n return `${scope.appKind}\\0${scope.localId}`;\n}\n\nasync function loadContainerScope(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<{\n containerIds: string[];\n containerRows: ResetContainerRow[];\n}> {\n const liveContainerRows = (\n await tx\n .select({ id: containers.id, parentId: containers.parentId })\n .from(containers)\n .where(eq(containers.organizationId, organizationId))\n ).flatMap((row) => (row.id ? [{ id: row.id, parentId: row.parentId }] : []));\n const dormantContainerRows = await tx\n .select({ id: dormantContainerMetadata.containerId })\n .from(dormantContainerMetadata)\n .where(eq(dormantContainerMetadata.organizationId, organizationId));\n const containerRows = liveContainerRows;\n return {\n containerIds: [\n ...new Set([\n ...containerRows.map((row) => row.id),\n ...dormantContainerRows.map((row) => row.id),\n ]),\n ],\n containerRows,\n };\n}\n\nasync function loadDocumentScope(input: {\n containerIds: readonly string[];\n organizationId: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<{\n documentLocalIds: string[];\n documentRows: ResetDocumentRow[];\n oldDocumentIds: string[];\n}> {\n const { organizationId, tx } = input;\n const containerIdSet = new Set(input.containerIds);\n const [allDocuments, projectionRows, linkRows] =\n await loadDocumentAssociationRows(tx);\n const linkedDocumentIds = new Set(\n linkRows\n .filter((row) => containerIdSet.has(row.containerId))\n .map((row) => row.documentId),\n );\n const projectedLocalIds = new Set(\n projectionRows\n .filter(\n (row) =>\n (row.containerId !== null && containerIdSet.has(row.containerId)) ||\n row.organizationId === organizationId ||\n (row.documentId !== null && linkedDocumentIds.has(row.documentId)),\n )\n .flatMap((row) => (row.localId ? [row.localId] : [])),\n );\n const documentRows = allDocuments.filter(\n (row) =>\n (row.appKind === \"container-metadata\" &&\n containerIdSet.has(row.localId)) ||\n (row.appKind === \"documents\" && projectedLocalIds.has(row.localId)) ||\n (row.documentId !== null && linkedDocumentIds.has(row.documentId)),\n );\n return {\n documentLocalIds: [\n ...new Set(\n documentRows\n .filter((row) => row.appKind === \"documents\")\n .map((row) => row.localId),\n ),\n ],\n documentRows,\n oldDocumentIds: [\n ...new Set(\n documentRows.flatMap((row) => (row.documentId ? [row.documentId] : [])),\n ),\n ],\n };\n}\n\nfunction loadDocumentAssociationRows(tx: ClientSQLiteTransactionScope) {\n return Promise.all([\n tx\n .select({\n appKind: documents.appKind,\n documentId: documents.documentId,\n localId: documents.localId,\n recoveryDocumentId: documents.recoveryDocumentId,\n })\n .from(documents),\n tx.select().from(documentProjection),\n tx.select().from(documentContainerProjection),\n ]);\n}\n\nasync function loadSnapshotCounts(input: {\n containerIds: readonly string[];\n documentRows: readonly ResetDocumentRow[];\n organizationId: string;\n tx: ClientSQLiteTransactionScope;\n}) {\n const { organizationId, tx } = input;\n const containerIdSet = new Set(input.containerIds);\n const documentScopeKeys = new Set(input.documentRows.map(scopeKey));\n const [principalScope, createRows, moveRows, docMoves] = await Promise.all([\n loadRemoteResetPrincipalScope(tx, organizationId),\n tx.select().from(containerCreateIntents),\n tx.select().from(containerMoveIntents),\n tx.select().from(documentMoveIntents),\n ]);\n const principalKeys = principalScope.principalKeys;\n const principalKeySet = new Set(principalKeys.map(principalKeyOfRow));\n const scopedContainerIds = new Set(input.containerIds);\n const [watermarks, laneChecks] = await Promise.all([\n tx.select().from(containerSyncWatermarks),\n tx.select().from(containerSyncLaneChecks),\n ]);\n\n return {\n clearedContainerCreateIntentCount: createRows.filter((row) =>\n containerIdSet.has(row.containerId),\n ).length,\n clearedContainerMoveIntentCount: moveRows.filter((row) =>\n containerIdSet.has(row.containerId),\n ).length,\n clearedDocumentMoveIntentCount: docMoves.filter((row) =>\n documentScopeKeys.has(\n scopeKey({ appKind: \"documents\", localId: row.localId }),\n ),\n ).length,\n clearedPrincipalPolicyCount: principalScope.policyRows.filter((row) =>\n principalKeySet.has(`${row.type}\\0${row.id}`),\n ).length,\n clearedSyncCursorCount:\n watermarks.filter((row) =>\n isRemoteResetSyncCursor({\n containerIds: scopedContainerIds,\n row,\n }),\n ).length +\n laneChecks.filter((row) =>\n isRemoteResetSyncCursor({\n containerIds: scopedContainerIds,\n row,\n }),\n ).length,\n principalKeys,\n };\n}\n\nexport async function readRemoteSyncStateSnapshot(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<RemoteSyncStateSnapshot> {\n const containerScope = await loadContainerScope(tx, organizationId);\n const documentScope = await loadDocumentScope({\n containerIds: containerScope.containerIds,\n organizationId,\n tx,\n });\n const counts = await loadSnapshotCounts({\n containerIds: containerScope.containerIds,\n documentRows: documentScope.documentRows,\n organizationId,\n tx,\n });\n return { ...containerScope, ...documentScope, ...counts };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteResetScope.js","sourceRoot":"","sources":["remoteResetScope.ts"],"names":[],"mappings":"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","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport {\n containerCreateIntents,\n containerMoveIntents,\n containerSyncWatermarks,\n containers,\n documentContainerProjection,\n documentMoveIntents,\n documentProjection,\n documents,\n dormantContainerMetadata,\n} from \"../../data/sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport { isRemoteResetSyncCursor } from \"./remoteResetCursorScope\";\nimport type { ResetDocumentScope } from \"./remoteResetPlans\";\nimport {\n loadRemoteResetPrincipalScope,\n type RemoteResetPrincipalKey,\n} from \"./remoteResetPrincipalScope\";\n\nexport interface RemoteResetReplacement {\n readonly organizationId: string;\n readonly rootContainerId: string;\n}\n\nexport interface RemoteResetInput {\n readonly organizationId: string;\n readonly replacement?: RemoteResetReplacement | undefined;\n}\n\nexport interface ResetContainerRow {\n readonly id: string;\n readonly parentId: string | null;\n}\n\nexport interface ResetDocumentRow extends ResetDocumentScope {\n readonly documentId: string | null;\n readonly recoveryDocumentId: string | null;\n}\n\nexport interface RemoteSyncStateSnapshot {\n readonly clearedContainerCreateIntentCount: number;\n readonly clearedContainerMoveIntentCount: number;\n readonly clearedDocumentMoveIntentCount: number;\n readonly clearedPrincipalPolicyCount: number;\n readonly clearedSyncCursorCount: number;\n readonly containerIds: readonly string[];\n readonly containerRows: readonly ResetContainerRow[];\n readonly documentLocalIds: readonly string[];\n readonly documentRows: readonly ResetDocumentRow[];\n readonly oldDocumentIds: readonly string[];\n readonly principalKeys: readonly RemoteResetPrincipalKey[];\n}\n\nfunction principalKeyOfRow(row: {\n readonly principalId: string;\n readonly principalType: string;\n}): string {\n return `${row.principalType}\\0${row.principalId}`;\n}\n\nfunction scopeKey(scope: ResetDocumentScope): string {\n return `${scope.appKind}\\0${scope.localId}`;\n}\n\nasync function loadContainerScope(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<{\n containerIds: string[];\n containerRows: ResetContainerRow[];\n}> {\n const liveContainerRows = (\n await tx\n .select({ id: containers.id, parentId: containers.parentId })\n .from(containers)\n .where(eq(containers.organizationId, organizationId))\n ).flatMap((row) => (row.id ? [{ id: row.id, parentId: row.parentId }] : []));\n const dormantContainerRows = await tx\n .select({ id: dormantContainerMetadata.containerId })\n .from(dormantContainerMetadata)\n .where(eq(dormantContainerMetadata.organizationId, organizationId));\n const containerRows = liveContainerRows;\n return {\n containerIds: [\n ...new Set([\n ...containerRows.map((row) => row.id),\n ...dormantContainerRows.map((row) => row.id),\n ]),\n ],\n containerRows,\n };\n}\n\nasync function loadDocumentScope(input: {\n containerIds: readonly string[];\n organizationId: string;\n tx: ClientSQLiteTransactionScope;\n}): Promise<{\n documentLocalIds: string[];\n documentRows: ResetDocumentRow[];\n oldDocumentIds: string[];\n}> {\n const { organizationId, tx } = input;\n const containerIdSet = new Set(input.containerIds);\n const [allDocuments, projectionRows, linkRows] =\n await loadDocumentAssociationRows(tx);\n const linkedDocumentIds = new Set(\n linkRows\n .filter((row) => containerIdSet.has(row.containerId))\n .map((row) => row.documentId),\n );\n const projectedLocalIds = new Set(\n projectionRows\n .filter(\n (row) =>\n (row.containerId !== null && containerIdSet.has(row.containerId)) ||\n row.organizationId === organizationId ||\n (row.documentId !== null && linkedDocumentIds.has(row.documentId)),\n )\n .flatMap((row) => (row.localId ? [row.localId] : [])),\n );\n const documentRows = allDocuments.filter(\n (row) =>\n (row.appKind === \"container-metadata\" &&\n containerIdSet.has(row.localId)) ||\n (row.appKind === \"documents\" && projectedLocalIds.has(row.localId)) ||\n (row.documentId !== null && linkedDocumentIds.has(row.documentId)),\n );\n return {\n documentLocalIds: [\n ...new Set(\n documentRows\n .filter((row) => row.appKind === \"documents\")\n .map((row) => row.localId),\n ),\n ],\n documentRows,\n oldDocumentIds: [\n ...new Set(\n documentRows.flatMap((row) => (row.documentId ? [row.documentId] : [])),\n ),\n ],\n };\n}\n\nfunction loadDocumentAssociationRows(tx: ClientSQLiteTransactionScope) {\n return Promise.all([\n tx\n .select({\n appKind: documents.appKind,\n documentId: documents.documentId,\n localId: documents.localId,\n recoveryDocumentId: documents.recoveryDocumentId,\n })\n .from(documents),\n tx.select().from(documentProjection),\n tx.select().from(documentContainerProjection),\n ]);\n}\n\nasync function loadSnapshotCounts(input: {\n containerIds: readonly string[];\n documentRows: readonly ResetDocumentRow[];\n organizationId: string;\n tx: ClientSQLiteTransactionScope;\n}) {\n const { organizationId, tx } = input;\n const containerIdSet = new Set(input.containerIds);\n const documentScopeKeys = new Set(input.documentRows.map(scopeKey));\n const [principalScope, createRows, moveRows, docMoves] = await Promise.all([\n loadRemoteResetPrincipalScope(tx, organizationId),\n tx.select().from(containerCreateIntents),\n tx.select().from(containerMoveIntents),\n tx.select().from(documentMoveIntents),\n ]);\n const principalKeys = principalScope.principalKeys;\n const principalKeySet = new Set(principalKeys.map(principalKeyOfRow));\n const scopedContainerIds = new Set(input.containerIds);\n const syncLanes = await tx.select().from(containerSyncWatermarks);\n\n return {\n clearedContainerCreateIntentCount: createRows.filter((row) =>\n containerIdSet.has(row.containerId),\n ).length,\n clearedContainerMoveIntentCount: moveRows.filter((row) =>\n containerIdSet.has(row.containerId),\n ).length,\n clearedDocumentMoveIntentCount: docMoves.filter((row) =>\n documentScopeKeys.has(\n scopeKey({ appKind: \"documents\", localId: row.localId }),\n ),\n ).length,\n clearedPrincipalPolicyCount: principalScope.policyRows.filter((row) =>\n principalKeySet.has(`${row.type}\\0${row.id}`),\n ).length,\n clearedSyncCursorCount: syncLanes.filter((row) =>\n isRemoteResetSyncCursor({\n containerIds: scopedContainerIds,\n row,\n }),\n ).length,\n principalKeys,\n };\n}\n\nexport async function readRemoteSyncStateSnapshot(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<RemoteSyncStateSnapshot> {\n const containerScope = await loadContainerScope(tx, organizationId);\n const documentScope = await loadDocumentScope({\n containerIds: containerScope.containerIds,\n organizationId,\n tx,\n });\n const counts = await loadSnapshotCounts({\n containerIds: containerScope.containerIds,\n documentRows: documentScope.documentRows,\n organizationId,\n tx,\n });\n return { ...containerScope, ...documentScope, ...counts };\n}\n"]}
|