@tearleads/client-sdk 0.1.115 → 0.1.116

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 (43) hide show
  1. package/client/containerContents/documentDiscovery.js +5 -3
  2. package/client/containerContents/documentDiscovery.js.map +1 -1
  3. package/internal/api-client/ApiClient.d.ts +118 -0
  4. package/internal/api-client/ApiClient.js +4 -0
  5. package/internal/api-client/ApiClient.js.map +1 -1
  6. package/internal/api-client/index.d.ts +1 -1
  7. package/internal/api-client/index.js.map +1 -1
  8. package/internal/api-client/principalPolicyPages.d.ts +15 -1
  9. package/internal/api-client/principalPolicyPages.js +48 -2
  10. package/internal/api-client/principalPolicyPages.js.map +1 -1
  11. package/internal/api-client/principalPolicyRequests.d.ts +118 -1
  12. package/internal/api-client/principalPolicyRequests.js +4 -1
  13. package/internal/api-client/principalPolicyRequests.js.map +1 -1
  14. package/internal/validators/operation/principalPolicyPageQuery.d.ts +9 -0
  15. package/internal/validators/operation/principalPolicyPageQuery.js +10 -0
  16. package/internal/validators/operation/principalPolicyPageQuery.js.map +1 -1
  17. package/internal/validators/operation/principals.d.ts +37 -4
  18. package/internal/validators/operation/principals.js +5 -3
  19. package/internal/validators/operation/principals.js.map +1 -1
  20. package/internal/validators/response/index.d.ts +1 -1
  21. package/internal/validators/response/index.js +1 -1
  22. package/internal/validators/response/index.js.map +1 -1
  23. package/internal/validators/response/principalPolicyPage.d.ts +497 -1
  24. package/internal/validators/response/principalPolicyPage.js +18 -0
  25. package/internal/validators/response/principalPolicyPage.js.map +1 -1
  26. package/package.json +1 -1
  27. package/workflows/container-contents/documentLinks/index.d.ts +4 -0
  28. package/workflows/container-contents/documentLinks/index.js +10 -3
  29. package/workflows/container-contents/documentLinks/index.js.map +1 -1
  30. package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js +7 -2
  31. package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js.map +1 -1
  32. package/workflows/container-contents/tombstones/documentTombstoneEvidence.js +6 -5
  33. package/workflows/container-contents/tombstones/documentTombstoneEvidence.js.map +1 -1
  34. package/workflows/principals/principalPolicyHistoryReader.d.ts +6 -1
  35. package/workflows/principals/principalPolicyHistoryReader.js +4 -1
  36. package/workflows/principals/principalPolicyHistoryReader.js.map +1 -1
  37. package/workflows/principals/recoveryOperation/principalRecoveryDirectory.js +108 -59
  38. package/workflows/principals/recoveryOperation/principalRecoveryDirectory.js.map +1 -1
  39. package/workflows/principals/runtimePolicyRecovery.js +26 -14
  40. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  41. package/workflows/principals/runtimePolicyWarmer.d.ts +26 -0
  42. package/workflows/principals/runtimePolicyWarmer.js +8 -5
  43. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
@@ -9,11 +9,11 @@ import { createContainerDocumentQueriesFromRuntime } from "../../workflows/conta
9
9
  import { createContainerContentsWorkflowRuntime, } from "../../workflows/container-contents/runtime.js";
10
10
  import { guardDocumentDiscoveryWrites } from "../../workflows/container-contents/syncPause/discoveryGuard.js";
11
11
  import { createContainerDocumentTombstoneVerifier, createDocumentHeadLinkSetLoader, } from "../../workflows/container-contents/tombstones/documentTombstoneEvidence.js";
12
- import { createRuntimePrincipalPolicyWarmer } from "../../workflows/principals/runtimePolicyWarmer.js";
12
+ import { createPrincipalPolicyOperation, createRuntimePrincipalPolicyWarmer, } from "../../workflows/principals/runtimePolicyWarmer.js";
13
13
  function createDiscoveryLane(input) {
14
14
  const { containerOrganizationId, execSql, request, runtime } = input;
15
- const warmReferencedPrincipalPolicies = createRuntimePrincipalPolicyWarmer(runtime);
16
- const loadHead = createDocumentHeadLinkSetLoader(runtime);
15
+ const warmReferencedPrincipalPolicies = createRuntimePrincipalPolicyWarmer(runtime, { operation: input.policyOperation });
16
+ const loadHead = createDocumentHeadLinkSetLoader(runtime, undefined, input.policyOperation);
17
17
  const loadEpoch = (documentId) => loadLocalDocumentAccessEpoch(execSql, documentId);
18
18
  return {
19
19
  ...input.queries,
@@ -63,6 +63,7 @@ export async function discoverContainerDocumentLanesForRuntime({ onOutcome, requ
63
63
  const syncPauses = getOrCreateOrganizationSyncPauses(input.state.domainScope);
64
64
  await syncPauses.load(execSql);
65
65
  const lanes = [];
66
+ const policyOperation = createPrincipalPolicyOperation();
66
67
  for (const request of requests) {
67
68
  const stored = await sqlContainerContentsPersistence.loadContainerMetadataState(execSql, request.containerId);
68
69
  if (!stored)
@@ -76,6 +77,7 @@ export async function discoverContainerDocumentLanesForRuntime({ onOutcome, requ
76
77
  isContainerPaused,
77
78
  evidenceStore,
78
79
  execSql,
80
+ policyOperation,
79
81
  queries,
80
82
  request,
81
83
  runtime,
@@ -1 +1 @@
1
- {"version":3,"file":"documentDiscovery.js","sourceRoot":"","sources":["documentDiscovery.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { sqlContainerContentsPersistence } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n holdContainerDocumentTombstones,\n listKnownContainerDocumentPlacements,\n listRetryableHeldContainerDocumentTombstones,\n loadLocalDocumentAccessEpoch,\n refuteContainerDocumentTombstoneHolds,\n} from \"../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence\";\nimport { createDocumentDiscoveryEvidenceStore } from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\nimport { getOrCreateOrganizationSyncPauses } from \"../../data/sync/organizationSyncPauses\";\nimport { listContainerDocumentLanesFromApi } from \"../../workflows/container-contents/documentDiscovery/containerDocumentListing\";\nimport { createDiscoveredDocumentVerifier } from \"../../workflows/container-contents/documentDiscovery/documentDiscoveryEvidence\";\nimport {\n type ContainerDocumentDiscoveryLane,\n type ContainerDocumentDiscoveryOutcome,\n type ContainerDocumentDiscoveryOutcomeHandler,\n discoverContainerDocumentLanes,\n} from \"../../workflows/container-contents/documentDiscovery/documentDiscoveryLanes\";\nimport { createContainerDocumentQueriesFromRuntime } from \"../../workflows/container-contents/documentQueries\";\nimport {\n type ContainerContentsWorkflowRuntime,\n createContainerContentsWorkflowRuntime,\n} from \"../../workflows/container-contents/runtime\";\nimport { guardDocumentDiscoveryWrites } from \"../../workflows/container-contents/syncPause/discoveryGuard\";\nimport {\n createContainerDocumentTombstoneVerifier,\n createDocumentHeadLinkSetLoader,\n} from \"../../workflows/container-contents/tombstones/documentTombstoneEvidence\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../workflows/principals/runtimePolicyWarmer\";\nimport type { InternalRuntime } from \"../runtime/workflowRuntime\";\n\nexport type { ContainerDocumentDiscoveryOutcome } from \"../../workflows/container-contents/documentDiscovery/documentDiscoveryLanes\";\n\n/** One container to discover, with the reconciler's per-lane callbacks. */\nexport interface ContainerDocumentDiscoveryRequest {\n readonly containerId: string;\n readonly onFullListing?:\n | ((documentIds: ReadonlyArray<string>) => void)\n | undefined;\n readonly onPendingDiscovery?: ((delayMs: number) => void) | undefined;\n}\n\ntype ExecSql = ReturnType<InternalRuntime[\"workflowInput\"]>[\"infra\"][\"execSql\"];\n\nfunction createDiscoveryLane(input: {\n readonly containerOrganizationId: string | undefined;\n readonly isContainerPaused: () => boolean;\n readonly evidenceStore: ReturnType<\n typeof createDocumentDiscoveryEvidenceStore\n >;\n readonly execSql: ExecSql;\n readonly queries: ReturnType<\n typeof createContainerDocumentQueriesFromRuntime\n >;\n readonly request: ContainerDocumentDiscoveryRequest;\n readonly runtime: ContainerContentsWorkflowRuntime;\n}): ContainerDocumentDiscoveryLane {\n const { containerOrganizationId, execSql, request, runtime } = input;\n const warmReferencedPrincipalPolicies =\n createRuntimePrincipalPolicyWarmer(runtime);\n const loadHead = createDocumentHeadLinkSetLoader(runtime);\n const loadEpoch = (documentId: string) =>\n loadLocalDocumentAccessEpoch(execSql, documentId);\n return {\n ...input.queries,\n cacheReferencedPrincipalPolicies: (references) =>\n containerOrganizationId\n ? warmReferencedPrincipalPolicies({\n organizationId: containerOrganizationId,\n references,\n })\n : Promise.resolve(),\n containerId: request.containerId,\n holdContainerDocumentTombstones: (tombstones) =>\n holdContainerDocumentTombstones(execSql, tombstones),\n listHeldContainerDocumentTombstones: (containerIds) =>\n listRetryableHeldContainerDocumentTombstones(execSql, containerIds),\n listKnownContainerDocumentPlacements: (placements) =>\n listKnownContainerDocumentPlacements(execSql, placements),\n onFullListing: request.onFullListing,\n refuteContainerDocumentTombstoneHolds: (placements) =>\n refuteContainerDocumentTombstoneHolds(execSql, placements),\n verifyContainerDocumentTombstones: createContainerDocumentTombstoneVerifier(\n containerOrganizationId,\n loadHead,\n loadEpoch,\n ),\n ...guardDocumentDiscoveryWrites({\n execSql,\n isPaused: input.isContainerPaused,\n verifyDiscoveredDocuments: createDiscoveredDocumentVerifier(\n containerOrganizationId,\n loadHead,\n loadEpoch,\n input.evidenceStore,\n request.onPendingDiscovery,\n ),\n }),\n };\n}\n\n/**\n * Internal adapter shared by explicit discovery and background reconciliation:\n * one batched listing for every requested container, then per-container\n * verification scoped to each container's durable organization.\n */\nexport async function discoverContainerDocumentLanesForRuntime({\n onOutcome,\n requests,\n runtimeService,\n}: {\n readonly onOutcome?: ContainerDocumentDiscoveryOutcomeHandler | undefined;\n readonly requests: ReadonlyArray<ContainerDocumentDiscoveryRequest>;\n readonly runtimeService: InternalRuntime;\n}): Promise<ReadonlyArray<ContainerDocumentDiscoveryOutcome>> {\n const unlisted = (\n containerId: string,\n ): ContainerDocumentDiscoveryOutcome => ({\n containerId,\n status: \"fulfilled\",\n value: null,\n });\n const input = runtimeService.workflowInput();\n if (input.infra.dbStatus !== \"ready\") {\n return requests.map(({ containerId }) => unlisted(containerId));\n }\n const runtime = createContainerContentsWorkflowRuntime(input);\n const execSql = input.infra.execSql;\n const evidenceStore = createDocumentDiscoveryEvidenceStore(execSql);\n const queries = createContainerDocumentQueriesFromRuntime(runtime);\n // Capture the reset fence before reading any lane's scope, so a reset\n // between these reads and the listing cannot publish old-organization\n // evidence into its replacement.\n const generation = await evidenceStore.begin();\n const syncPauses = getOrCreateOrganizationSyncPauses(input.state.domainScope);\n await syncPauses.load(execSql);\n const lanes: ContainerDocumentDiscoveryLane[] = [];\n for (const request of requests) {\n const stored =\n await sqlContainerContentsPersistence.loadContainerMetadataState(\n execSql,\n request.containerId,\n );\n if (!stored) continue;\n const isContainerPaused = () =>\n syncPauses.isContainerPaused(\n stored.container,\n runtimeService.workflowInput().auth.organizationId ?? null,\n );\n // A paused organization's container lists like one that is not stored,\n // and a pause landing mid-listing stops its write.\n if (!isContainerPaused())\n lanes.push(\n createDiscoveryLane({\n containerOrganizationId: stored.container.organizationId,\n isContainerPaused,\n evidenceStore,\n execSql,\n queries,\n request,\n runtime,\n }),\n );\n }\n const outcomes = await discoverContainerDocumentLanes({\n generation,\n lanes,\n listContainerDocumentLanes: (listed) =>\n listContainerDocumentLanesFromApi(runtime.apiClient, listed),\n loadContainerDocumentWatermark: queries.loadContainerDocumentWatermark,\n onOutcome,\n });\n const outcomeByContainerId = new Map(\n outcomes.map((outcome) => [outcome.containerId, outcome]),\n );\n return requests.map(\n ({ containerId }) =>\n outcomeByContainerId.get(containerId) ?? unlisted(containerId),\n );\n}\n\n/** Discovers one container; a rejected lane rethrows its failure. */\nexport async function discoverContainerDocumentsForRuntime({\n runtimeService,\n ...request\n}: ContainerDocumentDiscoveryRequest & {\n readonly runtimeService: InternalRuntime;\n}): Promise<ReadonlyArray<DocumentSummary> | null> {\n const [outcome] = await discoverContainerDocumentLanesForRuntime({\n requests: [request],\n runtimeService,\n });\n if (outcome?.status === \"rejected\") throw outcome.reason;\n return outcome?.value ?? null;\n}\n"]}
1
+ {"version":3,"file":"documentDiscovery.js","sourceRoot":"","sources":["documentDiscovery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,wEAAwE,CAAC;AACzH,OAAO,EACL,+BAA+B,EAC/B,oCAAoC,EACpC,4CAA4C,EAC5C,4BAA4B,EAC5B,qCAAqC,GACtC,MAAM,6EAA6E,CAAC;AACrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,uEAAuE,CAAC;AAC7H,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,EAAE,iCAAiC,EAAE,MAAM,+EAA+E,CAAC;AAClI,OAAO,EAAE,gCAAgC,EAAE,MAAM,gFAAgF,CAAC;AAClI,OAAO,EAIL,8BAA8B,GAC/B,MAAM,6EAA6E,CAAC;AACrF,OAAO,EAAE,yCAAyC,EAAE,MAAM,oDAAoD,CAAC;AAC/G,OAAO,EAEL,sCAAsC,GACvC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,6DAA6D,CAAC;AAC3G,OAAO,EACL,wCAAwC,EACxC,+BAA+B,GAChC,MAAM,yEAAyE,CAAC;AACjF,OAAO,EACL,8BAA8B,EAC9B,kCAAkC,GAEnC,MAAM,gDAAgD,CAAC;AAgBxD,SAAS,mBAAmB,CAAC,KAc5B;IACC,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACrE,MAAM,+BAA+B,GAAG,kCAAkC,CACxE,OAAO,EACP,EAAE,SAAS,EAAE,KAAK,CAAC,eAAe,EAAE,CACrC,CAAC;IACF,MAAM,QAAQ,GAAG,+BAA+B,CAC9C,OAAO,EACP,SAAS,EACT,KAAK,CAAC,eAAe,CACtB,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAE,EAAE,CACvC,4BAA4B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACpD,OAAO;QACL,GAAG,KAAK,CAAC,OAAO;QAChB,gCAAgC,EAAE,CAAC,UAAU,EAAE,EAAE,CAC/C,uBAAuB;YACrB,CAAC,CAAC,+BAA+B,CAAC;gBAC9B,cAAc,EAAE,uBAAuB;gBACvC,UAAU;aACX,CAAC;YACJ,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE;QACvB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,+BAA+B,EAAE,CAAC,UAAU,EAAE,EAAE,CAC9C,+BAA+B,CAAC,OAAO,EAAE,UAAU,CAAC;QACtD,mCAAmC,EAAE,CAAC,YAAY,EAAE,EAAE,CACpD,4CAA4C,CAAC,OAAO,EAAE,YAAY,CAAC;QACrE,oCAAoC,EAAE,CAAC,UAAU,EAAE,EAAE,CACnD,oCAAoC,CAAC,OAAO,EAAE,UAAU,CAAC;QAC3D,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,qCAAqC,EAAE,CAAC,UAAU,EAAE,EAAE,CACpD,qCAAqC,CAAC,OAAO,EAAE,UAAU,CAAC;QAC5D,iCAAiC,EAAE,wCAAwC,CACzE,uBAAuB,EACvB,QAAQ,EACR,SAAS,CACV;QACD,GAAG,4BAA4B,CAAC;YAC9B,OAAO;YACP,QAAQ,EAAE,KAAK,CAAC,iBAAiB;YACjC,yBAAyB,EAAE,gCAAgC,CACzD,uBAAuB,EACvB,QAAQ,EACR,SAAS,EACT,KAAK,CAAC,aAAa,EACnB,OAAO,CAAC,kBAAkB,CAC3B;SACF,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAAC,EAC7D,SAAS,EACT,QAAQ,EACR,cAAc,GAKf;IACC,MAAM,QAAQ,GAAG,CACf,WAAmB,EACgB,EAAE,CAAC,CAAC;QACvC,WAAW;QACX,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,cAAc,CAAC,aAAa,EAAE,CAAC;IAC7C,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACrC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,OAAO,GAAG,sCAAsC,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;IACpC,MAAM,aAAa,GAAG,oCAAoC,CAAC,OAAO,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,yCAAyC,CAAC,OAAO,CAAC,CAAC;IACnE,sEAAsE;IACtE,sEAAsE;IACtE,iCAAiC;IACjC,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,iCAAiC,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9E,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAqC,EAAE,CAAC;IACnD,MAAM,eAAe,GAAG,8BAA8B,EAAE,CAAC;IACzD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GACV,MAAM,+BAA+B,CAAC,0BAA0B,CAC9D,OAAO,EACP,OAAO,CAAC,WAAW,CACpB,CAAC;QACJ,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAC7B,UAAU,CAAC,iBAAiB,CAC1B,MAAM,CAAC,SAAS,EAChB,cAAc,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAC3D,CAAC;QACJ,uEAAuE;QACvE,mDAAmD;QACnD,IAAI,CAAC,iBAAiB,EAAE;YACtB,KAAK,CAAC,IAAI,CACR,mBAAmB,CAAC;gBAClB,uBAAuB,EAAE,MAAM,CAAC,SAAS,CAAC,cAAc;gBACxD,iBAAiB;gBACjB,aAAa;gBACb,OAAO;gBACP,eAAe;gBACf,OAAO;gBACP,OAAO;gBACP,OAAO;aACR,CAAC,CACH,CAAC;IACN,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,8BAA8B,CAAC;QACpD,UAAU;QACV,KAAK;QACL,0BAA0B,EAAE,CAAC,MAAM,EAAE,EAAE,CACrC,iCAAiC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;QAC9D,8BAA8B,EAAE,OAAO,CAAC,8BAA8B;QACtE,SAAS;KACV,CAAC,CAAC;IACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAClC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAC1D,CAAC;IACF,OAAO,QAAQ,CAAC,GAAG,CACjB,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAClB,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC,CACjE,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,EACzD,cAAc,EACd,GAAG,OAAO,EAGX;IACC,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,wCAAwC,CAAC;QAC/D,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,cAAc;KACf,CAAC,CAAC;IACH,IAAI,OAAO,EAAE,MAAM,KAAK,UAAU;QAAE,MAAM,OAAO,CAAC,MAAM,CAAC;IACzD,OAAO,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC;AAChC,CAAC","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport { sqlContainerContentsPersistence } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n holdContainerDocumentTombstones,\n listKnownContainerDocumentPlacements,\n listRetryableHeldContainerDocumentTombstones,\n loadLocalDocumentAccessEpoch,\n refuteContainerDocumentTombstoneHolds,\n} from \"../../data/persistence/documents/containerDocumentTombstoneHoldsPersistence\";\nimport { createDocumentDiscoveryEvidenceStore } from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\nimport { getOrCreateOrganizationSyncPauses } from \"../../data/sync/organizationSyncPauses\";\nimport { listContainerDocumentLanesFromApi } from \"../../workflows/container-contents/documentDiscovery/containerDocumentListing\";\nimport { createDiscoveredDocumentVerifier } from \"../../workflows/container-contents/documentDiscovery/documentDiscoveryEvidence\";\nimport {\n type ContainerDocumentDiscoveryLane,\n type ContainerDocumentDiscoveryOutcome,\n type ContainerDocumentDiscoveryOutcomeHandler,\n discoverContainerDocumentLanes,\n} from \"../../workflows/container-contents/documentDiscovery/documentDiscoveryLanes\";\nimport { createContainerDocumentQueriesFromRuntime } from \"../../workflows/container-contents/documentQueries\";\nimport {\n type ContainerContentsWorkflowRuntime,\n createContainerContentsWorkflowRuntime,\n} from \"../../workflows/container-contents/runtime\";\nimport { guardDocumentDiscoveryWrites } from \"../../workflows/container-contents/syncPause/discoveryGuard\";\nimport {\n createContainerDocumentTombstoneVerifier,\n createDocumentHeadLinkSetLoader,\n} from \"../../workflows/container-contents/tombstones/documentTombstoneEvidence\";\nimport {\n createPrincipalPolicyOperation,\n createRuntimePrincipalPolicyWarmer,\n type PrincipalPolicyOperation,\n} from \"../../workflows/principals/runtimePolicyWarmer\";\nimport type { InternalRuntime } from \"../runtime/workflowRuntime\";\n\nexport type { ContainerDocumentDiscoveryOutcome } from \"../../workflows/container-contents/documentDiscovery/documentDiscoveryLanes\";\n\n/** One container to discover, with the reconciler's per-lane callbacks. */\nexport interface ContainerDocumentDiscoveryRequest {\n readonly containerId: string;\n readonly onFullListing?:\n | ((documentIds: ReadonlyArray<string>) => void)\n | undefined;\n readonly onPendingDiscovery?: ((delayMs: number) => void) | undefined;\n}\n\ntype ExecSql = ReturnType<InternalRuntime[\"workflowInput\"]>[\"infra\"][\"execSql\"];\n\nfunction createDiscoveryLane(input: {\n readonly containerOrganizationId: string | undefined;\n readonly isContainerPaused: () => boolean;\n readonly evidenceStore: ReturnType<\n typeof createDocumentDiscoveryEvidenceStore\n >;\n readonly execSql: ExecSql;\n /** The discovery pass's token: its lanes share one directory discovery. */\n readonly policyOperation: PrincipalPolicyOperation;\n readonly queries: ReturnType<\n typeof createContainerDocumentQueriesFromRuntime\n >;\n readonly request: ContainerDocumentDiscoveryRequest;\n readonly runtime: ContainerContentsWorkflowRuntime;\n}): ContainerDocumentDiscoveryLane {\n const { containerOrganizationId, execSql, request, runtime } = input;\n const warmReferencedPrincipalPolicies = createRuntimePrincipalPolicyWarmer(\n runtime,\n { operation: input.policyOperation },\n );\n const loadHead = createDocumentHeadLinkSetLoader(\n runtime,\n undefined,\n input.policyOperation,\n );\n const loadEpoch = (documentId: string) =>\n loadLocalDocumentAccessEpoch(execSql, documentId);\n return {\n ...input.queries,\n cacheReferencedPrincipalPolicies: (references) =>\n containerOrganizationId\n ? warmReferencedPrincipalPolicies({\n organizationId: containerOrganizationId,\n references,\n })\n : Promise.resolve(),\n containerId: request.containerId,\n holdContainerDocumentTombstones: (tombstones) =>\n holdContainerDocumentTombstones(execSql, tombstones),\n listHeldContainerDocumentTombstones: (containerIds) =>\n listRetryableHeldContainerDocumentTombstones(execSql, containerIds),\n listKnownContainerDocumentPlacements: (placements) =>\n listKnownContainerDocumentPlacements(execSql, placements),\n onFullListing: request.onFullListing,\n refuteContainerDocumentTombstoneHolds: (placements) =>\n refuteContainerDocumentTombstoneHolds(execSql, placements),\n verifyContainerDocumentTombstones: createContainerDocumentTombstoneVerifier(\n containerOrganizationId,\n loadHead,\n loadEpoch,\n ),\n ...guardDocumentDiscoveryWrites({\n execSql,\n isPaused: input.isContainerPaused,\n verifyDiscoveredDocuments: createDiscoveredDocumentVerifier(\n containerOrganizationId,\n loadHead,\n loadEpoch,\n input.evidenceStore,\n request.onPendingDiscovery,\n ),\n }),\n };\n}\n\n/**\n * Internal adapter shared by explicit discovery and background reconciliation:\n * one batched listing for every requested container, then per-container\n * verification scoped to each container's durable organization.\n */\nexport async function discoverContainerDocumentLanesForRuntime({\n onOutcome,\n requests,\n runtimeService,\n}: {\n readonly onOutcome?: ContainerDocumentDiscoveryOutcomeHandler | undefined;\n readonly requests: ReadonlyArray<ContainerDocumentDiscoveryRequest>;\n readonly runtimeService: InternalRuntime;\n}): Promise<ReadonlyArray<ContainerDocumentDiscoveryOutcome>> {\n const unlisted = (\n containerId: string,\n ): ContainerDocumentDiscoveryOutcome => ({\n containerId,\n status: \"fulfilled\",\n value: null,\n });\n const input = runtimeService.workflowInput();\n if (input.infra.dbStatus !== \"ready\") {\n return requests.map(({ containerId }) => unlisted(containerId));\n }\n const runtime = createContainerContentsWorkflowRuntime(input);\n const execSql = input.infra.execSql;\n const evidenceStore = createDocumentDiscoveryEvidenceStore(execSql);\n const queries = createContainerDocumentQueriesFromRuntime(runtime);\n // Capture the reset fence before reading any lane's scope, so a reset\n // between these reads and the listing cannot publish old-organization\n // evidence into its replacement.\n const generation = await evidenceStore.begin();\n const syncPauses = getOrCreateOrganizationSyncPauses(input.state.domainScope);\n await syncPauses.load(execSql);\n const lanes: ContainerDocumentDiscoveryLane[] = [];\n const policyOperation = createPrincipalPolicyOperation();\n for (const request of requests) {\n const stored =\n await sqlContainerContentsPersistence.loadContainerMetadataState(\n execSql,\n request.containerId,\n );\n if (!stored) continue;\n const isContainerPaused = () =>\n syncPauses.isContainerPaused(\n stored.container,\n runtimeService.workflowInput().auth.organizationId ?? null,\n );\n // A paused organization's container lists like one that is not stored,\n // and a pause landing mid-listing stops its write.\n if (!isContainerPaused())\n lanes.push(\n createDiscoveryLane({\n containerOrganizationId: stored.container.organizationId,\n isContainerPaused,\n evidenceStore,\n execSql,\n policyOperation,\n queries,\n request,\n runtime,\n }),\n );\n }\n const outcomes = await discoverContainerDocumentLanes({\n generation,\n lanes,\n listContainerDocumentLanes: (listed) =>\n listContainerDocumentLanesFromApi(runtime.apiClient, listed),\n loadContainerDocumentWatermark: queries.loadContainerDocumentWatermark,\n onOutcome,\n });\n const outcomeByContainerId = new Map(\n outcomes.map((outcome) => [outcome.containerId, outcome]),\n );\n return requests.map(\n ({ containerId }) =>\n outcomeByContainerId.get(containerId) ?? unlisted(containerId),\n );\n}\n\n/** Discovers one container; a rejected lane rethrows its failure. */\nexport async function discoverContainerDocumentsForRuntime({\n runtimeService,\n ...request\n}: ContainerDocumentDiscoveryRequest & {\n readonly runtimeService: InternalRuntime;\n}): Promise<ReadonlyArray<DocumentSummary> | null> {\n const [outcome] = await discoverContainerDocumentLanesForRuntime({\n requests: [request],\n runtimeService,\n });\n if (outcome?.status === \"rejected\") throw outcome.reason;\n return outcome?.value ?? null;\n}\n"]}
@@ -1134,6 +1134,124 @@ export declare class ApiClient {
1134
1134
  version: number;
1135
1135
  };
1136
1136
  }>, void, any>;
1137
+ /** Unpinned discovery; `ifHead` asks for a bare head when it is still live. */
1138
+ getPrincipalPolicyDiscovery(...args: Parameters<PrincipalPolicyRequests["discover"]>): Promise<RequestResult<{
1139
+ previousStates: {
1140
+ grants: {
1141
+ accessLevel: "admin" | "read" | "write";
1142
+ containerId: string;
1143
+ }[];
1144
+ projection: {
1145
+ role: "member" | "admin";
1146
+ userId: string;
1147
+ }[];
1148
+ state: {
1149
+ createdAt: string;
1150
+ encapsulationPublicKey: string;
1151
+ externalAuthority: {
1152
+ keyEpoch: number;
1153
+ keyFingerprint: string;
1154
+ principalId: string;
1155
+ principalType: "group";
1156
+ stateHash: string;
1157
+ version: number;
1158
+ } | null;
1159
+ grantCount: number;
1160
+ grantRoot: string;
1161
+ keyEpoch: number;
1162
+ keyFingerprint: string;
1163
+ memberCount: number;
1164
+ memberEnvelopesRoot: string;
1165
+ membershipMode: "projection";
1166
+ membershipRoot: string;
1167
+ payloadCiphertextHash: string;
1168
+ prevStateHash: string | null;
1169
+ principalId: string;
1170
+ principalType: "group" | "organization";
1171
+ projectionRoot: string;
1172
+ signature: string;
1173
+ signedAt: string;
1174
+ signerUserId: string;
1175
+ signerUserKeyFingerprint: string;
1176
+ stateHash: string;
1177
+ version: number;
1178
+ };
1179
+ }[];
1180
+ historyPage: {
1181
+ afterVersion: number;
1182
+ nextAfterVersion: number | null;
1183
+ };
1184
+ currentGrants: {
1185
+ accessLevel: "admin" | "read" | "write";
1186
+ containerId: string;
1187
+ }[];
1188
+ currentMemberEnvelopes: {
1189
+ envelopes: {
1190
+ kemCipherText: string;
1191
+ memberKeyFingerprint: string;
1192
+ userId: string;
1193
+ wrappedKey: string;
1194
+ }[];
1195
+ epoch: number;
1196
+ principalId: string;
1197
+ principalType: "group" | "organization";
1198
+ stateHash: string;
1199
+ };
1200
+ currentPayload: {
1201
+ cipherSuite: "aes-256-gcm";
1202
+ ciphertext: string;
1203
+ ciphertextHash: string;
1204
+ createdAt: string;
1205
+ principalId: string;
1206
+ principalType: "group" | "organization";
1207
+ stateHash: string;
1208
+ };
1209
+ currentProjection: {
1210
+ role: "member" | "admin";
1211
+ userId: string;
1212
+ }[];
1213
+ currentState: {
1214
+ createdAt: string;
1215
+ encapsulationPublicKey: string;
1216
+ externalAuthority: {
1217
+ keyEpoch: number;
1218
+ keyFingerprint: string;
1219
+ principalId: string;
1220
+ principalType: "group";
1221
+ stateHash: string;
1222
+ version: number;
1223
+ } | null;
1224
+ grantCount: number;
1225
+ grantRoot: string;
1226
+ keyEpoch: number;
1227
+ keyFingerprint: string;
1228
+ memberCount: number;
1229
+ memberEnvelopesRoot: string;
1230
+ membershipMode: "projection";
1231
+ membershipRoot: string;
1232
+ payloadCiphertextHash: string;
1233
+ prevStateHash: string | null;
1234
+ principalId: string;
1235
+ principalType: "group" | "organization";
1236
+ projectionRoot: string;
1237
+ signature: string;
1238
+ signedAt: string;
1239
+ signerUserId: string;
1240
+ signerUserKeyFingerprint: string;
1241
+ stateHash: string;
1242
+ version: number;
1243
+ };
1244
+ } | {
1245
+ unchanged: true;
1246
+ head: {
1247
+ keyEpoch: number;
1248
+ keyFingerprint: string;
1249
+ principalId: string;
1250
+ principalType: "group" | "organization";
1251
+ stateHash: string;
1252
+ version: number;
1253
+ };
1254
+ }>>;
1137
1255
  getProjectionPolicyHistoryPages(...args: Parameters<PrincipalPolicyRequests["publicPages"]>): AsyncGenerator<RequestResult<{
1138
1256
  currentGrants: {
1139
1257
  accessLevel: "admin" | "read" | "write";
@@ -271,6 +271,10 @@ export class ApiClient {
271
271
  getPrincipalPolicyPages(principalType, principalId, options = {}) {
272
272
  return this.principalPolicyRequests.pages(principalType, principalId, options);
273
273
  }
274
+ /** Unpinned discovery; `ifHead` asks for a bare head when it is still live. */
275
+ getPrincipalPolicyDiscovery(...args) {
276
+ return this.principalPolicyRequests.discover(...args);
277
+ }
274
278
  getProjectionPolicyHistoryPages(...args) {
275
279
  return this.principalPolicyRequests.publicPages(...args);
276
280
  }