@tearleads/client-sdk 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/data/blobs/transferPool.js +53 -0
  2. package/data/blobs/transferPool.js.map +1 -0
  3. package/data/documents/blob/shared/types.d.ts +2 -2
  4. package/data/documents/blob/shared/types.js.map +1 -1
  5. package/data/sync/coordinatorLaneRun.js +154 -0
  6. package/data/sync/coordinatorLaneRun.js.map +1 -0
  7. package/data/sync/coordinatorPump.js +72 -169
  8. package/data/sync/coordinatorPump.js.map +1 -1
  9. package/data/sync/coordinatorState.d.ts +6 -0
  10. package/data/sync/coordinatorState.js +3 -1
  11. package/data/sync/coordinatorState.js.map +1 -1
  12. package/data/sync/syncCoordinator.js +4 -3
  13. package/data/sync/syncCoordinator.js.map +1 -1
  14. package/data/sync/syncLaneConfig.d.ts +2 -0
  15. package/data/sync/syncLaneConfig.js.map +1 -1
  16. package/internal/api-client/ApiClient.d.ts +2 -2
  17. package/internal/api-client/ApiClient.js +6 -30
  18. package/internal/api-client/ApiClient.js.map +1 -1
  19. package/internal/api-client/routes/blobs/get.d.ts +2 -2
  20. package/internal/api-client/routes/blobs/get.js +24 -21
  21. package/internal/api-client/routes/blobs/get.js.map +1 -1
  22. package/internal/api-client/routes/blobs/multipartUpload.js +146 -0
  23. package/internal/api-client/routes/blobs/multipartUpload.js.map +1 -0
  24. package/internal/api-client/routes/blobs/storageFetchOptions.js +11 -0
  25. package/internal/api-client/routes/blobs/storageFetchOptions.js.map +1 -0
  26. package/internal/api-client/types.d.ts +1 -1
  27. package/internal/api-client/types.js.map +1 -1
  28. package/internal/validators/operation/blobDownloads.js +3 -9
  29. package/internal/validators/operation/blobDownloads.js.map +1 -1
  30. package/internal/validators/operation/blobTransferSchemas.js +11 -0
  31. package/internal/validators/operation/blobTransferSchemas.js.map +1 -0
  32. package/internal/validators/operation/index.d.ts +1 -0
  33. package/internal/validators/operation/index.js +1 -0
  34. package/internal/validators/operation/index.js.map +1 -1
  35. package/internal/validators/operation/multipartPartUploads.d.ts +179 -0
  36. package/internal/validators/operation/multipartPartUploads.js +47 -0
  37. package/internal/validators/operation/multipartPartUploads.js.map +1 -0
  38. package/internal/validators/operation/registry.d.ts +2 -0
  39. package/internal/validators/operation/registry.js +2 -0
  40. package/internal/validators/operation/registry.js.map +1 -1
  41. package/internal/validators/util/blob.d.ts +2 -4
  42. package/internal/validators/util/blob.js +2 -4
  43. package/internal/validators/util/blob.js.map +1 -1
  44. package/package.json +1 -1
  45. package/stores/documents/documentStore/attachmentHydration.js +33 -0
  46. package/stores/documents/documentStore/attachmentHydration.js.map +1 -1
  47. package/stores/documents/documentStore/remoteWork.js +1 -1
  48. package/stores/documents/documentStore/remoteWork.js.map +1 -1
  49. package/stores/documents/documentStore/sync.js +3 -0
  50. package/stores/documents/documentStore/sync.js.map +1 -1
  51. package/sync/reconciliation/documentContentPull.js +7 -3
  52. package/sync/reconciliation/documentContentPull.js.map +1 -1
  53. package/sync/reconciliation/idleBackfill.js +14 -2
  54. package/sync/reconciliation/idleBackfill.js.map +1 -1
  55. package/sync/reconciliation/knownContainerSweep.js +5 -2
  56. package/sync/reconciliation/knownContainerSweep.js.map +1 -1
  57. package/sync/reconciliation/reconcileContainer.js +3 -3
  58. package/sync/reconciliation/reconcileContainer.js.map +1 -1
  59. package/sync/reconciliation/service.js +9 -4
  60. package/sync/reconciliation/service.js.map +1 -1
  61. package/sync/reconciliation/serviceTypes.d.ts +5 -3
  62. package/sync/reconciliation/serviceTypes.js.map +1 -1
  63. package/sync/reconciliation/triggers.d.ts +2 -1
  64. package/sync/reconciliation/triggers.js +5 -2
  65. package/sync/reconciliation/triggers.js.map +1 -1
  66. package/workflows/blobs/hydrate.d.ts +4 -2
  67. package/workflows/blobs/hydrate.js +21 -7
  68. package/workflows/blobs/hydrate.js.map +1 -1
  69. package/workflows/blobs/multipartStageFailures.js +1 -1
  70. package/workflows/blobs/multipartStageFailures.js.map +1 -1
  71. package/workflows/blobs/multipartUpload.js +69 -39
  72. package/workflows/blobs/multipartUpload.js.map +1 -1
  73. package/workflows/blobs/readAttachmentTransfer.js +42 -0
  74. package/workflows/blobs/readAttachmentTransfer.js.map +1 -0
  75. package/workflows/documents/syncLane.d.ts +1 -0
  76. package/workflows/documents/syncLane.js +1 -0
  77. package/workflows/documents/syncLane.js.map +1 -1
  78. package/workflows/registration/persistRegistrationBootstrap.js +3 -0
  79. package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { ErrorResponseSchema, SessionFailureResponseSchema } from "../response/index.js";
3
+ import { boundedPositiveIntegerSchema, nonEmptyStringSchema, uuidStringSchema, } from "../schema.js";
4
+ import { MAX_MULTIPART_BLOB_PART_BYTES } from "../util/index.js";
5
+ import { MultipartBlobPartPathParamsSchema } from "./blobBytes.js";
6
+ import { blobPartContentMd5Schema, signedBlobUrlExpirySchema, signedBlobUrlSchema, } from "./blobTransferSchemas.js";
7
+ import { defineJsonOperation } from "./definition.js";
8
+ const partByteLengthSchema = boundedPositiveIntegerSchema(MAX_MULTIPART_BLOB_PART_BYTES);
9
+ export const MultipartBlobPartUploadRequestSchema = z.strictObject({
10
+ byteLength: partByteLengthSchema,
11
+ contentMd5: blobPartContentMd5Schema,
12
+ uploadId: nonEmptyStringSchema,
13
+ });
14
+ export const MultipartBlobPartUploadResponseSchema = z.strictObject({
15
+ byteLength: partByteLengthSchema,
16
+ contentMd5: blobPartContentMd5Schema,
17
+ partNumber: boundedPositiveIntegerSchema(10_000),
18
+ stageId: uuidStringSchema,
19
+ uploadId: nonEmptyStringSchema,
20
+ source: z.discriminatedUnion("kind", [
21
+ z.strictObject({ kind: z.literal("api") }),
22
+ z.strictObject({
23
+ kind: z.literal("signed-url"),
24
+ url: signedBlobUrlSchema,
25
+ expiresAt: signedBlobUrlExpirySchema,
26
+ }),
27
+ ]),
28
+ });
29
+ export const authorizeMultipartBlobPartUploadOperation = defineJsonOperation({
30
+ auth: "session",
31
+ body: MultipartBlobPartUploadRequestSchema,
32
+ failureResponses: {
33
+ 400: ErrorResponseSchema,
34
+ 401: SessionFailureResponseSchema,
35
+ 403: ErrorResponseSchema,
36
+ 404: ErrorResponseSchema,
37
+ 409: ErrorResponseSchema,
38
+ 500: ErrorResponseSchema,
39
+ },
40
+ failureStatuses: [400, 401, 403, 404, 409, 500],
41
+ id: "blobs.multipartStages.parts.authorize",
42
+ method: "POST",
43
+ params: MultipartBlobPartPathParamsSchema,
44
+ path: "/blobs/stages/multipart/{stageId}/parts/{partNumber}/upload",
45
+ responses: { 200: MultipartBlobPartUploadResponseSchema },
46
+ });
47
+ //# sourceMappingURL=multipartPartUploads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipartPartUploads.js","sourceRoot":"","sources":["multipartPartUploads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,oBAAoB,GAAG,4BAA4B,CACvD,6BAA6B,CAC9B,CAAC;AAEF,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,CAAC,YAAY,CAAC;IACjE,UAAU,EAAE,oBAAoB;IAChC,UAAU,EAAE,wBAAwB;IACpC,QAAQ,EAAE,oBAAoB;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,CAAC,YAAY,CAAC;IAClE,UAAU,EAAE,oBAAoB;IAChC,UAAU,EAAE,wBAAwB;IACpC,UAAU,EAAE,4BAA4B,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,gBAAgB;IACzB,QAAQ,EAAE,oBAAoB;IAC9B,MAAM,EAAE,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;QACnC,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,CAAC,CAAC,YAAY,CAAC;YACb,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;YAC7B,GAAG,EAAE,mBAAmB;YACxB,SAAS,EAAE,yBAAyB;SACrC,CAAC;KACH,CAAC;CACH,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,yCAAyC,GAAG,mBAAmB,CAAC;IAC3E,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,oCAAoC;IAC1C,gBAAgB,EAAE;QAChB,GAAG,EAAE,mBAAmB;QACxB,GAAG,EAAE,4BAA4B;QACjC,GAAG,EAAE,mBAAmB;QACxB,GAAG,EAAE,mBAAmB;QACxB,GAAG,EAAE,mBAAmB;QACxB,GAAG,EAAE,mBAAmB;KACzB;IACD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC/C,EAAE,EAAE,uCAAuC;IAC3C,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,iCAAiC;IACzC,IAAI,EAAE,6DAA6D;IACnE,SAAS,EAAE,EAAE,GAAG,EAAE,qCAAqC,EAAE;CAC1D,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { ErrorResponseSchema, SessionFailureResponseSchema } from \"../response\";\nimport {\n boundedPositiveIntegerSchema,\n nonEmptyStringSchema,\n uuidStringSchema,\n} from \"../schema\";\nimport { MAX_MULTIPART_BLOB_PART_BYTES } from \"../util\";\nimport { MultipartBlobPartPathParamsSchema } from \"./blobBytes\";\nimport {\n blobPartContentMd5Schema,\n signedBlobUrlExpirySchema,\n signedBlobUrlSchema,\n} from \"./blobTransferSchemas\";\nimport { defineJsonOperation } from \"./definition\";\n\nconst partByteLengthSchema = boundedPositiveIntegerSchema(\n MAX_MULTIPART_BLOB_PART_BYTES,\n);\n\nexport const MultipartBlobPartUploadRequestSchema = z.strictObject({\n byteLength: partByteLengthSchema,\n contentMd5: blobPartContentMd5Schema,\n uploadId: nonEmptyStringSchema,\n});\n\nexport const MultipartBlobPartUploadResponseSchema = z.strictObject({\n byteLength: partByteLengthSchema,\n contentMd5: blobPartContentMd5Schema,\n partNumber: boundedPositiveIntegerSchema(10_000),\n stageId: uuidStringSchema,\n uploadId: nonEmptyStringSchema,\n source: z.discriminatedUnion(\"kind\", [\n z.strictObject({ kind: z.literal(\"api\") }),\n z.strictObject({\n kind: z.literal(\"signed-url\"),\n url: signedBlobUrlSchema,\n expiresAt: signedBlobUrlExpirySchema,\n }),\n ]),\n});\n\nexport type MultipartBlobPartUploadRequest = z.infer<\n typeof MultipartBlobPartUploadRequestSchema\n>;\nexport type MultipartBlobPartUploadResponse = z.infer<\n typeof MultipartBlobPartUploadResponseSchema\n>;\n\nexport const authorizeMultipartBlobPartUploadOperation = defineJsonOperation({\n auth: \"session\",\n body: MultipartBlobPartUploadRequestSchema,\n failureResponses: {\n 400: ErrorResponseSchema,\n 401: SessionFailureResponseSchema,\n 403: ErrorResponseSchema,\n 404: ErrorResponseSchema,\n 409: ErrorResponseSchema,\n 500: ErrorResponseSchema,\n },\n failureStatuses: [400, 401, 403, 404, 409, 500],\n id: \"blobs.multipartStages.parts.authorize\",\n method: \"POST\",\n params: MultipartBlobPartPathParamsSchema,\n path: \"/blobs/stages/multipart/{stageId}/parts/{partNumber}/upload\",\n responses: { 200: MultipartBlobPartUploadResponseSchema },\n});\n"]}
@@ -11,6 +11,7 @@ import { createDocumentOperation, getDocumentPurgeProofOperation, linkDocumentOp
11
11
  import { documentSyncOperation } from "./documentSync.js";
12
12
  import { getHealthOperation } from "./health.js";
13
13
  import { completeMultipartBlobStageOperation, getMultipartBlobStageOperation, initiateMultipartBlobStageOperation } from "./multipartBlobs.js";
14
+ import { authorizeMultipartBlobPartUploadOperation } from "./multipartPartUploads.js";
14
15
  import { claimNativeOrganizationSubscriptionOperation, getOrganizationBillingHistoryOperation, getOrganizationBillingManagementUrlOperation, getOrganizationBillingOperation, getOrganizationNativePurchaseEligibilityOperation, startOrganizationTrialOperation } from "./organizationBilling.js";
15
16
  import { getOrganizationPolicyHistoryOperation } from "./organizationPolicyHistory.js";
16
17
  import { createOrganizationGroupOperation, createOrganizationOperation, deleteOrganizationGroupOperation, getOrganizationDataUsageOperation, getOrganizationReadModelOperation, listOrganizationGroupMembersOperation, updateOrganizationProfileOperation, updateOrganizationRosterEntryOperation } from "./organizations.js";
@@ -40,6 +41,7 @@ export declare const protocolOperations: readonly [
40
41
  typeof initiateMultipartBlobStageOperation,
41
42
  typeof getMultipartBlobStageOperation,
42
43
  typeof completeMultipartBlobStageOperation,
44
+ typeof authorizeMultipartBlobPartUploadOperation,
43
45
  typeof uploadMultipartBlobPartBytesOperation,
44
46
  typeof listDocumentAttachmentsOperation,
45
47
  typeof getDocumentAttributionOperation,
@@ -11,6 +11,7 @@ import { createDocumentOperation, getDocumentPurgeProofOperation, linkDocumentOp
11
11
  import { documentSyncOperation } from "./documentSync.js";
12
12
  import { getHealthOperation } from "./health.js";
13
13
  import { completeMultipartBlobStageOperation, getMultipartBlobStageOperation, initiateMultipartBlobStageOperation, } from "./multipartBlobs.js";
14
+ import { authorizeMultipartBlobPartUploadOperation } from "./multipartPartUploads.js";
14
15
  import { claimNativeOrganizationSubscriptionOperation, getOrganizationBillingHistoryOperation, getOrganizationBillingManagementUrlOperation, getOrganizationBillingOperation, getOrganizationNativePurchaseEligibilityOperation, startOrganizationTrialOperation, } from "./organizationBilling.js";
15
16
  import { getOrganizationPolicyHistoryOperation } from "./organizationPolicyHistory.js";
16
17
  import { createOrganizationGroupOperation, createOrganizationOperation, deleteOrganizationGroupOperation, getOrganizationDataUsageOperation, getOrganizationReadModelOperation, listOrganizationGroupMembersOperation, updateOrganizationProfileOperation, updateOrganizationRosterEntryOperation, } from "./organizations.js";
@@ -42,6 +43,7 @@ export const protocolOperations = [
42
43
  initiateMultipartBlobStageOperation,
43
44
  getMultipartBlobStageOperation,
44
45
  completeMultipartBlobStageOperation,
46
+ authorizeMultipartBlobPartUploadOperation,
45
47
  uploadMultipartBlobPartBytesOperation,
46
48
  listDocumentAttachmentsOperation,
47
49
  getDocumentAttributionOperation,
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["registry.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n bindBlobAttachmentOperation,\n detachBlobAttachmentOperation,\n listDocumentAttachmentsOperation,\n} from \"./attachments\";\nimport {\n challengeOperation,\n destroySessionOperation,\n listSessionsOperation,\n logoutOperation,\n registerOperation,\n userIdentityOperation,\n verifyOperation,\n webSocketTicketOperation,\n} from \"./auth\";\nimport {\n receiveRevenueCatWebhookOperation,\n receiveStripeWebhookOperation,\n} from \"./billingWebhooks\";\nimport {\n getBlobBytesOperation,\n uploadMultipartBlobPartBytesOperation,\n} from \"./blobBytes\";\nimport { getBlobDownloadOperation } from \"./blobDownloads\";\nimport {\n createContainerOperation,\n createContainerWithMetadataDocumentOperation,\n deleteContainerOperation,\n moveContainerOperation,\n reciteContainerOperation,\n rekeyContainerOperation,\n revokeContainerOperation,\n shareContainerOperation,\n} from \"./containerMutations\";\nimport {\n getContainerKekLogOperation,\n listContainerDocumentsOperation,\n listContainerParentLanesOperation,\n} from \"./containerReads\";\nimport { getContainerReplacementAuthorizationsOperation } from \"./containerReplacement\";\nimport {\n getDocumentAttributionOperation,\n listDocumentAttributionRangesOperation,\n} from \"./documentAttribution\";\nimport {\n createDocumentOperation,\n getDocumentPurgeProofOperation,\n linkDocumentOperation,\n purgeDocumentOperation,\n unlinkDocumentOperation,\n} from \"./documentMutations\";\nimport { documentSyncOperation } from \"./documentSync\";\nimport { getHealthOperation } from \"./health\";\nimport {\n completeMultipartBlobStageOperation,\n getMultipartBlobStageOperation,\n initiateMultipartBlobStageOperation,\n} from \"./multipartBlobs\";\nimport {\n claimNativeOrganizationSubscriptionOperation,\n getOrganizationBillingHistoryOperation,\n getOrganizationBillingManagementUrlOperation,\n getOrganizationBillingOperation,\n getOrganizationNativePurchaseEligibilityOperation,\n startOrganizationTrialOperation,\n} from \"./organizationBilling\";\nimport { getOrganizationPolicyHistoryOperation } from \"./organizationPolicyHistory\";\nimport {\n createOrganizationGroupOperation,\n createOrganizationOperation,\n deleteOrganizationGroupOperation,\n getOrganizationDataUsageOperation,\n getOrganizationReadModelOperation,\n listOrganizationGroupMembersOperation,\n updateOrganizationProfileOperation,\n updateOrganizationRosterEntryOperation,\n} from \"./organizations\";\nimport {\n commitOrganizationGroupPolicyOperation,\n getPrincipalPolicyOperation,\n putPrincipalPolicyOperation,\n} from \"./principals\";\nimport { getProjectionPolicyHistoryOperation } from \"./projectionPolicyHistory\";\nimport {\n getRootIdentityOperation,\n listRootIdentitiesOperation,\n listRootIdentityOrganizationsOperation,\n} from \"./root\";\nimport {\n getRootOrganizationDataUsageOperation,\n getRootOrganizationOperation,\n listRootDataUsageReportOperation,\n listRootOrganizationIdentitiesOperation,\n listRootOrganizationsOperation,\n} from \"./rootOrganizations\";\nimport {\n cancelStripeSubscriptionOperation,\n createStripeCheckoutOperation,\n createStripeCheckoutSessionOperation,\n createStripePortalOperation,\n getStripeCheckoutOptionsOperation,\n} from \"./stripeCheckout\";\nimport {\n getContainerWriterProjectionOperation,\n getDocumentWriterProjectionOperation,\n} from \"./writerProjections\";\n\n// Name each imported operation type instead of expanding every Zod schema in\n// the emitted declaration; the exact readonly tuple and runtime order stay intact.\nexport const protocolOperations: readonly [\n typeof getContainerReplacementAuthorizationsOperation,\n typeof getHealthOperation,\n typeof challengeOperation,\n typeof destroySessionOperation,\n typeof listSessionsOperation,\n typeof logoutOperation,\n typeof registerOperation,\n typeof userIdentityOperation,\n typeof verifyOperation,\n typeof webSocketTicketOperation,\n typeof getBlobBytesOperation,\n typeof getBlobDownloadOperation,\n typeof receiveRevenueCatWebhookOperation,\n typeof receiveStripeWebhookOperation,\n typeof bindBlobAttachmentOperation,\n typeof detachBlobAttachmentOperation,\n typeof initiateMultipartBlobStageOperation,\n typeof getMultipartBlobStageOperation,\n typeof completeMultipartBlobStageOperation,\n typeof uploadMultipartBlobPartBytesOperation,\n typeof listDocumentAttachmentsOperation,\n typeof getDocumentAttributionOperation,\n typeof listDocumentAttributionRangesOperation,\n typeof createDocumentOperation,\n typeof getDocumentPurgeProofOperation,\n typeof linkDocumentOperation,\n typeof purgeDocumentOperation,\n typeof unlinkDocumentOperation,\n typeof getContainerKekLogOperation,\n typeof listContainerDocumentsOperation,\n typeof listContainerParentLanesOperation,\n typeof createContainerOperation,\n typeof createContainerWithMetadataDocumentOperation,\n typeof deleteContainerOperation,\n typeof moveContainerOperation,\n typeof reciteContainerOperation,\n typeof rekeyContainerOperation,\n typeof revokeContainerOperation,\n typeof shareContainerOperation,\n typeof getContainerWriterProjectionOperation,\n typeof getDocumentWriterProjectionOperation,\n typeof createOrganizationOperation,\n typeof getOrganizationBillingOperation,\n typeof getOrganizationBillingHistoryOperation,\n typeof getOrganizationBillingManagementUrlOperation,\n typeof getOrganizationNativePurchaseEligibilityOperation,\n typeof claimNativeOrganizationSubscriptionOperation,\n typeof startOrganizationTrialOperation,\n typeof getStripeCheckoutOptionsOperation,\n typeof createStripeCheckoutOperation,\n typeof createStripeCheckoutSessionOperation,\n typeof createStripePortalOperation,\n typeof cancelStripeSubscriptionOperation,\n typeof getOrganizationDataUsageOperation,\n typeof getOrganizationReadModelOperation,\n typeof getOrganizationPolicyHistoryOperation,\n typeof createOrganizationGroupOperation,\n typeof deleteOrganizationGroupOperation,\n typeof listOrganizationGroupMembersOperation,\n typeof updateOrganizationProfileOperation,\n typeof updateOrganizationRosterEntryOperation,\n typeof getPrincipalPolicyOperation,\n typeof getProjectionPolicyHistoryOperation,\n typeof commitOrganizationGroupPolicyOperation,\n typeof putPrincipalPolicyOperation,\n typeof listRootIdentitiesOperation,\n typeof listRootOrganizationsOperation,\n typeof getRootOrganizationDataUsageOperation,\n typeof listRootDataUsageReportOperation,\n typeof getRootOrganizationOperation,\n typeof listRootOrganizationIdentitiesOperation,\n typeof getRootIdentityOperation,\n typeof listRootIdentityOrganizationsOperation,\n typeof documentSyncOperation,\n] = [\n getContainerReplacementAuthorizationsOperation,\n getHealthOperation,\n challengeOperation,\n destroySessionOperation,\n listSessionsOperation,\n logoutOperation,\n registerOperation,\n userIdentityOperation,\n verifyOperation,\n webSocketTicketOperation,\n getBlobBytesOperation,\n getBlobDownloadOperation,\n receiveRevenueCatWebhookOperation,\n receiveStripeWebhookOperation,\n bindBlobAttachmentOperation,\n detachBlobAttachmentOperation,\n initiateMultipartBlobStageOperation,\n getMultipartBlobStageOperation,\n completeMultipartBlobStageOperation,\n uploadMultipartBlobPartBytesOperation,\n listDocumentAttachmentsOperation,\n getDocumentAttributionOperation,\n listDocumentAttributionRangesOperation,\n createDocumentOperation,\n getDocumentPurgeProofOperation,\n linkDocumentOperation,\n purgeDocumentOperation,\n unlinkDocumentOperation,\n getContainerKekLogOperation,\n listContainerDocumentsOperation,\n listContainerParentLanesOperation,\n createContainerOperation,\n createContainerWithMetadataDocumentOperation,\n deleteContainerOperation,\n moveContainerOperation,\n reciteContainerOperation,\n rekeyContainerOperation,\n revokeContainerOperation,\n shareContainerOperation,\n getContainerWriterProjectionOperation,\n getDocumentWriterProjectionOperation,\n createOrganizationOperation,\n getOrganizationBillingOperation,\n getOrganizationBillingHistoryOperation,\n getOrganizationBillingManagementUrlOperation,\n getOrganizationNativePurchaseEligibilityOperation,\n claimNativeOrganizationSubscriptionOperation,\n startOrganizationTrialOperation,\n getStripeCheckoutOptionsOperation,\n createStripeCheckoutOperation,\n createStripeCheckoutSessionOperation,\n createStripePortalOperation,\n cancelStripeSubscriptionOperation,\n getOrganizationDataUsageOperation,\n getOrganizationReadModelOperation,\n getOrganizationPolicyHistoryOperation,\n createOrganizationGroupOperation,\n deleteOrganizationGroupOperation,\n listOrganizationGroupMembersOperation,\n updateOrganizationProfileOperation,\n updateOrganizationRosterEntryOperation,\n getPrincipalPolicyOperation,\n getProjectionPolicyHistoryOperation,\n commitOrganizationGroupPolicyOperation,\n putPrincipalPolicyOperation,\n listRootIdentitiesOperation,\n listRootOrganizationsOperation,\n getRootOrganizationDataUsageOperation,\n listRootDataUsageReportOperation,\n getRootOrganizationOperation,\n listRootOrganizationIdentitiesOperation,\n getRootIdentityOperation,\n listRootIdentityOrganizationsOperation,\n documentSyncOperation,\n];\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["registry.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n bindBlobAttachmentOperation,\n detachBlobAttachmentOperation,\n listDocumentAttachmentsOperation,\n} from \"./attachments\";\nimport {\n challengeOperation,\n destroySessionOperation,\n listSessionsOperation,\n logoutOperation,\n registerOperation,\n userIdentityOperation,\n verifyOperation,\n webSocketTicketOperation,\n} from \"./auth\";\nimport {\n receiveRevenueCatWebhookOperation,\n receiveStripeWebhookOperation,\n} from \"./billingWebhooks\";\nimport {\n getBlobBytesOperation,\n uploadMultipartBlobPartBytesOperation,\n} from \"./blobBytes\";\nimport { getBlobDownloadOperation } from \"./blobDownloads\";\nimport {\n createContainerOperation,\n createContainerWithMetadataDocumentOperation,\n deleteContainerOperation,\n moveContainerOperation,\n reciteContainerOperation,\n rekeyContainerOperation,\n revokeContainerOperation,\n shareContainerOperation,\n} from \"./containerMutations\";\nimport {\n getContainerKekLogOperation,\n listContainerDocumentsOperation,\n listContainerParentLanesOperation,\n} from \"./containerReads\";\nimport { getContainerReplacementAuthorizationsOperation } from \"./containerReplacement\";\nimport {\n getDocumentAttributionOperation,\n listDocumentAttributionRangesOperation,\n} from \"./documentAttribution\";\nimport {\n createDocumentOperation,\n getDocumentPurgeProofOperation,\n linkDocumentOperation,\n purgeDocumentOperation,\n unlinkDocumentOperation,\n} from \"./documentMutations\";\nimport { documentSyncOperation } from \"./documentSync\";\nimport { getHealthOperation } from \"./health\";\nimport {\n completeMultipartBlobStageOperation,\n getMultipartBlobStageOperation,\n initiateMultipartBlobStageOperation,\n} from \"./multipartBlobs\";\nimport { authorizeMultipartBlobPartUploadOperation } from \"./multipartPartUploads\";\nimport {\n claimNativeOrganizationSubscriptionOperation,\n getOrganizationBillingHistoryOperation,\n getOrganizationBillingManagementUrlOperation,\n getOrganizationBillingOperation,\n getOrganizationNativePurchaseEligibilityOperation,\n startOrganizationTrialOperation,\n} from \"./organizationBilling\";\nimport { getOrganizationPolicyHistoryOperation } from \"./organizationPolicyHistory\";\nimport {\n createOrganizationGroupOperation,\n createOrganizationOperation,\n deleteOrganizationGroupOperation,\n getOrganizationDataUsageOperation,\n getOrganizationReadModelOperation,\n listOrganizationGroupMembersOperation,\n updateOrganizationProfileOperation,\n updateOrganizationRosterEntryOperation,\n} from \"./organizations\";\nimport {\n commitOrganizationGroupPolicyOperation,\n getPrincipalPolicyOperation,\n putPrincipalPolicyOperation,\n} from \"./principals\";\nimport { getProjectionPolicyHistoryOperation } from \"./projectionPolicyHistory\";\nimport {\n getRootIdentityOperation,\n listRootIdentitiesOperation,\n listRootIdentityOrganizationsOperation,\n} from \"./root\";\nimport {\n getRootOrganizationDataUsageOperation,\n getRootOrganizationOperation,\n listRootDataUsageReportOperation,\n listRootOrganizationIdentitiesOperation,\n listRootOrganizationsOperation,\n} from \"./rootOrganizations\";\nimport {\n cancelStripeSubscriptionOperation,\n createStripeCheckoutOperation,\n createStripeCheckoutSessionOperation,\n createStripePortalOperation,\n getStripeCheckoutOptionsOperation,\n} from \"./stripeCheckout\";\nimport {\n getContainerWriterProjectionOperation,\n getDocumentWriterProjectionOperation,\n} from \"./writerProjections\";\n\n// Name each imported operation type instead of expanding every Zod schema in\n// the emitted declaration; the exact readonly tuple and runtime order stay intact.\nexport const protocolOperations: readonly [\n typeof getContainerReplacementAuthorizationsOperation,\n typeof getHealthOperation,\n typeof challengeOperation,\n typeof destroySessionOperation,\n typeof listSessionsOperation,\n typeof logoutOperation,\n typeof registerOperation,\n typeof userIdentityOperation,\n typeof verifyOperation,\n typeof webSocketTicketOperation,\n typeof getBlobBytesOperation,\n typeof getBlobDownloadOperation,\n typeof receiveRevenueCatWebhookOperation,\n typeof receiveStripeWebhookOperation,\n typeof bindBlobAttachmentOperation,\n typeof detachBlobAttachmentOperation,\n typeof initiateMultipartBlobStageOperation,\n typeof getMultipartBlobStageOperation,\n typeof completeMultipartBlobStageOperation,\n typeof authorizeMultipartBlobPartUploadOperation,\n typeof uploadMultipartBlobPartBytesOperation,\n typeof listDocumentAttachmentsOperation,\n typeof getDocumentAttributionOperation,\n typeof listDocumentAttributionRangesOperation,\n typeof createDocumentOperation,\n typeof getDocumentPurgeProofOperation,\n typeof linkDocumentOperation,\n typeof purgeDocumentOperation,\n typeof unlinkDocumentOperation,\n typeof getContainerKekLogOperation,\n typeof listContainerDocumentsOperation,\n typeof listContainerParentLanesOperation,\n typeof createContainerOperation,\n typeof createContainerWithMetadataDocumentOperation,\n typeof deleteContainerOperation,\n typeof moveContainerOperation,\n typeof reciteContainerOperation,\n typeof rekeyContainerOperation,\n typeof revokeContainerOperation,\n typeof shareContainerOperation,\n typeof getContainerWriterProjectionOperation,\n typeof getDocumentWriterProjectionOperation,\n typeof createOrganizationOperation,\n typeof getOrganizationBillingOperation,\n typeof getOrganizationBillingHistoryOperation,\n typeof getOrganizationBillingManagementUrlOperation,\n typeof getOrganizationNativePurchaseEligibilityOperation,\n typeof claimNativeOrganizationSubscriptionOperation,\n typeof startOrganizationTrialOperation,\n typeof getStripeCheckoutOptionsOperation,\n typeof createStripeCheckoutOperation,\n typeof createStripeCheckoutSessionOperation,\n typeof createStripePortalOperation,\n typeof cancelStripeSubscriptionOperation,\n typeof getOrganizationDataUsageOperation,\n typeof getOrganizationReadModelOperation,\n typeof getOrganizationPolicyHistoryOperation,\n typeof createOrganizationGroupOperation,\n typeof deleteOrganizationGroupOperation,\n typeof listOrganizationGroupMembersOperation,\n typeof updateOrganizationProfileOperation,\n typeof updateOrganizationRosterEntryOperation,\n typeof getPrincipalPolicyOperation,\n typeof getProjectionPolicyHistoryOperation,\n typeof commitOrganizationGroupPolicyOperation,\n typeof putPrincipalPolicyOperation,\n typeof listRootIdentitiesOperation,\n typeof listRootOrganizationsOperation,\n typeof getRootOrganizationDataUsageOperation,\n typeof listRootDataUsageReportOperation,\n typeof getRootOrganizationOperation,\n typeof listRootOrganizationIdentitiesOperation,\n typeof getRootIdentityOperation,\n typeof listRootIdentityOrganizationsOperation,\n typeof documentSyncOperation,\n] = [\n getContainerReplacementAuthorizationsOperation,\n getHealthOperation,\n challengeOperation,\n destroySessionOperation,\n listSessionsOperation,\n logoutOperation,\n registerOperation,\n userIdentityOperation,\n verifyOperation,\n webSocketTicketOperation,\n getBlobBytesOperation,\n getBlobDownloadOperation,\n receiveRevenueCatWebhookOperation,\n receiveStripeWebhookOperation,\n bindBlobAttachmentOperation,\n detachBlobAttachmentOperation,\n initiateMultipartBlobStageOperation,\n getMultipartBlobStageOperation,\n completeMultipartBlobStageOperation,\n authorizeMultipartBlobPartUploadOperation,\n uploadMultipartBlobPartBytesOperation,\n listDocumentAttachmentsOperation,\n getDocumentAttributionOperation,\n listDocumentAttributionRangesOperation,\n createDocumentOperation,\n getDocumentPurgeProofOperation,\n linkDocumentOperation,\n purgeDocumentOperation,\n unlinkDocumentOperation,\n getContainerKekLogOperation,\n listContainerDocumentsOperation,\n listContainerParentLanesOperation,\n createContainerOperation,\n createContainerWithMetadataDocumentOperation,\n deleteContainerOperation,\n moveContainerOperation,\n reciteContainerOperation,\n rekeyContainerOperation,\n revokeContainerOperation,\n shareContainerOperation,\n getContainerWriterProjectionOperation,\n getDocumentWriterProjectionOperation,\n createOrganizationOperation,\n getOrganizationBillingOperation,\n getOrganizationBillingHistoryOperation,\n getOrganizationBillingManagementUrlOperation,\n getOrganizationNativePurchaseEligibilityOperation,\n claimNativeOrganizationSubscriptionOperation,\n startOrganizationTrialOperation,\n getStripeCheckoutOptionsOperation,\n createStripeCheckoutOperation,\n createStripeCheckoutSessionOperation,\n createStripePortalOperation,\n cancelStripeSubscriptionOperation,\n getOrganizationDataUsageOperation,\n getOrganizationReadModelOperation,\n getOrganizationPolicyHistoryOperation,\n createOrganizationGroupOperation,\n deleteOrganizationGroupOperation,\n listOrganizationGroupMembersOperation,\n updateOrganizationProfileOperation,\n updateOrganizationRosterEntryOperation,\n getPrincipalPolicyOperation,\n getProjectionPolicyHistoryOperation,\n commitOrganizationGroupPolicyOperation,\n putPrincipalPolicyOperation,\n listRootIdentitiesOperation,\n listRootOrganizationsOperation,\n getRootOrganizationDataUsageOperation,\n listRootDataUsageReportOperation,\n getRootOrganizationOperation,\n listRootOrganizationIdentitiesOperation,\n getRootIdentityOperation,\n listRootIdentityOrganizationsOperation,\n documentSyncOperation,\n];\n"]}
@@ -1,7 +1,5 @@
1
1
  /**
2
- * Protocol ceiling for one buffered multipart blob part. The API buffers a
3
- * part before uploading it, and the Workers isolate that serves uploads has
4
- * 128 MB of memory, so the ceiling leaves room for the copy the digest check
5
- * makes.
2
+ * Protocol ceiling for a multipart blob part. Bounds client hashing and native
3
+ * HTTP bridge buffers for direct uploads, and API buffers for non-signing stores.
6
4
  */
7
5
  export declare const MAX_MULTIPART_BLOB_PART_BYTES: number;
@@ -1,8 +1,6 @@
1
1
  /**
2
- * Protocol ceiling for one buffered multipart blob part. The API buffers a
3
- * part before uploading it, and the Workers isolate that serves uploads has
4
- * 128 MB of memory, so the ceiling leaves room for the copy the digest check
5
- * makes.
2
+ * Protocol ceiling for a multipart blob part. Bounds client hashing and native
3
+ * HTTP bridge buffers for direct uploads, and API buffers for non-signing stores.
6
4
  */
7
5
  export const MAX_MULTIPART_BLOB_PART_BYTES = 32 * 1024 * 1024;
8
6
  //# sourceMappingURL=blob.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blob.js","sourceRoot":"","sources":["blob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC","sourcesContent":["/**\n * Protocol ceiling for one buffered multipart blob part. The API buffers a\n * part before uploading it, and the Workers isolate that serves uploads has\n * 128 MB of memory, so the ceiling leaves room for the copy the digest check\n * makes.\n */\nexport const MAX_MULTIPART_BLOB_PART_BYTES = 32 * 1024 * 1024;\n"]}
1
+ {"version":3,"file":"blob.js","sourceRoot":"","sources":["blob.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC","sourcesContent":["/**\n * Protocol ceiling for a multipart blob part. Bounds client hashing and native\n * HTTP bridge buffers for direct uploads, and API buffers for non-signing stores.\n */\nexport const MAX_MULTIPART_BLOB_PART_BYTES = 32 * 1024 * 1024;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tearleads/client-sdk",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "description": "React-free Tearleads client runtime: local SQLite persistence, keys, sync, encrypted blobs, and domain workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -5,6 +5,10 @@ import { createRuntimePrincipalPolicyWarmer } from "../../../workflows/principal
5
5
  import { commitHydratedAttachment } from "./attachmentHydrationCommit.js";
6
6
  import { runDocumentOrphanMaintenance } from "./orphanMaintenance.js";
7
7
  import { isDocumentStoreSyncGenerationCurrent as isSyncGenerationCurrent, } from "./syncGeneration.js";
8
+ // A remote probe is evidence that bindings may have moved independently of
9
+ // content. Capture its sequence before I/O so a hint arriving during hydration
10
+ // survives for the trailing pass. Missing or changed local bytes always retry.
11
+ const checkedSignals = new WeakMap();
8
12
  export async function hydrateAttachmentBlobs(state, currentDoc, currentRecord, expectedGeneration) {
9
13
  const generationIsCurrent = () => !expectedGeneration || isSyncGenerationCurrent(state, expectedGeneration);
10
14
  if (!generationIsCurrent())
@@ -21,9 +25,16 @@ export async function hydrateAttachmentBlobs(state, currentDoc, currentRecord, e
21
25
  if (attachments.length === 0) {
22
26
  return;
23
27
  }
28
+ const signalSequence = state.remoteUpdateSignalSeq;
29
+ if (bindingsAlreadyChecked(state, currentDoc, currentRecord.documentId, attachments, signalSequence))
30
+ return;
24
31
  const expectedStorageKeys = { ...state.attachmentStorageKeyBySlotId };
32
+ let bindingsChecked = false;
25
33
  const hydratedBlobs = await hydrateDocumentAttachmentBlobs({
26
34
  apiClient: runtime.apiClient,
35
+ onBindingsChecked: () => {
36
+ bindingsChecked = true;
37
+ },
27
38
  attachments,
28
39
  documentId: currentRecord.documentId,
29
40
  execSql: runtime.infra.execSql,
@@ -52,6 +63,28 @@ export async function hydrateAttachmentBlobs(state, currentDoc, currentRecord, e
52
63
  expectedStorageKey: expectedStorageKeys[hydratedBlob.attachment.slotId] ?? null,
53
64
  });
54
65
  }
66
+ if (bindingsChecked &&
67
+ generationIsCurrent() &&
68
+ hydratedBlobs.every((blob) => state.attachmentBlobIdBySlotId[blob.attachment.slotId] ===
69
+ blob.binding.blobId)) {
70
+ checkedSignals.set(state, {
71
+ documentId: currentRecord.documentId,
72
+ document: new WeakRef(currentDoc),
73
+ sequence: signalSequence,
74
+ });
75
+ }
55
76
  void runDocumentOrphanMaintenance(state);
56
77
  }
78
+ function bindingsAlreadyChecked(state, currentDoc, documentId, attachments, signalSequence) {
79
+ const checked = checkedSignals.get(state);
80
+ const needsBindingProbe = signalSequence >
81
+ (checked?.documentId === documentId &&
82
+ checked.document.deref() === currentDoc
83
+ ? checked.sequence
84
+ : 0);
85
+ return (!needsBindingProbe &&
86
+ attachments.every((attachment) => state.attachmentStorageKeyBySlotId[attachment.slotId] &&
87
+ state.attachmentContentSha256BySlotId[attachment.slotId] ===
88
+ attachment.contentSha256));
89
+ }
57
90
  //# sourceMappingURL=attachmentHydration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachmentHydration.js","sourceRoot":"","sources":["attachmentHydration.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAE1E,OAAO,EAAE,kCAAkC,EAAE,MAAM,mDAAmD,CAAC;AACvG,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAEL,oCAAoC,IAAI,uBAAuB,GAChE,MAAM,kBAAkB,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAyB,EACzB,UAAyB,EACzB,aAAoC,EACpC,kBAAgD;IAEhD,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAC/B,CAAC,kBAAkB,IAAI,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IAC5E,IAAI,CAAC,mBAAmB,EAAE;QAAE,OAAO;IAEnC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC;IACjE,IACE,CAAC,oBAAoB;QACrB,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe;QAC7B,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM;QACrB,CAAC,aAAa,EAAE,UAAU,EAC1B,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,MAAM,mBAAmB,GAAG,EAAE,GAAG,KAAK,CAAC,4BAA4B,EAAE,CAAC;IACtE,MAAM,aAAa,GAAG,MAAM,8BAA8B,CAAC;QACzD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW;QACX,UAAU,EAAE,aAAa,CAAC,UAAU;QACpC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;QAC9B,mBAAmB,EAAE,KAAK,CAAC,wBAAwB;QACnD,uBAAuB,EAAE,KAAK,CAAC,4BAA4B;QAC3D,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QACrB,sBAAsB,EAAE,KAAK,CAAC,gCAAgC;QAC9D,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB;QAC3D,wBAAwB,EACtB,kBAAkB,EAAE,wBAAwB;YAC5C,KAAK,CAAC,wBAAwB;QAChC,eAAe,EAAE,oBAAoB,CAAC,SAAS;QAC/C,YAAY,EAAE,mBAAmB;QACjC,+BAA+B,EAC7B,kCAAkC,CAAC,OAAO,CAAC;KAC9C,CAAC,CAAC;IACH,IAAI,CAAC,mBAAmB,EAAE;QAAE,OAAO;IACnC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IAED,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,MAAM,wBAAwB,CAAC;YAC7B,KAAK;YACL,UAAU;YACV,YAAY;YACZ,mBAAmB;YACnB,kBAAkB,EAChB,mBAAmB,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI;SAC9D,CAAC,CAAC;IACL,CAAC;IACD,KAAK,4BAA4B,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["/** Hydrate only bytes matching the current document's authenticated attachment intent. */\n\nimport { getDocumentAttachments } from \"../../../data/documents/documentContent\";\nimport { hydrateDocumentAttachmentBlobs } from \"../../../workflows/blobs\";\nimport type { DocumentRecord } from \"../../../workflows/documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../workflows/principals/runtimePolicyWarmer\";\nimport { commitHydratedAttachment } from \"./attachmentHydrationCommit\";\nimport { runDocumentOrphanMaintenance } from \"./orphanMaintenance\";\nimport type { DocumentState, DocumentStoreState } from \"./state\";\nimport {\n type DocumentStoreSyncGeneration,\n isDocumentStoreSyncGenerationCurrent as isSyncGenerationCurrent,\n} from \"./syncGeneration\";\n\nexport async function hydrateAttachmentBlobs(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n currentRecord: DocumentRecord | null,\n expectedGeneration?: DocumentStoreSyncGeneration,\n) {\n const generationIsCurrent = () =>\n !expectedGeneration || isSyncGenerationCurrent(state, expectedGeneration);\n if (!generationIsCurrent()) return;\n\n const runtime = state.runtime;\n const encapsulationKeyPair = runtime.crypto.encapsulationKeyPair;\n if (\n !encapsulationKeyPair ||\n !runtime.auth.isAuthenticated ||\n !runtime.state.online ||\n !currentRecord?.documentId\n ) {\n return;\n }\n\n const attachments = getDocumentAttachments(currentDoc);\n if (attachments.length === 0) {\n return;\n }\n\n const expectedStorageKeys = { ...state.attachmentStorageKeyBySlotId };\n const hydratedBlobs = await hydrateDocumentAttachmentBlobs({\n apiClient: runtime.apiClient,\n attachments,\n documentId: currentRecord.documentId,\n execSql: runtime.infra.execSql,\n localBlobIdBySlotId: state.attachmentBlobIdBySlotId,\n localStorageKeyBySlotId: state.attachmentStorageKeyBySlotId,\n log: runtime.util.log,\n rejectedServedBindings: state.rejectedServedAttachmentBindings,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n resolveProjectionUserKey:\n expectedGeneration?.resolveProjectionUserKey ??\n state.resolveProjectionUserKey,\n targetSecretKey: encapsulationKeyPair.secretKey,\n stillCurrent: generationIsCurrent,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!generationIsCurrent()) return;\n if (!hydratedBlobs) {\n return;\n }\n\n for (const hydratedBlob of hydratedBlobs) {\n await commitHydratedAttachment({\n state,\n currentDoc,\n hydratedBlob,\n generationIsCurrent,\n expectedStorageKey:\n expectedStorageKeys[hydratedBlob.attachment.slotId] ?? null,\n });\n }\n void runDocumentOrphanMaintenance(state);\n}\n"]}
1
+ {"version":3,"file":"attachmentHydration.js","sourceRoot":"","sources":["attachmentHydration.ts"],"names":[],"mappings":"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","sourcesContent":["/** Hydrate only bytes matching the current document's authenticated attachment intent. */\n\nimport { getDocumentAttachments } from \"../../../data/documents/documentContent\";\nimport { hydrateDocumentAttachmentBlobs } from \"../../../workflows/blobs\";\nimport type { DocumentRecord } from \"../../../workflows/documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../../workflows/principals/runtimePolicyWarmer\";\nimport { commitHydratedAttachment } from \"./attachmentHydrationCommit\";\nimport { runDocumentOrphanMaintenance } from \"./orphanMaintenance\";\nimport type { DocumentState, DocumentStoreState } from \"./state\";\nimport {\n type DocumentStoreSyncGeneration,\n isDocumentStoreSyncGenerationCurrent as isSyncGenerationCurrent,\n} from \"./syncGeneration\";\n\n// A remote probe is evidence that bindings may have moved independently of\n// content. Capture its sequence before I/O so a hint arriving during hydration\n// survives for the trailing pass. Missing or changed local bytes always retry.\nconst checkedSignals = new WeakMap<\n DocumentStoreState,\n { documentId: string; document: WeakRef<DocumentState>; sequence: number }\n>();\n\nexport async function hydrateAttachmentBlobs(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n currentRecord: DocumentRecord | null,\n expectedGeneration?: DocumentStoreSyncGeneration,\n) {\n const generationIsCurrent = () =>\n !expectedGeneration || isSyncGenerationCurrent(state, expectedGeneration);\n if (!generationIsCurrent()) return;\n\n const runtime = state.runtime;\n const encapsulationKeyPair = runtime.crypto.encapsulationKeyPair;\n if (\n !encapsulationKeyPair ||\n !runtime.auth.isAuthenticated ||\n !runtime.state.online ||\n !currentRecord?.documentId\n ) {\n return;\n }\n\n const attachments = getDocumentAttachments(currentDoc);\n if (attachments.length === 0) {\n return;\n }\n\n const signalSequence = state.remoteUpdateSignalSeq;\n if (\n bindingsAlreadyChecked(\n state,\n currentDoc,\n currentRecord.documentId,\n attachments,\n signalSequence,\n )\n )\n return;\n\n const expectedStorageKeys = { ...state.attachmentStorageKeyBySlotId };\n let bindingsChecked = false;\n const hydratedBlobs = await hydrateDocumentAttachmentBlobs({\n apiClient: runtime.apiClient,\n onBindingsChecked: () => {\n bindingsChecked = true;\n },\n attachments,\n documentId: currentRecord.documentId,\n execSql: runtime.infra.execSql,\n localBlobIdBySlotId: state.attachmentBlobIdBySlotId,\n localStorageKeyBySlotId: state.attachmentStorageKeyBySlotId,\n log: runtime.util.log,\n rejectedServedBindings: state.rejectedServedAttachmentBindings,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n resolveProjectionUserKey:\n expectedGeneration?.resolveProjectionUserKey ??\n state.resolveProjectionUserKey,\n targetSecretKey: encapsulationKeyPair.secretKey,\n stillCurrent: generationIsCurrent,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n if (!generationIsCurrent()) return;\n if (!hydratedBlobs) {\n return;\n }\n\n for (const hydratedBlob of hydratedBlobs) {\n await commitHydratedAttachment({\n state,\n currentDoc,\n hydratedBlob,\n generationIsCurrent,\n expectedStorageKey:\n expectedStorageKeys[hydratedBlob.attachment.slotId] ?? null,\n });\n }\n if (\n bindingsChecked &&\n generationIsCurrent() &&\n hydratedBlobs.every(\n (blob) =>\n state.attachmentBlobIdBySlotId[blob.attachment.slotId] ===\n blob.binding.blobId,\n )\n ) {\n checkedSignals.set(state, {\n documentId: currentRecord.documentId,\n document: new WeakRef(currentDoc),\n sequence: signalSequence,\n });\n }\n void runDocumentOrphanMaintenance(state);\n}\n\nfunction bindingsAlreadyChecked(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n documentId: string,\n attachments: ReturnType<typeof getDocumentAttachments>,\n signalSequence: number,\n): boolean {\n const checked = checkedSignals.get(state);\n const needsBindingProbe =\n signalSequence >\n (checked?.documentId === documentId &&\n checked.document.deref() === currentDoc\n ? checked.sequence\n : 0);\n return (\n !needsBindingProbe &&\n attachments.every(\n (attachment) =>\n state.attachmentStorageKeyBySlotId[attachment.slotId] &&\n state.attachmentContentSha256BySlotId[attachment.slotId] ===\n attachment.contentSha256,\n )\n );\n}\n"]}
@@ -15,7 +15,7 @@ export function getActiveDocumentRemoteWork(state) {
15
15
  ? active.tail
16
16
  : null;
17
17
  }
18
- /** Never wait on another remote request inside the coordinator's serial pump. */
18
+ /** A document lane retries instead of waiting on overlapping remote work. */
19
19
  export function runDocumentRemoteWork(state, task) {
20
20
  const pending = getActiveDocumentRemoteWork(state);
21
21
  if (pending) {
@@ -1 +1 @@
1
- {"version":3,"file":"remoteWork.js","sourceRoot":"","sources":["remoteWork.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sCAAsC,EACtC,sCAAsC,EAEtC,wCAAwC,GACzC,MAAM,kBAAkB,CAAC;AAE1B,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAOlC,CAAC;AAEJ,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAC/B;IAArB,YAAqB,QAAuB;QAC1C,KAAK,CAAC,4DAA4D,CAAC,CAAC;QADjD,aAAQ,GAAR,QAAQ,CAAe;QAE1C,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,2BAA2B,CACzC,KAAyB;IAEzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,MAAM;QACX,wCAAwC,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC;QAClE,CAAC,CAAC,MAAM,CAAC,IAAI;QACb,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,qBAAqB,CACnC,KAAyB,EACzB,IAAsB;IAEtB,MAAM,OAAO,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACnD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,gFAAgF;IAChF,MAAM,UAAU,GAAG;QACjB,GAAG,sCAAsC,CAAC,KAAK,CAAC;QAChD,GAAG,sCAAsC,CAAC,KAAK,CAAC;KACjD,CAAC;IACF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE;SAC3B,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,GAAG,EAAE;QACZ,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,EAAE,CAAC;YAC5C,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC;IACL,MAAM,MAAM,GAAG;QACb,UAAU;QACV,IAAI,EAAE,IAAI,CAAC,IAAI,CACb,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB;KACF,CAAC;IACF,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { DocumentStoreState } from \"./state\";\nimport {\n captureDocumentStoreGenerationIdentity,\n captureDocumentStoreSyncLaneGeneration,\n type DocumentStoreSyncLaneGeneration,\n isDocumentStoreGenerationIdentityCurrent,\n} from \"./syncGeneration\";\n\nconst remoteWorkByState = new WeakMap<\n DocumentStoreState,\n {\n generation: DocumentStoreSyncLaneGeneration &\n ReturnType<typeof captureDocumentStoreGenerationIdentity>;\n tail: Promise<void>;\n }\n>();\n\nexport class DocumentRemoteWorkBusyError extends Error {\n constructor(readonly whenIdle: Promise<void>) {\n super(\"Document remote work is still running; retry the operation\");\n this.name = \"DocumentRemoteWorkBusyError\";\n }\n}\n\nexport function getActiveDocumentRemoteWork(\n state: DocumentStoreState,\n): Promise<void> | null {\n const active = remoteWorkByState.get(state);\n return active &&\n isDocumentStoreGenerationIdentityCurrent(state, active.generation)\n ? active.tail\n : null;\n}\n\n/** Never wait on another remote request inside the coordinator's serial pump. */\nexport function runDocumentRemoteWork<T>(\n state: DocumentStoreState,\n task: () => Promise<T>,\n): Promise<T> {\n const pending = getActiveDocumentRemoteWork(state);\n if (pending) {\n return Promise.reject(new DocumentRemoteWorkBusyError(pending));\n }\n // Database/runtime replacement abandons ownership; ordinary local edits do not.\n const generation = {\n ...captureDocumentStoreGenerationIdentity(state),\n ...captureDocumentStoreSyncLaneGeneration(state),\n };\n const work = Promise.resolve()\n .then(task)\n .finally(() => {\n if (remoteWorkByState.get(state) === active) {\n remoteWorkByState.delete(state);\n }\n });\n const active = {\n generation,\n tail: work.then(\n () => undefined,\n () => undefined,\n ),\n };\n remoteWorkByState.set(state, active);\n return work;\n}\n"]}
1
+ {"version":3,"file":"remoteWork.js","sourceRoot":"","sources":["remoteWork.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sCAAsC,EACtC,sCAAsC,EAEtC,wCAAwC,GACzC,MAAM,kBAAkB,CAAC;AAE1B,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAOlC,CAAC;AAEJ,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAC/B;IAArB,YAAqB,QAAuB;QAC1C,KAAK,CAAC,4DAA4D,CAAC,CAAC;QADjD,aAAQ,GAAR,QAAQ,CAAe;QAE1C,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,2BAA2B,CACzC,KAAyB;IAEzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,MAAM;QACX,wCAAwC,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC;QAClE,CAAC,CAAC,MAAM,CAAC,IAAI;QACb,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CACnC,KAAyB,EACzB,IAAsB;IAEtB,MAAM,OAAO,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACnD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,gFAAgF;IAChF,MAAM,UAAU,GAAG;QACjB,GAAG,sCAAsC,CAAC,KAAK,CAAC;QAChD,GAAG,sCAAsC,CAAC,KAAK,CAAC;KACjD,CAAC;IACF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE;SAC3B,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,GAAG,EAAE;QACZ,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,EAAE,CAAC;YAC5C,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC;IACL,MAAM,MAAM,GAAG;QACb,UAAU;QACV,IAAI,EAAE,IAAI,CAAC,IAAI,CACb,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB;KACF,CAAC;IACF,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { DocumentStoreState } from \"./state\";\nimport {\n captureDocumentStoreGenerationIdentity,\n captureDocumentStoreSyncLaneGeneration,\n type DocumentStoreSyncLaneGeneration,\n isDocumentStoreGenerationIdentityCurrent,\n} from \"./syncGeneration\";\n\nconst remoteWorkByState = new WeakMap<\n DocumentStoreState,\n {\n generation: DocumentStoreSyncLaneGeneration &\n ReturnType<typeof captureDocumentStoreGenerationIdentity>;\n tail: Promise<void>;\n }\n>();\n\nexport class DocumentRemoteWorkBusyError extends Error {\n constructor(readonly whenIdle: Promise<void>) {\n super(\"Document remote work is still running; retry the operation\");\n this.name = \"DocumentRemoteWorkBusyError\";\n }\n}\n\nexport function getActiveDocumentRemoteWork(\n state: DocumentStoreState,\n): Promise<void> | null {\n const active = remoteWorkByState.get(state);\n return active &&\n isDocumentStoreGenerationIdentityCurrent(state, active.generation)\n ? active.tail\n : null;\n}\n\n/** A document lane retries instead of waiting on overlapping remote work. */\nexport function runDocumentRemoteWork<T>(\n state: DocumentStoreState,\n task: () => Promise<T>,\n): Promise<T> {\n const pending = getActiveDocumentRemoteWork(state);\n if (pending) {\n return Promise.reject(new DocumentRemoteWorkBusyError(pending));\n }\n // Database/runtime replacement abandons ownership; ordinary local edits do not.\n const generation = {\n ...captureDocumentStoreGenerationIdentity(state),\n ...captureDocumentStoreSyncLaneGeneration(state),\n };\n const work = Promise.resolve()\n .then(task)\n .finally(() => {\n if (remoteWorkByState.get(state) === active) {\n remoteWorkByState.delete(state);\n }\n });\n const active = {\n generation,\n tail: work.then(\n () => undefined,\n () => undefined,\n ),\n };\n remoteWorkByState.set(state, active);\n return work;\n}\n"]}
@@ -260,6 +260,9 @@ export function registerDocumentStoreSyncLane(state, getSyncLaneGeneration) {
260
260
  return registerDocumentSyncLane({
261
261
  domainScope: state.runtime.state.domainScope,
262
262
  localId: state.localId,
263
+ priority: () => state.remoteUpdatePending || state.record?.snapshotEndVersion === ""
264
+ ? -1
265
+ : 0,
263
266
  logError: (message, error) => {
264
267
  // Read the runtime lazily: a store's runtime is replaced in place, and a
265
268
  // reference captured here would report into a torn-down host.
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["sync.ts"],"names":[],"mappings":"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","sourcesContent":["import { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport {\n type DocumentRecord,\n type DocumentSyncLane,\n isDatabaseUnavailableError,\n type PendingUpdateRecord,\n registerDocumentSyncLane,\n resolveDocumentCreateAuthor,\n} from \"../../../workflows/documents\";\nimport { requestDocumentStoreSync } from \"../registry\";\nimport { awaitInitializationForSync } from \"./initialization\";\nimport { listPendingUpdates } from \"./persistence\";\nimport { logRevalidationUnavailable as logUnavailable } from \"./remoteRevalidationTelemetry\";\nimport {\n getActiveDocumentRemoteWork,\n runDocumentRemoteWork,\n} from \"./remoteWork\";\nimport {\n type DocumentState,\n type DocumentStoreState,\n type DocumentSyncAttempt,\n type EncapsulationKeyPair,\n setDocumentSyncing,\n} from \"./state\";\nimport {\n cleanupPreRegisteredUpdateIdsOnFailure,\n discardPreRegisteredUpdateIds,\n preRegisterMaterializedDocumentSyncUpdateIds,\n} from \"./syncAcceptedUpdateIds\";\nimport { syncPendingAttachments } from \"./syncAttachments\";\nimport { syncDetachedAttachmentBindings } from \"./syncDetachedAttachments\";\nimport { finalizeDocumentSync } from \"./syncFinalize\";\nimport {\n captureDocumentStoreAttachmentSyncGeneration,\n captureDocumentStoreRemoteSyncGeneration,\n captureDocumentStoreSyncGeneration,\n type DocumentStoreSyncGeneration,\n type DocumentStoreSyncLaneGeneration,\n isDocumentStoreRemoteSyncBlocked,\n isDocumentStoreSyncGenerationCurrent,\n isDocumentStoreSyncLaneGenerationCurrent,\n} from \"./syncGeneration\";\nimport { prepareDocumentOutgoingCoverage } from \"./syncOutgoingCoverage\";\nimport { requestRemoteDocumentSync } from \"./syncRequest\";\nimport {\n ensureRemoteDocument,\n isContainerAwaitingRemoteCreate,\n shouldSkipCleanScheduledDocumentSync,\n} from \"./syncShared\";\n\nfunction canRunScheduledSync(state: DocumentStoreState): boolean {\n return (\n state.doc !== null &&\n state.snapshot.ready &&\n state.runtime.state.online &&\n state.runtime.auth.isAuthenticated &&\n state.runtime.crypto.encapsulationKeyPair !== null &&\n resolveDocumentCreateAuthor(state.runtime) !== null\n );\n}\n\nasync function requestOutgoingDocumentBatch(input: {\n readonly currentDoc: DocumentState;\n readonly encapsulationKeyPair: EncapsulationKeyPair;\n readonly generation: DocumentStoreSyncGeneration;\n readonly pendingUpdates: PendingUpdateRecord[];\n readonly record: DocumentRecord;\n readonly state: DocumentStoreState;\n}): Promise<{\n sentUpdateIds: string[];\n syncAttempt: DocumentSyncAttempt | null;\n}> {\n const { planningUpdates, queuedUpdateCount } = prepareDocumentStoreSyncQueue(\n input.pendingUpdates,\n );\n const sentUpdateIds: string[] = [];\n const syncAttempt = await cleanupPreRegisteredUpdateIdsOnFailure(\n input.state,\n sentUpdateIds,\n () =>\n requestRemoteDocumentSync({\n currentDoc: input.currentDoc,\n currentRecord: input.record,\n encapsulationKeyPair: input.encapsulationKeyPair,\n generation: input.generation,\n onOutgoingUpdatesMaterialized: (updateIds) =>\n preRegisterMaterializedDocumentSyncUpdateIds(\n input.state,\n sentUpdateIds,\n updateIds,\n ),\n pendingUpdates: planningUpdates,\n queuedUpdateCount,\n state: input.state,\n unavailableWriterLogMessage:\n \"Documents: skipped sync because the writer context is unavailable.\",\n }),\n );\n return { sentUpdateIds, syncAttempt };\n}\n\n/**\n * Keep the full durable queue visible to stale-heal/checkpoint classification.\n * The workflow planner owns the final count and byte bounds, and the exact\n * materialized batch is pre-registered immediately before each submit.\n */\nexport function prepareDocumentStoreSyncQueue(\n pendingUpdates: PendingUpdateRecord[],\n): {\n planningUpdates: PendingUpdateRecord[];\n queuedUpdateCount: number;\n} {\n return {\n planningUpdates: pendingUpdates,\n queuedUpdateCount: pendingUpdates.length,\n };\n}\n\nexport function canSyncDetachedAttachmentBindings(\n record: DocumentRecord,\n pendingUpdateCount: number,\n): boolean {\n return (\n pendingUpdateCount === 0 &&\n (record.pullContinuation ?? null) === null &&\n !record.pullContinuationRecoveryRequired\n );\n}\n\nasync function syncDocumentState(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n nextRecord: DocumentRecord,\n encapsulationKeyPair: EncapsulationKeyPair,\n generation: DocumentStoreSyncGeneration,\n): Promise<DocumentRecord> {\n // Snapshot the remote-update signal sequence before any await. The GET below\n // fetches server state as of its own snapshot; any remote event delivered\n // after this point describes an update that may not be in that response, so\n // finalizeDocumentSync must not clear the signal if this sequence has moved.\n const consumedRemoteUpdateSignalSeq = state.remoteUpdateSignalSeq;\n const wasRemoteProbe = state.remoteUpdatePending;\n let pendingUpdates = await listPendingUpdates(state);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRecord;\n }\n if (pendingUpdates.length === 0 && isDocumentStoreRemoteSyncBlocked(state)) {\n return nextRecord;\n }\n // Create the remote document even when nothing is queued to send: a note\n // created and never edited enqueues no updates, but its local row is still a\n // pending create the write queue reports — it must flush, not sit. Defer\n // while the container itself still awaits its remote create — with OR\n // without queued edits, since the create cannot succeed before its parent\n // exists and attempting it just records a spurious failure. The structural\n // lane primes this store again as soon as the container create lands.\n if (!nextRecord.documentId) {\n const containerAwaitsCreate = await isContainerAwaitingRemoteCreate(state);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRecord;\n }\n if (containerAwaitsCreate) return nextRecord;\n }\n let nextRemoteRecord = await ensureRemoteDocument(\n state,\n currentDoc,\n nextRecord,\n encapsulationKeyPair,\n generation,\n );\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRecord;\n }\n if (!nextRemoteRecord?.documentId) return nextRecord;\n\n const preparedCoverage = await prepareDocumentOutgoingCoverage({\n currentDoc,\n generation,\n pendingUpdates,\n state,\n });\n if (!preparedCoverage) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRemoteRecord;\n }\n nextRemoteRecord = preparedCoverage.record;\n pendingUpdates = preparedCoverage.pendingUpdates;\n\n if (\n shouldSkipCleanScheduledDocumentSync({\n currentRecord: nextRemoteRecord,\n pendingUpdates,\n state,\n })\n ) {\n return nextRemoteRecord;\n }\n\n // Pre-register the IDs we are about to send so the author's OWN\n // `document_update_created` echo (fanned back over redis) is classified as\n // self-authored and never re-arms a redundant sync. Registering BEFORE the\n // network await closes the race where the echo lands before\n // finalizeDocumentSync records the accepted IDs — the gap that turned every\n // fast keystroke into an extra self-triggered sync.\n const { sentUpdateIds, syncAttempt } = await requestOutgoingDocumentBatch({\n currentDoc,\n encapsulationKeyPair,\n generation,\n pendingUpdates,\n record: nextRemoteRecord,\n state,\n });\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n discardPreRegisteredUpdateIds(state, sentUpdateIds);\n requestDocumentStoreSync(state);\n return state.record ?? nextRemoteRecord;\n }\n if (!syncAttempt) {\n discardPreRegisteredUpdateIds(state, sentUpdateIds);\n logUnavailable(state, wasRemoteProbe);\n return nextRemoteRecord;\n }\n\n return cleanupPreRegisteredUpdateIdsOnFailure(state, sentUpdateIds, () =>\n finalizeDocumentSync(\n state,\n currentDoc,\n nextRemoteRecord,\n syncAttempt,\n consumedRemoteUpdateSignalSeq,\n generation,\n sentUpdateIds,\n wasRemoteProbe,\n ),\n );\n}\n\nasync function revalidateRemoteDocumentBeforeAttachments(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n nextRecord: DocumentRecord,\n encapsulationKeyPair: EncapsulationKeyPair,\n generation: DocumentStoreSyncGeneration,\n): Promise<{ canSyncAttachments: boolean; nextRecord: DocumentRecord }> {\n if (state.pendingAttachments.length === 0 || !nextRecord.documentId) {\n return { canSyncAttachments: true, nextRecord };\n }\n\n const consumedRemoteUpdateSignalSeq = state.remoteUpdateSignalSeq;\n const wasRemoteProbe = state.remoteUpdatePending;\n const syncAttempt = await requestRemoteDocumentSync({\n state,\n currentDoc,\n currentRecord: nextRecord,\n encapsulationKeyPair,\n generation,\n pendingUpdates: [],\n unavailableWriterLogMessage:\n \"Documents: skipped pre-attachment revalidation because the writer context is unavailable.\",\n });\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return { canSyncAttachments: false, nextRecord };\n }\n if (!syncAttempt) {\n logUnavailable(state, wasRemoteProbe);\n return { canSyncAttachments: false, nextRecord };\n }\n\n const refreshedRecord = await finalizeDocumentSync(\n state,\n currentDoc,\n nextRecord,\n syncAttempt,\n consumedRemoteUpdateSignalSeq,\n generation,\n [],\n wasRemoteProbe,\n );\n return {\n canSyncAttachments:\n !syncAttempt.synced.hasIncompletePull &&\n refreshedRecord.pullContinuation == null &&\n refreshedRecord.pullContinuationRecoveryRequired !== true &&\n isDocumentStoreSyncGenerationCurrent(state, generation),\n nextRecord: refreshedRecord,\n };\n}\n\nasync function runDocumentSyncPass(\n state: DocumentStoreState,\n syncLaneGeneration: DocumentStoreSyncLaneGeneration,\n) {\n const currentDoc = state.doc;\n const encapsulationKeyPair = state.runtime.crypto.encapsulationKeyPair;\n let nextRecord = state.record;\n\n if (!currentDoc || !nextRecord || !encapsulationKeyPair) {\n return;\n }\n\n const generation = captureDocumentStoreRemoteSyncGeneration(\n state,\n currentDoc,\n syncLaneGeneration,\n );\n const attachmentGeneration = captureDocumentStoreAttachmentSyncGeneration(\n state,\n currentDoc,\n syncLaneGeneration,\n );\n if (!generation || !attachmentGeneration) {\n requestDocumentStoreSync(state);\n return;\n }\n\n const revalidation = await revalidateRemoteDocumentBeforeAttachments(\n state,\n currentDoc,\n nextRecord,\n encapsulationKeyPair,\n generation,\n );\n nextRecord = revalidation.nextRecord;\n if (!revalidation.canSyncAttachments) {\n return;\n }\n\n const attachmentResult = await syncPendingAttachments(\n state,\n nextRecord,\n encapsulationKeyPair,\n attachmentGeneration,\n );\n nextRecord = attachmentResult.nextRecord;\n if (state.pendingAttachments.length > 0) {\n return;\n }\n // A settled bind and the content update carrying its digest are two server\n // writes. Push the content in this same pass rather than re-arming a later\n // one, so a device lost between them is the only remaining window: peers\n // otherwise see the old digest against the new binding.\n\n nextRecord = await syncDocumentState(\n state,\n currentDoc,\n nextRecord,\n encapsulationKeyPair,\n generation,\n );\n\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return;\n }\n\n if (!state.doc || !state.record) return;\n\n const pendingUpdates = await listPendingUpdates(state);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return;\n }\n if (!canSyncDetachedAttachmentBindings(nextRecord, pendingUpdates.length)) {\n return;\n }\n\n await syncDetachedAttachmentBindings(state, nextRecord, generation);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n }\n}\n\nasync function runScheduledSyncIteration(\n state: DocumentStoreState,\n syncLaneGeneration: DocumentStoreSyncLaneGeneration,\n) {\n if (!(await awaitInitializationForSync(state))) {\n return false;\n }\n if (!isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)) {\n return true;\n }\n\n if (!canRunScheduledSync(state)) {\n return true;\n }\n\n try {\n await runDocumentSyncPass(state, syncLaneGeneration);\n return true;\n } catch (error) {\n if (isDatabaseUnavailableError(error)) {\n return false;\n }\n\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: state.record?.documentId ?? state.localId,\n objectKind: \"document\",\n operation: \"document.sync\",\n },\n );\n\n throw error;\n }\n}\n\nasync function runScheduledSyncLoop(\n state: DocumentStoreState,\n syncLaneGeneration: DocumentStoreSyncLaneGeneration,\n) {\n const syncingGeneration = captureDocumentStoreSyncGeneration(\n state,\n state.doc,\n );\n setDocumentSyncing(state, true);\n\n try {\n await runScheduledSyncIteration(state, syncLaneGeneration);\n } finally {\n if (\n syncingGeneration &&\n isDocumentStoreSyncGenerationCurrent(state, syncingGeneration) &&\n isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)\n ) {\n setDocumentSyncing(state, false);\n }\n }\n}\n\nexport function registerDocumentStoreSyncLane(\n state: DocumentStoreState,\n getSyncLaneGeneration: () => DocumentStoreSyncLaneGeneration | null,\n): DocumentSyncLane {\n return registerDocumentSyncLane({\n domainScope: state.runtime.state.domainScope,\n localId: state.localId,\n logError: (message, error) => {\n // Read the runtime lazily: a store's runtime is replaced in place, and a\n // reference captured here would report into a torn-down host.\n const { log, logError } = state.runtime.util;\n // Return the host's result: both callbacks are declared `=> void` but may\n // be async, and the lane reporter only catches a rejection it is handed.\n return logError ? logError(message, error) : log(message);\n },\n run: () => {\n const syncLaneGeneration = getSyncLaneGeneration();\n if (!syncLaneGeneration) return Promise.resolve();\n const activeWork = getActiveDocumentRemoteWork(state);\n if (activeWork) {\n // Re-arm on settlement, not immediately: immediate re-requests would\n // spin this lane and starve other work while the HTTP request is held.\n void activeWork.then(() => {\n if (\n isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)\n ) {\n requestDocumentStoreSync(state);\n }\n });\n return Promise.resolve();\n }\n return runDocumentRemoteWork(state, () =>\n isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)\n ? runScheduledSyncLoop(state, syncLaneGeneration)\n : Promise.resolve(),\n );\n },\n });\n}\n"]}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["sync.ts"],"names":[],"mappings":"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","sourcesContent":["import { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport {\n type DocumentRecord,\n type DocumentSyncLane,\n isDatabaseUnavailableError,\n type PendingUpdateRecord,\n registerDocumentSyncLane,\n resolveDocumentCreateAuthor,\n} from \"../../../workflows/documents\";\nimport { requestDocumentStoreSync } from \"../registry\";\nimport { awaitInitializationForSync } from \"./initialization\";\nimport { listPendingUpdates } from \"./persistence\";\nimport { logRevalidationUnavailable as logUnavailable } from \"./remoteRevalidationTelemetry\";\nimport {\n getActiveDocumentRemoteWork,\n runDocumentRemoteWork,\n} from \"./remoteWork\";\nimport {\n type DocumentState,\n type DocumentStoreState,\n type DocumentSyncAttempt,\n type EncapsulationKeyPair,\n setDocumentSyncing,\n} from \"./state\";\nimport {\n cleanupPreRegisteredUpdateIdsOnFailure,\n discardPreRegisteredUpdateIds,\n preRegisterMaterializedDocumentSyncUpdateIds,\n} from \"./syncAcceptedUpdateIds\";\nimport { syncPendingAttachments } from \"./syncAttachments\";\nimport { syncDetachedAttachmentBindings } from \"./syncDetachedAttachments\";\nimport { finalizeDocumentSync } from \"./syncFinalize\";\nimport {\n captureDocumentStoreAttachmentSyncGeneration,\n captureDocumentStoreRemoteSyncGeneration,\n captureDocumentStoreSyncGeneration,\n type DocumentStoreSyncGeneration,\n type DocumentStoreSyncLaneGeneration,\n isDocumentStoreRemoteSyncBlocked,\n isDocumentStoreSyncGenerationCurrent,\n isDocumentStoreSyncLaneGenerationCurrent,\n} from \"./syncGeneration\";\nimport { prepareDocumentOutgoingCoverage } from \"./syncOutgoingCoverage\";\nimport { requestRemoteDocumentSync } from \"./syncRequest\";\nimport {\n ensureRemoteDocument,\n isContainerAwaitingRemoteCreate,\n shouldSkipCleanScheduledDocumentSync,\n} from \"./syncShared\";\n\nfunction canRunScheduledSync(state: DocumentStoreState): boolean {\n return (\n state.doc !== null &&\n state.snapshot.ready &&\n state.runtime.state.online &&\n state.runtime.auth.isAuthenticated &&\n state.runtime.crypto.encapsulationKeyPair !== null &&\n resolveDocumentCreateAuthor(state.runtime) !== null\n );\n}\n\nasync function requestOutgoingDocumentBatch(input: {\n readonly currentDoc: DocumentState;\n readonly encapsulationKeyPair: EncapsulationKeyPair;\n readonly generation: DocumentStoreSyncGeneration;\n readonly pendingUpdates: PendingUpdateRecord[];\n readonly record: DocumentRecord;\n readonly state: DocumentStoreState;\n}): Promise<{\n sentUpdateIds: string[];\n syncAttempt: DocumentSyncAttempt | null;\n}> {\n const { planningUpdates, queuedUpdateCount } = prepareDocumentStoreSyncQueue(\n input.pendingUpdates,\n );\n const sentUpdateIds: string[] = [];\n const syncAttempt = await cleanupPreRegisteredUpdateIdsOnFailure(\n input.state,\n sentUpdateIds,\n () =>\n requestRemoteDocumentSync({\n currentDoc: input.currentDoc,\n currentRecord: input.record,\n encapsulationKeyPair: input.encapsulationKeyPair,\n generation: input.generation,\n onOutgoingUpdatesMaterialized: (updateIds) =>\n preRegisterMaterializedDocumentSyncUpdateIds(\n input.state,\n sentUpdateIds,\n updateIds,\n ),\n pendingUpdates: planningUpdates,\n queuedUpdateCount,\n state: input.state,\n unavailableWriterLogMessage:\n \"Documents: skipped sync because the writer context is unavailable.\",\n }),\n );\n return { sentUpdateIds, syncAttempt };\n}\n\n/**\n * Keep the full durable queue visible to stale-heal/checkpoint classification.\n * The workflow planner owns the final count and byte bounds, and the exact\n * materialized batch is pre-registered immediately before each submit.\n */\nexport function prepareDocumentStoreSyncQueue(\n pendingUpdates: PendingUpdateRecord[],\n): {\n planningUpdates: PendingUpdateRecord[];\n queuedUpdateCount: number;\n} {\n return {\n planningUpdates: pendingUpdates,\n queuedUpdateCount: pendingUpdates.length,\n };\n}\n\nexport function canSyncDetachedAttachmentBindings(\n record: DocumentRecord,\n pendingUpdateCount: number,\n): boolean {\n return (\n pendingUpdateCount === 0 &&\n (record.pullContinuation ?? null) === null &&\n !record.pullContinuationRecoveryRequired\n );\n}\n\nasync function syncDocumentState(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n nextRecord: DocumentRecord,\n encapsulationKeyPair: EncapsulationKeyPair,\n generation: DocumentStoreSyncGeneration,\n): Promise<DocumentRecord> {\n // Snapshot the remote-update signal sequence before any await. The GET below\n // fetches server state as of its own snapshot; any remote event delivered\n // after this point describes an update that may not be in that response, so\n // finalizeDocumentSync must not clear the signal if this sequence has moved.\n const consumedRemoteUpdateSignalSeq = state.remoteUpdateSignalSeq;\n const wasRemoteProbe = state.remoteUpdatePending;\n let pendingUpdates = await listPendingUpdates(state);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRecord;\n }\n if (pendingUpdates.length === 0 && isDocumentStoreRemoteSyncBlocked(state)) {\n return nextRecord;\n }\n // Create the remote document even when nothing is queued to send: a note\n // created and never edited enqueues no updates, but its local row is still a\n // pending create the write queue reports — it must flush, not sit. Defer\n // while the container itself still awaits its remote create — with OR\n // without queued edits, since the create cannot succeed before its parent\n // exists and attempting it just records a spurious failure. The structural\n // lane primes this store again as soon as the container create lands.\n if (!nextRecord.documentId) {\n const containerAwaitsCreate = await isContainerAwaitingRemoteCreate(state);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRecord;\n }\n if (containerAwaitsCreate) return nextRecord;\n }\n let nextRemoteRecord = await ensureRemoteDocument(\n state,\n currentDoc,\n nextRecord,\n encapsulationKeyPair,\n generation,\n );\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRecord;\n }\n if (!nextRemoteRecord?.documentId) return nextRecord;\n\n const preparedCoverage = await prepareDocumentOutgoingCoverage({\n currentDoc,\n generation,\n pendingUpdates,\n state,\n });\n if (!preparedCoverage) {\n requestDocumentStoreSync(state);\n return state.record ?? nextRemoteRecord;\n }\n nextRemoteRecord = preparedCoverage.record;\n pendingUpdates = preparedCoverage.pendingUpdates;\n\n if (\n shouldSkipCleanScheduledDocumentSync({\n currentRecord: nextRemoteRecord,\n pendingUpdates,\n state,\n })\n ) {\n return nextRemoteRecord;\n }\n\n // Pre-register the IDs we are about to send so the author's OWN\n // `document_update_created` echo (fanned back over redis) is classified as\n // self-authored and never re-arms a redundant sync. Registering BEFORE the\n // network await closes the race where the echo lands before\n // finalizeDocumentSync records the accepted IDs — the gap that turned every\n // fast keystroke into an extra self-triggered sync.\n const { sentUpdateIds, syncAttempt } = await requestOutgoingDocumentBatch({\n currentDoc,\n encapsulationKeyPair,\n generation,\n pendingUpdates,\n record: nextRemoteRecord,\n state,\n });\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n discardPreRegisteredUpdateIds(state, sentUpdateIds);\n requestDocumentStoreSync(state);\n return state.record ?? nextRemoteRecord;\n }\n if (!syncAttempt) {\n discardPreRegisteredUpdateIds(state, sentUpdateIds);\n logUnavailable(state, wasRemoteProbe);\n return nextRemoteRecord;\n }\n\n return cleanupPreRegisteredUpdateIdsOnFailure(state, sentUpdateIds, () =>\n finalizeDocumentSync(\n state,\n currentDoc,\n nextRemoteRecord,\n syncAttempt,\n consumedRemoteUpdateSignalSeq,\n generation,\n sentUpdateIds,\n wasRemoteProbe,\n ),\n );\n}\n\nasync function revalidateRemoteDocumentBeforeAttachments(\n state: DocumentStoreState,\n currentDoc: DocumentState,\n nextRecord: DocumentRecord,\n encapsulationKeyPair: EncapsulationKeyPair,\n generation: DocumentStoreSyncGeneration,\n): Promise<{ canSyncAttachments: boolean; nextRecord: DocumentRecord }> {\n if (state.pendingAttachments.length === 0 || !nextRecord.documentId) {\n return { canSyncAttachments: true, nextRecord };\n }\n\n const consumedRemoteUpdateSignalSeq = state.remoteUpdateSignalSeq;\n const wasRemoteProbe = state.remoteUpdatePending;\n const syncAttempt = await requestRemoteDocumentSync({\n state,\n currentDoc,\n currentRecord: nextRecord,\n encapsulationKeyPair,\n generation,\n pendingUpdates: [],\n unavailableWriterLogMessage:\n \"Documents: skipped pre-attachment revalidation because the writer context is unavailable.\",\n });\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return { canSyncAttachments: false, nextRecord };\n }\n if (!syncAttempt) {\n logUnavailable(state, wasRemoteProbe);\n return { canSyncAttachments: false, nextRecord };\n }\n\n const refreshedRecord = await finalizeDocumentSync(\n state,\n currentDoc,\n nextRecord,\n syncAttempt,\n consumedRemoteUpdateSignalSeq,\n generation,\n [],\n wasRemoteProbe,\n );\n return {\n canSyncAttachments:\n !syncAttempt.synced.hasIncompletePull &&\n refreshedRecord.pullContinuation == null &&\n refreshedRecord.pullContinuationRecoveryRequired !== true &&\n isDocumentStoreSyncGenerationCurrent(state, generation),\n nextRecord: refreshedRecord,\n };\n}\n\nasync function runDocumentSyncPass(\n state: DocumentStoreState,\n syncLaneGeneration: DocumentStoreSyncLaneGeneration,\n) {\n const currentDoc = state.doc;\n const encapsulationKeyPair = state.runtime.crypto.encapsulationKeyPair;\n let nextRecord = state.record;\n\n if (!currentDoc || !nextRecord || !encapsulationKeyPair) {\n return;\n }\n\n const generation = captureDocumentStoreRemoteSyncGeneration(\n state,\n currentDoc,\n syncLaneGeneration,\n );\n const attachmentGeneration = captureDocumentStoreAttachmentSyncGeneration(\n state,\n currentDoc,\n syncLaneGeneration,\n );\n if (!generation || !attachmentGeneration) {\n requestDocumentStoreSync(state);\n return;\n }\n\n const revalidation = await revalidateRemoteDocumentBeforeAttachments(\n state,\n currentDoc,\n nextRecord,\n encapsulationKeyPair,\n generation,\n );\n nextRecord = revalidation.nextRecord;\n if (!revalidation.canSyncAttachments) {\n return;\n }\n\n const attachmentResult = await syncPendingAttachments(\n state,\n nextRecord,\n encapsulationKeyPair,\n attachmentGeneration,\n );\n nextRecord = attachmentResult.nextRecord;\n if (state.pendingAttachments.length > 0) {\n return;\n }\n // A settled bind and the content update carrying its digest are two server\n // writes. Push the content in this same pass rather than re-arming a later\n // one, so a device lost between them is the only remaining window: peers\n // otherwise see the old digest against the new binding.\n\n nextRecord = await syncDocumentState(\n state,\n currentDoc,\n nextRecord,\n encapsulationKeyPair,\n generation,\n );\n\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return;\n }\n\n if (!state.doc || !state.record) return;\n\n const pendingUpdates = await listPendingUpdates(state);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n return;\n }\n if (!canSyncDetachedAttachmentBindings(nextRecord, pendingUpdates.length)) {\n return;\n }\n\n await syncDetachedAttachmentBindings(state, nextRecord, generation);\n if (!isDocumentStoreSyncGenerationCurrent(state, generation)) {\n requestDocumentStoreSync(state);\n }\n}\n\nasync function runScheduledSyncIteration(\n state: DocumentStoreState,\n syncLaneGeneration: DocumentStoreSyncLaneGeneration,\n) {\n if (!(await awaitInitializationForSync(state))) {\n return false;\n }\n if (!isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)) {\n return true;\n }\n\n if (!canRunScheduledSync(state)) {\n return true;\n }\n\n try {\n await runDocumentSyncPass(state, syncLaneGeneration);\n return true;\n } catch (error) {\n if (isDatabaseUnavailableError(error)) {\n return false;\n }\n\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: state.record?.documentId ?? state.localId,\n objectKind: \"document\",\n operation: \"document.sync\",\n },\n );\n\n throw error;\n }\n}\n\nasync function runScheduledSyncLoop(\n state: DocumentStoreState,\n syncLaneGeneration: DocumentStoreSyncLaneGeneration,\n) {\n const syncingGeneration = captureDocumentStoreSyncGeneration(\n state,\n state.doc,\n );\n setDocumentSyncing(state, true);\n\n try {\n await runScheduledSyncIteration(state, syncLaneGeneration);\n } finally {\n if (\n syncingGeneration &&\n isDocumentStoreSyncGenerationCurrent(state, syncingGeneration) &&\n isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)\n ) {\n setDocumentSyncing(state, false);\n }\n }\n}\n\nexport function registerDocumentStoreSyncLane(\n state: DocumentStoreState,\n getSyncLaneGeneration: () => DocumentStoreSyncLaneGeneration | null,\n): DocumentSyncLane {\n return registerDocumentSyncLane({\n domainScope: state.runtime.state.domainScope,\n localId: state.localId,\n priority: () =>\n state.remoteUpdatePending || state.record?.snapshotEndVersion === \"\"\n ? -1\n : 0,\n logError: (message, error) => {\n // Read the runtime lazily: a store's runtime is replaced in place, and a\n // reference captured here would report into a torn-down host.\n const { log, logError } = state.runtime.util;\n // Return the host's result: both callbacks are declared `=> void` but may\n // be async, and the lane reporter only catches a rejection it is handed.\n return logError ? logError(message, error) : log(message);\n },\n run: () => {\n const syncLaneGeneration = getSyncLaneGeneration();\n if (!syncLaneGeneration) return Promise.resolve();\n const activeWork = getActiveDocumentRemoteWork(state);\n if (activeWork) {\n // Re-arm on settlement, not immediately: immediate re-requests would\n // spin this lane and starve other work while the HTTP request is held.\n void activeWork.then(() => {\n if (\n isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)\n ) {\n requestDocumentStoreSync(state);\n }\n });\n return Promise.resolve();\n }\n return runDocumentRemoteWork(state, () =>\n isDocumentStoreSyncLaneGenerationCurrent(state, syncLaneGeneration)\n ? runScheduledSyncLoop(state, syncLaneGeneration)\n : Promise.resolve(),\n );\n },\n });\n}\n"]}
@@ -1,4 +1,7 @@
1
1
  import { isSystemContainerNode } from "../../stores/container-contents/index.js";
2
+ function shouldForceDocument(force, documentIds, documentId) {
3
+ return force && (!documentIds || documentIds.has(documentId));
4
+ }
2
5
  /**
3
6
  * Routes reconciled summaries into the appropriate content-sync policy.
4
7
  *
@@ -12,12 +15,13 @@ export function createReconciledDocumentContentPuller(host) {
12
15
  // Keeping the version in the key would grow this cache for every historical
13
16
  // updatedAt value over the reconciler's lifetime.
14
17
  const pulledSystemDocumentVersions = new Map();
15
- return (containerId, documents, force) => {
18
+ return (containerId, documents, force, documentIds) => {
16
19
  const systemContainer = isSystemContainerNode(host.getContainer(containerId) ?? { systemSlot: null });
17
20
  for (const document of documents) {
18
21
  if (!document.documentId) {
19
22
  continue;
20
23
  }
24
+ const forceDocument = shouldForceDocument(force, documentIds, document.documentId);
21
25
  if (systemContainer) {
22
26
  // Container scope is significant: the same document can be linked into
23
27
  // multiple system containers whose keys establish different decryption
@@ -31,7 +35,7 @@ export function createReconciledDocumentContentPuller(host) {
31
35
  });
32
36
  pulledSystemDocumentVersions.set(documentKey, document.updatedAt);
33
37
  }
34
- else if (force) {
38
+ else if (forceDocument) {
35
39
  // The first eager pull registers a document store before scheduling
36
40
  // its async sync. If that sync failed, a later explicit Refresh must
37
41
  // be able to retry the same server version without defeating normal
@@ -40,7 +44,7 @@ export function createReconciledDocumentContentPuller(host) {
40
44
  }
41
45
  continue;
42
46
  }
43
- if (force) {
47
+ if (forceDocument) {
44
48
  host.requestRegisteredDocumentRemoteSync(document.id, document.documentId);
45
49
  }
46
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"documentContentPull.js","sourceRoot":"","sources":["documentContentPull.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAgBxE;;;;;;;GAOG;AACH,MAAM,UAAU,qCAAqC,CACnD,IAAuC;IAEvC,4EAA4E;IAC5E,4EAA4E;IAC5E,kDAAkD;IAClD,MAAM,4BAA4B,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE/D,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;QACvC,MAAM,eAAe,GAAG,qBAAqB,CAC3C,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CACvD,CAAC;QAEF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBACzB,SAAS;YACX,CAAC;YAED,IAAI,eAAe,EAAE,CAAC;gBACpB,uEAAuE;gBACvE,uEAAuE;gBACvE,oCAAoC;gBACpC,MAAM,WAAW,GAAG,GAAG,WAAW,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC5D,IACE,4BAA4B,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,SAAS,EACpE,CAAC;oBACD,IAAI,CAAC,mBAAmB,CAAC;wBACvB,WAAW;wBACX,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,QAAQ,CAAC,EAAE;qBACrB,CAAC,CAAC;oBACH,4BAA4B,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;gBACpE,CAAC;qBAAM,IAAI,KAAK,EAAE,CAAC;oBACjB,oEAAoE;oBACpE,qEAAqE;oBACrE,oEAAoE;oBACpE,qBAAqB;oBACrB,IAAI,CAAC,mCAAmC,CACtC,QAAQ,CAAC,EAAE,EACX,QAAQ,CAAC,UAAU,CACpB,CAAC;gBACJ,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,mCAAmC,CACtC,QAAQ,CAAC,EAAE,EACX,QAAQ,CAAC,UAAU,CACpB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ContainerNode } from \"../../stores/container-contents\";\nimport { isSystemContainerNode } from \"../../stores/container-contents\";\nimport type { ReconciliationHost } from \"./serviceTypes\";\n\ninterface ReconciledDocumentContentPullHost {\n readonly getContainer: (containerId: string) => ContainerNode | null;\n readonly pullDocumentContent: (input: {\n readonly containerId: string;\n readonly documentId: string;\n readonly localId: string;\n }) => void;\n readonly requestRegisteredDocumentRemoteSync: (\n localId: string,\n documentId: string,\n ) => void;\n}\n\n/**\n * Routes reconciled summaries into the appropriate content-sync policy.\n *\n * System-container contents cannot rely on a mini-app opening them on this\n * device, especially during identity recovery. Pull each remote version once.\n * Ordinary documents stay lazy unless an explicit refresh asks an already-open\n * store to revalidate.\n */\nexport function createReconciledDocumentContentPuller(\n host: ReconciledDocumentContentPullHost,\n): ReconciliationHost[\"requestDocumentContentPull\"] {\n // Retain only the last observed version for each system-container document.\n // Keeping the version in the key would grow this cache for every historical\n // updatedAt value over the reconciler's lifetime.\n const pulledSystemDocumentVersions = new Map<string, string>();\n\n return (containerId, documents, force) => {\n const systemContainer = isSystemContainerNode(\n host.getContainer(containerId) ?? { systemSlot: null },\n );\n\n for (const document of documents) {\n if (!document.documentId) {\n continue;\n }\n\n if (systemContainer) {\n // Container scope is significant: the same document can be linked into\n // multiple system containers whose keys establish different decryption\n // contexts for the transient store.\n const documentKey = `${containerId}:${document.documentId}`;\n if (\n pulledSystemDocumentVersions.get(documentKey) !== document.updatedAt\n ) {\n host.pullDocumentContent({\n containerId,\n documentId: document.documentId,\n localId: document.id,\n });\n pulledSystemDocumentVersions.set(documentKey, document.updatedAt);\n } else if (force) {\n // The first eager pull registers a document store before scheduling\n // its async sync. If that sync failed, a later explicit Refresh must\n // be able to retry the same server version without defeating normal\n // background dedupe.\n host.requestRegisteredDocumentRemoteSync(\n document.id,\n document.documentId,\n );\n }\n continue;\n }\n\n if (force) {\n host.requestRegisteredDocumentRemoteSync(\n document.id,\n document.documentId,\n );\n }\n }\n };\n}\n"]}
1
+ {"version":3,"file":"documentContentPull.js","sourceRoot":"","sources":["documentContentPull.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAgBxE,SAAS,mBAAmB,CAC1B,KAAc,EACd,WAA4C,EAC5C,UAAkB;IAElB,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qCAAqC,CACnD,IAAuC;IAEvC,4EAA4E;IAC5E,4EAA4E;IAC5E,kDAAkD;IAClD,MAAM,4BAA4B,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE/D,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;QACpD,MAAM,eAAe,GAAG,qBAAqB,CAC3C,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CACvD,CAAC;QAEF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBACzB,SAAS;YACX,CAAC;YAED,MAAM,aAAa,GAAG,mBAAmB,CACvC,KAAK,EACL,WAAW,EACX,QAAQ,CAAC,UAAU,CACpB,CAAC;YAEF,IAAI,eAAe,EAAE,CAAC;gBACpB,uEAAuE;gBACvE,uEAAuE;gBACvE,oCAAoC;gBACpC,MAAM,WAAW,GAAG,GAAG,WAAW,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC5D,IACE,4BAA4B,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,SAAS,EACpE,CAAC;oBACD,IAAI,CAAC,mBAAmB,CAAC;wBACvB,WAAW;wBACX,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,QAAQ,CAAC,EAAE;qBACrB,CAAC,CAAC;oBACH,4BAA4B,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;gBACpE,CAAC;qBAAM,IAAI,aAAa,EAAE,CAAC;oBACzB,oEAAoE;oBACpE,qEAAqE;oBACrE,oEAAoE;oBACpE,qBAAqB;oBACrB,IAAI,CAAC,mCAAmC,CACtC,QAAQ,CAAC,EAAE,EACX,QAAQ,CAAC,UAAU,CACpB,CAAC;gBACJ,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,aAAa,EAAE,CAAC;gBAClB,IAAI,CAAC,mCAAmC,CACtC,QAAQ,CAAC,EAAE,EACX,QAAQ,CAAC,UAAU,CACpB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ContainerNode } from \"../../stores/container-contents\";\nimport { isSystemContainerNode } from \"../../stores/container-contents\";\nimport type { ReconciliationHost } from \"./serviceTypes\";\n\ninterface ReconciledDocumentContentPullHost {\n readonly getContainer: (containerId: string) => ContainerNode | null;\n readonly pullDocumentContent: (input: {\n readonly containerId: string;\n readonly documentId: string;\n readonly localId: string;\n }) => void;\n readonly requestRegisteredDocumentRemoteSync: (\n localId: string,\n documentId: string,\n ) => void;\n}\n\nfunction shouldForceDocument(\n force: boolean,\n documentIds: ReadonlySet<string> | undefined,\n documentId: string,\n): boolean {\n return force && (!documentIds || documentIds.has(documentId));\n}\n\n/**\n * Routes reconciled summaries into the appropriate content-sync policy.\n *\n * System-container contents cannot rely on a mini-app opening them on this\n * device, especially during identity recovery. Pull each remote version once.\n * Ordinary documents stay lazy unless an explicit refresh asks an already-open\n * store to revalidate.\n */\nexport function createReconciledDocumentContentPuller(\n host: ReconciledDocumentContentPullHost,\n): ReconciliationHost[\"requestDocumentContentPull\"] {\n // Retain only the last observed version for each system-container document.\n // Keeping the version in the key would grow this cache for every historical\n // updatedAt value over the reconciler's lifetime.\n const pulledSystemDocumentVersions = new Map<string, string>();\n\n return (containerId, documents, force, documentIds) => {\n const systemContainer = isSystemContainerNode(\n host.getContainer(containerId) ?? { systemSlot: null },\n );\n\n for (const document of documents) {\n if (!document.documentId) {\n continue;\n }\n\n const forceDocument = shouldForceDocument(\n force,\n documentIds,\n document.documentId,\n );\n\n if (systemContainer) {\n // Container scope is significant: the same document can be linked into\n // multiple system containers whose keys establish different decryption\n // contexts for the transient store.\n const documentKey = `${containerId}:${document.documentId}`;\n if (\n pulledSystemDocumentVersions.get(documentKey) !== document.updatedAt\n ) {\n host.pullDocumentContent({\n containerId,\n documentId: document.documentId,\n localId: document.id,\n });\n pulledSystemDocumentVersions.set(documentKey, document.updatedAt);\n } else if (forceDocument) {\n // The first eager pull registers a document store before scheduling\n // its async sync. If that sync failed, a later explicit Refresh must\n // be able to retry the same server version without defeating normal\n // background dedupe.\n host.requestRegisteredDocumentRemoteSync(\n document.id,\n document.documentId,\n );\n }\n continue;\n }\n\n if (forceDocument) {\n host.requestRegisteredDocumentRemoteSync(\n document.id,\n document.documentId,\n );\n }\n }\n };\n}\n"]}
@@ -1,4 +1,13 @@
1
- export function markContainerForced(state, containerId) {
1
+ export function markContainerForced(state, containerId, documentId) {
2
+ const previous = state.forcedDocumentIds.get(containerId);
3
+ if (documentId &&
4
+ (!state.forcedContainerGenerations.has(containerId) || previous)) {
5
+ state.forcedDocumentIds.set(containerId, new Set([...(previous ?? []), documentId]));
6
+ }
7
+ else {
8
+ // A full revalidation dominates any pending targeted hints.
9
+ state.forcedDocumentIds.delete(containerId);
10
+ }
2
11
  state.nextForceGeneration += 1;
3
12
  state.automaticRetryGenerations.delete(containerId);
4
13
  state.forcedContainerGenerations.set(containerId, state.nextForceGeneration);
@@ -6,13 +15,16 @@ export function markContainerForced(state, containerId) {
6
15
  export function acknowledgeContainerForce(state, containerId, generation) {
7
16
  if (state.forcedContainerGenerations.get(containerId) === generation) {
8
17
  state.forcedContainerGenerations.delete(containerId);
18
+ state.forcedDocumentIds.delete(containerId);
9
19
  state.automaticRetryGenerations.delete(containerId);
10
20
  }
11
21
  }
12
22
  export function activateContainer(state, containerId, enqueue) {
13
23
  state.activeContainerId = containerId;
14
24
  if (containerId) {
15
- enqueue(containerId, state.forcedContainerGenerations.has(containerId));
25
+ // Navigation preserves pending targets and their bounded retry allowance.
26
+ // A new hint or explicit refresh, rather than navigation, rearms that budget.
27
+ enqueue(containerId);
16
28
  }
17
29
  }
18
30
  export function enqueueKnownContainersForIdleBackfill(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"idleBackfill.js","sourceRoot":"","sources":["idleBackfill.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,mBAAmB,CACjC,KAAwB,EACxB,WAAmB;IAEnB,KAAK,CAAC,mBAAmB,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACpD,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAAwB,EACxB,WAAmB,EACnB,UAA8B;IAE9B,IAAI,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,UAAU,EAAE,CAAC;QACrE,KAAK,CAAC,0BAA0B,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrD,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAwB,EACxB,WAA0B,EAC1B,OAAsD;IAEtD,KAAK,CAAC,iBAAiB,GAAG,WAAW,CAAC;IACtC,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,KAIrD;IACC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC7C,MAAM,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;IACvD,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAClD,MAAM,oBAAoB,GACxB,iBAAiB,KAAK,IAAI;QAC1B,CAAC,iBAAiB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC9C,IAAI,CAAC,6BAA6B,CAAC,iBAAiB,CAAC;QACnD,CAAC,CAAC,CAAC,GAAG,iBAAiB,EAAE,iBAAiB,CAAC;QAC3C,CAAC,CAAC,iBAAiB,CAAC;IACxB,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAC5B,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC,CAC5E,CAAC;IACF,KAAK,MAAM,WAAW,IAAI,oBAAoB,EAAE,CAAC;QAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAClE,SAAS;QACX,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,aAAa,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import type { InitialDocumentProbe } from \"./initialDocumentProbe\";\nimport type { ReconcileQueue } from \"./queue\";\nimport type { ReconciliationHost } from \"./serviceTypes\";\n\nexport interface IdleBackfillState {\n activeContainerId: string | null;\n automaticRetryGenerations: Map<string, number>;\n discoveredContainerIds: Set<string>;\n forcedContainerGenerations: Map<string, number>;\n initialDocumentProbe: InitialDocumentProbe;\n nextForceGeneration: number;\n queue: ReconcileQueue;\n}\n\nexport function markContainerForced(\n state: IdleBackfillState,\n containerId: string,\n): void {\n state.nextForceGeneration += 1;\n state.automaticRetryGenerations.delete(containerId);\n state.forcedContainerGenerations.set(containerId, state.nextForceGeneration);\n}\n\nexport function acknowledgeContainerForce(\n state: IdleBackfillState,\n containerId: string,\n generation: number | undefined,\n): void {\n if (state.forcedContainerGenerations.get(containerId) === generation) {\n state.forcedContainerGenerations.delete(containerId);\n state.automaticRetryGenerations.delete(containerId);\n }\n}\n\nexport function activateContainer(\n state: IdleBackfillState,\n containerId: string | null,\n enqueue: (containerId: string, force: boolean) => void,\n): void {\n state.activeContainerId = containerId;\n if (containerId) {\n enqueue(containerId, state.forcedContainerGenerations.has(containerId));\n }\n}\n\nexport function enqueueKnownContainersForIdleBackfill(input: {\n host: ReconciliationHost;\n scheduleDrain: () => void;\n state: IdleBackfillState;\n}): void {\n const { host, scheduleDrain, state } = input;\n const knownContainerIds = host.listKnownContainerIds();\n const activeContainerId = state.activeContainerId;\n const backfillContainerIds =\n activeContainerId !== null &&\n !knownContainerIds.includes(activeContainerId) &&\n host.canDiscoverContainerDocuments(activeContainerId)\n ? [...knownContainerIds, activeContainerId]\n : knownContainerIds;\n state.initialDocumentProbe.arm(\n backfillContainerIds.filter((id) => host.canDiscoverContainerDocuments(id)),\n );\n for (const containerId of backfillContainerIds) {\n const shouldForce = state.forcedContainerGenerations.has(containerId);\n if (!shouldForce && state.discoveredContainerIds.has(containerId)) {\n continue;\n }\n state.queue.enqueue(containerId, \"idle\");\n }\n scheduleDrain();\n}\n"]}
1
+ {"version":3,"file":"idleBackfill.js","sourceRoot":"","sources":["idleBackfill.ts"],"names":[],"mappings":"AAeA,MAAM,UAAU,mBAAmB,CACjC,KAAwB,EACxB,WAAmB,EACnB,UAAmB;IAEnB,MAAM,QAAQ,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1D,IACE,UAAU;QACV,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,EAChE,CAAC;QACD,KAAK,CAAC,iBAAiB,CAAC,GAAG,CACzB,WAAW,EACX,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAC3C,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,4DAA4D;QAC5D,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IACD,KAAK,CAAC,mBAAmB,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACpD,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAAwB,EACxB,WAAmB,EACnB,UAA8B;IAE9B,IAAI,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,UAAU,EAAE,CAAC;QACrE,KAAK,CAAC,0BAA0B,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrD,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAwB,EACxB,WAA0B,EAC1B,OAAsC;IAEtC,KAAK,CAAC,iBAAiB,GAAG,WAAW,CAAC;IACtC,IAAI,WAAW,EAAE,CAAC;QAChB,0EAA0E;QAC1E,8EAA8E;QAC9E,OAAO,CAAC,WAAW,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,KAIrD;IACC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC7C,MAAM,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;IACvD,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAClD,MAAM,oBAAoB,GACxB,iBAAiB,KAAK,IAAI;QAC1B,CAAC,iBAAiB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC9C,IAAI,CAAC,6BAA6B,CAAC,iBAAiB,CAAC;QACnD,CAAC,CAAC,CAAC,GAAG,iBAAiB,EAAE,iBAAiB,CAAC;QAC3C,CAAC,CAAC,iBAAiB,CAAC;IACxB,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAC5B,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC,CAC5E,CAAC;IACF,KAAK,MAAM,WAAW,IAAI,oBAAoB,EAAE,CAAC;QAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAClE,SAAS;QACX,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,aAAa,EAAE,CAAC;AAClB,CAAC","sourcesContent":["import type { InitialDocumentProbe } from \"./initialDocumentProbe\";\nimport type { ReconcileQueue } from \"./queue\";\nimport type { ReconciliationHost } from \"./serviceTypes\";\n\nexport interface IdleBackfillState {\n activeContainerId: string | null;\n automaticRetryGenerations: Map<string, number>;\n discoveredContainerIds: Set<string>;\n forcedContainerGenerations: Map<string, number>;\n forcedDocumentIds: Map<string, ReadonlySet<string>>;\n initialDocumentProbe: InitialDocumentProbe;\n nextForceGeneration: number;\n queue: ReconcileQueue;\n}\n\nexport function markContainerForced(\n state: IdleBackfillState,\n containerId: string,\n documentId?: string,\n): void {\n const previous = state.forcedDocumentIds.get(containerId);\n if (\n documentId &&\n (!state.forcedContainerGenerations.has(containerId) || previous)\n ) {\n state.forcedDocumentIds.set(\n containerId,\n new Set([...(previous ?? []), documentId]),\n );\n } else {\n // A full revalidation dominates any pending targeted hints.\n state.forcedDocumentIds.delete(containerId);\n }\n state.nextForceGeneration += 1;\n state.automaticRetryGenerations.delete(containerId);\n state.forcedContainerGenerations.set(containerId, state.nextForceGeneration);\n}\n\nexport function acknowledgeContainerForce(\n state: IdleBackfillState,\n containerId: string,\n generation: number | undefined,\n): void {\n if (state.forcedContainerGenerations.get(containerId) === generation) {\n state.forcedContainerGenerations.delete(containerId);\n state.forcedDocumentIds.delete(containerId);\n state.automaticRetryGenerations.delete(containerId);\n }\n}\n\nexport function activateContainer(\n state: IdleBackfillState,\n containerId: string | null,\n enqueue: (containerId: string) => void,\n): void {\n state.activeContainerId = containerId;\n if (containerId) {\n // Navigation preserves pending targets and their bounded retry allowance.\n // A new hint or explicit refresh, rather than navigation, rearms that budget.\n enqueue(containerId);\n }\n}\n\nexport function enqueueKnownContainersForIdleBackfill(input: {\n host: ReconciliationHost;\n scheduleDrain: () => void;\n state: IdleBackfillState;\n}): void {\n const { host, scheduleDrain, state } = input;\n const knownContainerIds = host.listKnownContainerIds();\n const activeContainerId = state.activeContainerId;\n const backfillContainerIds =\n activeContainerId !== null &&\n !knownContainerIds.includes(activeContainerId) &&\n host.canDiscoverContainerDocuments(activeContainerId)\n ? [...knownContainerIds, activeContainerId]\n : knownContainerIds;\n state.initialDocumentProbe.arm(\n backfillContainerIds.filter((id) => host.canDiscoverContainerDocuments(id)),\n );\n for (const containerId of backfillContainerIds) {\n const shouldForce = state.forcedContainerGenerations.has(containerId);\n if (!shouldForce && state.discoveredContainerIds.has(containerId)) {\n continue;\n }\n state.queue.enqueue(containerId, \"idle\");\n }\n scheduleDrain();\n}\n"]}
@@ -36,10 +36,13 @@ export function isCurrentReconciliationLifecycle(state, generation) {
36
36
  // Reconcile a container whose discovered mark is already set, rolling the mark
37
37
  // back when the container is skipped or fails so a transient error (or a
38
38
  // container that later becomes eligible) can be retried.
39
- export async function reconcileMarkedContainer(host, state, containerId, forceDocumentContentPull) {
39
+ export async function reconcileMarkedContainer(host, state, containerId, forceDocumentContentPull, fullRevalidation = false) {
40
40
  try {
41
41
  const reconciled = await reconcileOneContainer(host, containerId, {
42
42
  forceDocumentContentPull,
43
+ documentIds: fullRevalidation
44
+ ? undefined
45
+ : state.forcedDocumentIds.get(containerId),
43
46
  onFullListing: state.initialDocumentProbe.captureListing(containerId),
44
47
  onPendingDiscovery: (delayMs) => schedulePendingDiscovery(state, containerId, delayMs),
45
48
  });
@@ -60,7 +63,7 @@ async function sweepContainer(input) {
60
63
  }
61
64
  const forceGeneration = state.forcedContainerGenerations.get(containerId);
62
65
  try {
63
- const reconciled = await reconcileMarkedContainer(host, state, containerId, input.forceAllDocumentContentPulls || forceGeneration !== undefined);
66
+ const reconciled = await reconcileMarkedContainer(host, state, containerId, input.forceAllDocumentContentPulls || forceGeneration !== undefined, input.forceAllDocumentContentPulls);
64
67
  if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {
65
68
  return { status: "stale" };
66
69
  }