@tearleads/client-sdk 0.1.82 → 0.1.85

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 (182) hide show
  1. package/data/documents/documentSync.js.map +1 -1
  2. package/data/documents/shared/crypto.js.map +1 -1
  3. package/data/documents/shared/types.d.ts +1 -1
  4. package/data/documents/shared/types.js.map +1 -1
  5. package/data/persistence/container-contents/containerContentsPersistence.js +2 -2
  6. package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
  7. package/data/persistence/container-contents/containerContentsPersistenceTypes.d.ts +1 -1
  8. package/data/persistence/container-contents/containerContentsPersistenceTypes.js.map +1 -1
  9. package/data/persistence/container-contents/containerDeletionPersistence.js +1 -1
  10. package/data/persistence/container-contents/containerDeletionPersistence.js.map +1 -1
  11. package/data/persistence/container-contents/containerDocumentReassignment.js +7 -9
  12. package/data/persistence/container-contents/containerDocumentReassignment.js.map +1 -1
  13. package/data/persistence/container-contents/containerMetadataMutationPersistence.js +3 -3
  14. package/data/persistence/container-contents/containerMetadataMutationPersistence.js.map +1 -1
  15. package/data/persistence/container-contents/containerMetadataPullContinuationPersistence.js +1 -1
  16. package/data/persistence/container-contents/containerMetadataPullContinuationPersistence.js.map +1 -1
  17. package/data/persistence/container-contents/containerMetadataRows.js +4 -20
  18. package/data/persistence/container-contents/containerMetadataRows.js.map +1 -1
  19. package/data/persistence/container-contents/containerPendingUpdatePersistence.js +2 -2
  20. package/data/persistence/container-contents/containerPendingUpdatePersistence.js.map +1 -1
  21. package/data/persistence/container-contents/containerRebindPersistence.js +4 -17
  22. package/data/persistence/container-contents/containerRebindPersistence.js.map +1 -1
  23. package/data/persistence/container-contents/containerReconcilePersistence.js +1 -1
  24. package/data/persistence/container-contents/containerReconcilePersistence.js.map +1 -1
  25. package/data/persistence/container-contents/containerRemovalWork.js +1 -1
  26. package/data/persistence/container-contents/containerRemovalWork.js.map +1 -1
  27. package/data/persistence/container-contents/containerStructuralRepair.js +5 -11
  28. package/data/persistence/container-contents/containerStructuralRepair.js.map +1 -1
  29. package/data/persistence/container-contents/documentContainerProjectionPersistence.js +34 -9
  30. package/data/persistence/container-contents/documentContainerProjectionPersistence.js.map +1 -1
  31. package/data/persistence/container-contents/dormantContainerMetadata.js +4 -14
  32. package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
  33. package/data/persistence/documents/documentDiscoveryEvidencePersistence.js +5 -9
  34. package/data/persistence/documents/documentDiscoveryEvidencePersistence.js.map +1 -1
  35. package/data/persistence/documents/documentDiscoveryReset.d.ts +6 -0
  36. package/data/persistence/documents/documentProjectionContainers.js +28 -0
  37. package/data/persistence/documents/documentProjectionContainers.js.map +1 -0
  38. package/data/persistence/documents/documentsPersistence.js +5 -9
  39. package/data/persistence/documents/documentsPersistence.js.map +1 -1
  40. package/data/persistence/documents/internal/containerDocumentTombstones.js +4 -11
  41. package/data/persistence/documents/internal/containerDocumentTombstones.js.map +1 -1
  42. package/data/persistence/documents/internal/createDocumentWithHistoryCheckpoint.js +1 -1
  43. package/data/persistence/documents/internal/createDocumentWithHistoryCheckpoint.js.map +1 -1
  44. package/data/persistence/documents/internal/discardDocument.js +2 -2
  45. package/data/persistence/documents/internal/discardDocument.js.map +1 -1
  46. package/data/persistence/documents/internal/documentDeletionPersistence.js +8 -22
  47. package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
  48. package/data/persistence/documents/internal/documentMutationPersistence.js +3 -3
  49. package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
  50. package/data/persistence/documents/internal/documentPullContinuationPersistence.js +1 -1
  51. package/data/persistence/documents/internal/documentPullContinuationPersistence.js.map +1 -1
  52. package/data/persistence/documents/internal/documentRecordIdentity.js.map +1 -1
  53. package/data/persistence/documents/internal/documentRows.js.map +1 -1
  54. package/data/persistence/documents/internal/ensureDocumentsSchema.js +1 -1
  55. package/data/persistence/documents/internal/ensureDocumentsSchema.js.map +1 -1
  56. package/data/persistence/documents/internal/orphanSideRows.js +1 -1
  57. package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
  58. package/data/persistence/documents/internal/rowQueryPersistence.js +1 -1
  59. package/data/persistence/documents/internal/rowQueryPersistence.js.map +1 -1
  60. package/data/persistence/documents/internal/syncQueuePersistence.js +2 -2
  61. package/data/persistence/documents/internal/syncQueuePersistence.js.map +1 -1
  62. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentHistoryPersistence.d.ts +1 -1
  63. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentHistoryPersistence.js +5 -5
  64. package/data/persistence/documents/records/documentHistoryPersistence.js.map +1 -0
  65. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPendingUpdatePersistence.d.ts +2 -2
  66. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPendingUpdatePersistence.js +2 -2
  67. package/data/persistence/documents/records/documentPendingUpdatePersistence.js.map +1 -0
  68. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPersistenceTypes.d.ts +2 -2
  69. package/data/persistence/documents/records/documentPersistenceTypes.js.map +1 -0
  70. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentRecordPersistence.d.ts +1 -1
  71. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentRecordPersistence.js +4 -4
  72. package/data/persistence/documents/records/documentRecordPersistence.js.map +1 -0
  73. package/data/persistence/documents/records/documentRowsInTransaction.js +68 -0
  74. package/data/persistence/documents/records/documentRowsInTransaction.js.map +1 -0
  75. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentSyncFailurePersistence.d.ts +2 -2
  76. package/data/{sqlite/documentPersistence → persistence/documents/records}/documentSyncFailurePersistence.js +3 -3
  77. package/data/persistence/documents/records/documentSyncFailurePersistence.js.map +1 -0
  78. package/data/{sqlite/documentPersistence → persistence/documents/records}/index.d.ts +2 -2
  79. package/data/{sqlite/documentPersistence → persistence/documents/records}/index.js +4 -4
  80. package/data/persistence/documents/records/index.js.map +1 -0
  81. package/data/persistence/documents/types.d.ts +2 -2
  82. package/data/persistence/documents/types.js.map +1 -1
  83. package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.d.ts +2 -0
  84. package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js +9 -0
  85. package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js.map +1 -1
  86. package/data/persistence/keyingCheckpoints/keyingCheckpointPersistence.js +9 -0
  87. package/data/persistence/keyingCheckpoints/keyingCheckpointPersistence.js.map +1 -1
  88. package/data/persistence/principalPolicy/principalPolicyPersistence.js +3 -9
  89. package/data/persistence/principalPolicy/principalPolicyPersistence.js.map +1 -1
  90. package/{workflows/sync/remoteResetPrincipalScope.d.ts → data/persistence/principalPolicy/principalPolicyRemoteReset.d.ts} +1 -1
  91. package/{workflows/sync/remoteResetPrincipalScope.js → data/persistence/principalPolicy/principalPolicyRemoteReset.js} +16 -13
  92. package/data/persistence/principalPolicy/principalPolicyRemoteReset.js.map +1 -0
  93. package/data/persistence/verifiedManifestBundlePersistence.d.ts +2 -0
  94. package/data/persistence/verifiedManifestBundlePersistence.js +7 -0
  95. package/data/persistence/verifiedManifestBundlePersistence.js.map +1 -1
  96. package/data/sqlite/{documentPersistence/documentOrphanBlobReclaims.js → schema/documentOrphanBlobReclaimSchema.js} +1 -1
  97. package/data/sqlite/schema/documentOrphanBlobReclaimSchema.js.map +1 -0
  98. package/data/sqlite/schema/index.js +1 -1
  99. package/data/sqlite/schema/index.js.map +1 -1
  100. package/data/sqlite/sqliteBindBudget.js +12 -0
  101. package/data/sqlite/sqliteBindBudget.js.map +1 -1
  102. package/package.json +1 -1
  103. package/workflows/container-contents/container-state/create/createIntentSeed.js.map +1 -1
  104. package/workflows/container-contents/container-state/create/createWithMetadataPlan.js.map +1 -1
  105. package/workflows/container-contents/container-state/types.js.map +1 -1
  106. package/workflows/container-contents/metadata/index.js.map +1 -1
  107. package/workflows/container-contents/metadata/metadataEvents.d.ts +1 -1
  108. package/workflows/container-contents/metadata/metadataEvents.js.map +1 -1
  109. package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js +1 -1
  110. package/workflows/container-contents/metadata/metadataIncomingUpdateIsolation.js.map +1 -1
  111. package/workflows/container-contents/metadata/metadataRemoteSync.d.ts +1 -1
  112. package/workflows/container-contents/metadata/metadataRemoteSync.js.map +1 -1
  113. package/workflows/container-contents/pendingWrites/index.js +1 -1
  114. package/workflows/container-contents/pendingWrites/index.js.map +1 -1
  115. package/workflows/container-contents/recovery/accessRestoration.js +1 -1
  116. package/workflows/container-contents/recovery/accessRestoration.js.map +1 -1
  117. package/workflows/container-contents/remoteReset/containerRemoteReset.d.ts +185 -0
  118. package/workflows/container-contents/remoteReset/containerRemoteReset.js +174 -0
  119. package/workflows/container-contents/remoteReset/containerRemoteReset.js.map +1 -0
  120. package/workflows/container-contents/remoteReset/remoteResetCursorScope.d.ts +14 -0
  121. package/workflows/{sync → container-contents/remoteReset}/remoteResetCursorScope.js +2 -2
  122. package/workflows/container-contents/remoteReset/remoteResetCursorScope.js.map +1 -0
  123. package/workflows/documents/create/documentCreationPersistence.js.map +1 -1
  124. package/workflows/documents/create/index.d.ts +1 -1
  125. package/workflows/documents/create/index.js.map +1 -1
  126. package/workflows/documents/documentMutationCommit.d.ts +1 -1
  127. package/workflows/documents/documentMutationCommit.js.map +1 -1
  128. package/workflows/documents/index.d.ts +2 -2
  129. package/workflows/documents/index.js +2 -2
  130. package/workflows/documents/index.js.map +1 -1
  131. package/workflows/documents/remoteReset/documentRemoteReset.d.ts +56 -0
  132. package/workflows/documents/remoteReset/documentRemoteReset.js +135 -0
  133. package/workflows/documents/remoteReset/documentRemoteReset.js.map +1 -0
  134. package/workflows/{sync → documents/remoteReset}/remoteResetAttachments.js +3 -3
  135. package/workflows/documents/remoteReset/remoteResetAttachments.js.map +1 -0
  136. package/workflows/{sync → documents/remoteReset}/remoteResetPlans.d.ts +1 -1
  137. package/workflows/{sync → documents/remoteReset}/remoteResetPlans.js +7 -7
  138. package/workflows/documents/remoteReset/remoteResetPlans.js.map +1 -0
  139. package/workflows/documents/sync/index.js.map +1 -1
  140. package/workflows/documents/sync/initialSync.d.ts +1 -1
  141. package/workflows/documents/sync/initialSync.js.map +1 -1
  142. package/workflows/documents/sync/readOnlySync.d.ts +1 -1
  143. package/workflows/documents/sync/readOnlySync.js.map +1 -1
  144. package/workflows/documents/sync/syncAttemptPlanning.js.map +1 -1
  145. package/workflows/documents/sync/syncAttemptState.d.ts +1 -1
  146. package/workflows/documents/sync/syncAttemptState.js.map +1 -1
  147. package/workflows/documents/sync/syncResponseResult.js.map +1 -1
  148. package/workflows/documents/sync/syncSubmittedResult.js.map +1 -1
  149. package/workflows/documents/syncFailures/index.js.map +1 -1
  150. package/workflows/documents/syncPlan/syncContentKeys.d.ts +1 -1
  151. package/workflows/documents/syncPlan/syncContentKeys.js.map +1 -1
  152. package/workflows/documents/syncPlan/syncPlanMaterial.js.map +1 -1
  153. package/workflows/documents/syncPlan/syncPlanRequestBounds.js.map +1 -1
  154. package/workflows/documents/syncRekeys/syncContainerRekeys.js.map +1 -1
  155. package/workflows/documents/syncRekeys/syncRecoveryRekey.d.ts +1 -1
  156. package/workflows/documents/syncRekeys/syncRecoveryRekey.js +1 -1
  157. package/workflows/documents/syncRekeys/syncRecoveryRekey.js.map +1 -1
  158. package/workflows/organizations/readModel/listLocalOrganizations.js +1 -1
  159. package/workflows/organizations/readModel/listLocalOrganizations.js.map +1 -1
  160. package/workflows/organizations/readModel/organizationRemoteReset.js +25 -0
  161. package/workflows/organizations/readModel/organizationRemoteReset.js.map +1 -0
  162. package/workflows/registration/persistRegistrationBootstrap.d.ts +1 -1
  163. package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
  164. package/workflows/sync/remoteReset.js +60 -229
  165. package/workflows/sync/remoteReset.js.map +1 -1
  166. package/workflows/sync/remoteResetScope.d.ts +7 -10
  167. package/workflows/sync/remoteResetScope.js +26 -108
  168. package/workflows/sync/remoteResetScope.js.map +1 -1
  169. package/data/sqlite/documentPersistence/documentHistoryPersistence.js.map +0 -1
  170. package/data/sqlite/documentPersistence/documentOrphanBlobReclaims.js.map +0 -1
  171. package/data/sqlite/documentPersistence/documentPendingUpdatePersistence.js.map +0 -1
  172. package/data/sqlite/documentPersistence/documentPersistenceTypes.js.map +0 -1
  173. package/data/sqlite/documentPersistence/documentRecordPersistence.js.map +0 -1
  174. package/data/sqlite/documentPersistence/documentSyncFailurePersistence.js.map +0 -1
  175. package/data/sqlite/documentPersistence/index.js.map +0 -1
  176. package/workflows/sync/remoteResetAttachments.js.map +0 -1
  177. package/workflows/sync/remoteResetBatches.js +0 -13
  178. package/workflows/sync/remoteResetBatches.js.map +0 -1
  179. package/workflows/sync/remoteResetCursorScope.js.map +0 -1
  180. package/workflows/sync/remoteResetPlans.js.map +0 -1
  181. package/workflows/sync/remoteResetPrincipalScope.js.map +0 -1
  182. /package/data/{sqlite/documentPersistence → persistence/documents/records}/documentPersistenceTypes.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"listLocalOrganizations.js","sourceRoot":"","sources":["listLocalOrganizations.ts"],"names":[],"mappings":"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","sourcesContent":["import { readStoredDocumentState } from \"../../../data/documents/documentKinds\";\nimport { sqlContainerContentsPersistence } from \"../../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n DOCUMENTS_APP_KIND,\n sqlDocumentsPersistence,\n} from \"../../../data/persistence/documents/documentsPersistence\";\nimport { loadOrganizationProfileDocumentIds } from \"../../../data/persistence/organizations/organizationProfileDocumentPointers\";\nimport { findLocalIdByDocumentId } from \"../../../data/sqlite/documentPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { loadPersistedDocumentContent } from \"../../documents\";\nimport {\n getOrganizationProfileDocumentLocalId,\n readOrganizationProfileName,\n} from \"../organizationProfile\";\nimport { deriveOrganizationMetadataContainerSystemSlot } from \"../rosterProfileContainer\";\n\n// Just the container fields this module needs to locate an org's metadata\n// container among the locally-persisted containers.\ninterface LocalContainerForNameLookup {\n id: string;\n systemSlot: string | null;\n}\n\n/**\n * A locally-known organization the user belongs to, derived from its persisted\n * root container. `name` is the decrypted organization-profile display name when\n * one is stored locally, or null when it has not synced yet.\n */\nexport interface LocalOrganizationSummary {\n name: string | null;\n organizationId: string;\n rootContainerId: string;\n}\n\n// Reads and decrypts the `name` field of the organization_profile document\n// persisted under `documentLocalId`, or null if it is absent, empty, or\n// unparseable. A single corrupt profile must not break the whole list, so every\n// failure collapses to a null (unnamed) organization.\nasync function readOrganizationNameFromDocument(\n execSql: ExecSql,\n documentLocalId: string,\n): Promise<string | null> {\n try {\n const doc = await loadPersistedDocumentContent({\n execSql,\n localId: documentLocalId,\n persistence: sqlDocumentsPersistence,\n });\n if (!doc) {\n return null;\n }\n\n return readOrganizationProfileName(\n readStoredDocumentState(doc).structuredFields,\n );\n } catch {\n return null;\n }\n}\n\n/**\n * Resolves an organization's decrypted display name from local state.\n *\n * The same organization_profile document is addressed by several different\n * local-id conventions depending on how it arrived, so one lookup by id is not\n * enough:\n *\n * - The org's own **provisioner** (and any admin who later edits the name)\n * writes the document under the deterministic alias\n * `org-profile:<organizationId>` — resolved by the fast path below.\n * - A **device that only synced it** — a member of another org, or this same\n * user's freshly re-hydrated device after an identity restore — never runs\n * that write. The sync ingest keys the document under the server documentId\n * (there is no local alias to reuse — see `upsertDiscoveredDocumentWithExec`),\n * so the alias lookup misses.\n *\n * Two fallbacks cover the synced case, in order of authority:\n *\n * 1. The **organization read model** records the org's `profileDocumentId`.\n * That pointer is container-independent, so it resolves the name wherever\n * the document happens to be linked — including a profile document created\n * by an admin through the org-manager editor rather than by provisioning.\n * 2. Failing that, locate the org's metadata container by its deterministic\n * system slot and read whichever profile document is linked there. Keying on\n * the system slot (rather than the document kind) keeps it correct even\n * before the projected document kind has been rebuilt from a freshly-synced\n * snapshot, and it still works before the read model has been projected.\n */\nasync function readLocalOrganizationName(\n execSql: ExecSql,\n organizationId: string,\n organizationContainers: ReadonlyArray<LocalContainerForNameLookup>,\n profileDocumentId: string | null,\n): Promise<string | null> {\n const aliasName = await readOrganizationNameFromDocument(\n execSql,\n getOrganizationProfileDocumentLocalId({ organizationId }),\n );\n if (aliasName !== null) {\n return aliasName;\n }\n\n if (profileDocumentId) {\n // Reach the row wherever it landed: a device that only synced the document\n // keys it under the server documentId rather than any local alias.\n const syncedLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n profileDocumentId,\n );\n const syncedName = syncedLocalId\n ? await readOrganizationNameFromDocument(execSql, syncedLocalId)\n : null;\n if (syncedName !== null) {\n return syncedName;\n }\n }\n\n const metadataSystemSlot =\n await deriveOrganizationMetadataContainerSystemSlot({ organizationId });\n const metadataContainer = organizationContainers.find(\n (container) => container.systemSlot === metadataSystemSlot,\n );\n if (!metadataContainer) {\n return null;\n }\n\n const documentLocalIds =\n await sqlDocumentsPersistence.findDocumentLocalIdsByContainerId(\n execSql,\n metadataContainer.id,\n );\n for (const documentLocalId of documentLocalIds) {\n const name = await readOrganizationNameFromDocument(\n execSql,\n documentLocalId,\n );\n if (name !== null) {\n return name;\n }\n }\n return null;\n}\n\n/**\n * Enumerates the organizations the user can manage from local state: one per\n * persisted root container. This is intentionally offline — the Explorer already\n * resolves files across organizations by effective permission, so listing the\n * organizations to manage needs no server round-trip.\n */\nexport async function listLocalOrganizations(input: {\n execSql: ExecSql;\n}): Promise<LocalOrganizationSummary[]> {\n const containers = await sqlContainerContentsPersistence.loadContainers(\n input.execSql,\n );\n // A projected read model is not a precondition for listing organizations, so\n // an unreadable one degrades to the container-derived lookups below.\n const profileDocumentIdsByOrganizationId =\n await loadOrganizationProfileDocumentIds(input.execSql).catch(\n () => new Map<string, string>(),\n );\n\n // Group every persisted container by org so name resolution can locate an\n // org's independent metadata root without a second DB scan.\n const containersByOrganizationId = new Map<\n string,\n LocalContainerForNameLookup[]\n >();\n for (const { container } of containers) {\n const entry: LocalContainerForNameLookup = {\n id: container.id,\n systemSlot: container.systemSlot ?? null,\n };\n const group = containersByOrganizationId.get(container.organizationId);\n if (group) {\n group.push(entry);\n } else {\n containersByOrganizationId.set(container.organizationId, [entry]);\n }\n }\n\n const seen = new Set<string>();\n const rootContainers = containers.filter(({ container }) => {\n if (\n container.parentId !== null ||\n container.systemSlot ||\n seen.has(container.organizationId)\n ) {\n return false;\n }\n seen.add(container.organizationId);\n return true;\n });\n rootContainers.sort(\n (left, right) =>\n (left.container.localCreatedAt ?? \"\").localeCompare(\n right.container.localCreatedAt ?? \"\",\n ) ||\n left.container.organizationId.localeCompare(\n right.container.organizationId,\n ) ||\n left.container.id.localeCompare(right.container.id),\n );\n\n // Read each organization's profile name concurrently; readLocalOrganizationName\n // already falls back to null per organization, so a single corrupt profile\n // cannot reject the batch.\n return Promise.all(\n rootContainers.map(async ({ container }) => ({\n name: await readLocalOrganizationName(\n input.execSql,\n container.organizationId,\n containersByOrganizationId.get(container.organizationId) ?? [],\n profileDocumentIdsByOrganizationId.get(container.organizationId) ??\n null,\n ),\n organizationId: container.organizationId,\n rootContainerId: container.id,\n })),\n );\n}\n"]}
1
+ {"version":3,"file":"listLocalOrganizations.js","sourceRoot":"","sources":["listLocalOrganizations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,2EAA2E,CAAC;AAC5H,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AACtF,OAAO,EAAE,kCAAkC,EAAE,MAAM,6EAA6E,CAAC;AAEjI,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EACL,qCAAqC,EACrC,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,6CAA6C,EAAE,MAAM,2BAA2B,CAAC;AAoB1F,2EAA2E;AAC3E,wEAAwE;AACxE,gFAAgF;AAChF,sDAAsD;AACtD,KAAK,UAAU,gCAAgC,CAC7C,OAAgB,EAChB,eAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,4BAA4B,CAAC;YAC7C,OAAO;YACP,OAAO,EAAE,eAAe;YACxB,WAAW,EAAE,uBAAuB;SACrC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,2BAA2B,CAChC,uBAAuB,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAC9C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,KAAK,UAAU,yBAAyB,CACtC,OAAgB,EAChB,cAAsB,EACtB,sBAAkE,EAClE,iBAAgC;IAEhC,MAAM,SAAS,GAAG,MAAM,gCAAgC,CACtD,OAAO,EACP,qCAAqC,CAAC,EAAE,cAAc,EAAE,CAAC,CAC1D,CAAC;IACF,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,iBAAiB,EAAE,CAAC;QACtB,2EAA2E;QAC3E,mEAAmE;QACnE,MAAM,aAAa,GAAG,MAAM,uBAAuB,CACjD,OAAO,EACP,kBAAkB,EAClB,iBAAiB,CAClB,CAAC;QACF,MAAM,UAAU,GAAG,aAAa;YAC9B,CAAC,CAAC,MAAM,gCAAgC,CAAC,OAAO,EAAE,aAAa,CAAC;YAChE,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,kBAAkB,GACtB,MAAM,6CAA6C,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;IAC1E,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,IAAI,CACnD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAC3D,CAAC;IACF,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GACpB,MAAM,uBAAuB,CAAC,iCAAiC,CAC7D,OAAO,EACP,iBAAiB,CAAC,EAAE,CACrB,CAAC;IACJ,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,gCAAgC,CACjD,OAAO,EACP,eAAe,CAChB,CAAC;QACF,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAE5C;IACC,MAAM,UAAU,GAAG,MAAM,+BAA+B,CAAC,cAAc,CACrE,KAAK,CAAC,OAAO,CACd,CAAC;IACF,6EAA6E;IAC7E,qEAAqE;IACrE,MAAM,kCAAkC,GACtC,MAAM,kCAAkC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAC3D,GAAG,EAAE,CAAC,IAAI,GAAG,EAAkB,CAChC,CAAC;IAEJ,0EAA0E;IAC1E,4DAA4D;IAC5D,MAAM,0BAA0B,GAAG,IAAI,GAAG,EAGvC,CAAC;IACJ,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,UAAU,EAAE,CAAC;QACvC,MAAM,KAAK,GAAgC;YACzC,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI,IAAI;SACzC,CAAC;QACF,MAAM,KAAK,GAAG,0BAA0B,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACvE,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,0BAA0B,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;QACzD,IACE,SAAS,CAAC,QAAQ,KAAK,IAAI;YAC3B,SAAS,CAAC,UAAU;YACpB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,EAClC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,cAAc,CAAC,IAAI,CACjB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACd,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,aAAa,CACjD,KAAK,CAAC,SAAS,CAAC,cAAc,IAAI,EAAE,CACrC;QACD,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,aAAa,CACzC,KAAK,CAAC,SAAS,CAAC,cAAc,CAC/B;QACD,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CACtD,CAAC;IAEF,gFAAgF;IAChF,2EAA2E;IAC3E,2BAA2B;IAC3B,OAAO,OAAO,CAAC,GAAG,CAChB,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3C,IAAI,EAAE,MAAM,yBAAyB,CACnC,KAAK,CAAC,OAAO,EACb,SAAS,CAAC,cAAc,EACxB,0BAA0B,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,EAC9D,kCAAkC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC;YAC9D,IAAI,CACP;QACD,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,eAAe,EAAE,SAAS,CAAC,EAAE;KAC9B,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import { readStoredDocumentState } from \"../../../data/documents/documentKinds\";\nimport { sqlContainerContentsPersistence } from \"../../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n DOCUMENTS_APP_KIND,\n sqlDocumentsPersistence,\n} from \"../../../data/persistence/documents/documentsPersistence\";\nimport { findLocalIdByDocumentId } from \"../../../data/persistence/documents/records\";\nimport { loadOrganizationProfileDocumentIds } from \"../../../data/persistence/organizations/organizationProfileDocumentPointers\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { loadPersistedDocumentContent } from \"../../documents\";\nimport {\n getOrganizationProfileDocumentLocalId,\n readOrganizationProfileName,\n} from \"../organizationProfile\";\nimport { deriveOrganizationMetadataContainerSystemSlot } from \"../rosterProfileContainer\";\n\n// Just the container fields this module needs to locate an org's metadata\n// container among the locally-persisted containers.\ninterface LocalContainerForNameLookup {\n id: string;\n systemSlot: string | null;\n}\n\n/**\n * A locally-known organization the user belongs to, derived from its persisted\n * root container. `name` is the decrypted organization-profile display name when\n * one is stored locally, or null when it has not synced yet.\n */\nexport interface LocalOrganizationSummary {\n name: string | null;\n organizationId: string;\n rootContainerId: string;\n}\n\n// Reads and decrypts the `name` field of the organization_profile document\n// persisted under `documentLocalId`, or null if it is absent, empty, or\n// unparseable. A single corrupt profile must not break the whole list, so every\n// failure collapses to a null (unnamed) organization.\nasync function readOrganizationNameFromDocument(\n execSql: ExecSql,\n documentLocalId: string,\n): Promise<string | null> {\n try {\n const doc = await loadPersistedDocumentContent({\n execSql,\n localId: documentLocalId,\n persistence: sqlDocumentsPersistence,\n });\n if (!doc) {\n return null;\n }\n\n return readOrganizationProfileName(\n readStoredDocumentState(doc).structuredFields,\n );\n } catch {\n return null;\n }\n}\n\n/**\n * Resolves an organization's decrypted display name from local state.\n *\n * The same organization_profile document is addressed by several different\n * local-id conventions depending on how it arrived, so one lookup by id is not\n * enough:\n *\n * - The org's own **provisioner** (and any admin who later edits the name)\n * writes the document under the deterministic alias\n * `org-profile:<organizationId>` — resolved by the fast path below.\n * - A **device that only synced it** — a member of another org, or this same\n * user's freshly re-hydrated device after an identity restore — never runs\n * that write. The sync ingest keys the document under the server documentId\n * (there is no local alias to reuse — see `upsertDiscoveredDocumentWithExec`),\n * so the alias lookup misses.\n *\n * Two fallbacks cover the synced case, in order of authority:\n *\n * 1. The **organization read model** records the org's `profileDocumentId`.\n * That pointer is container-independent, so it resolves the name wherever\n * the document happens to be linked — including a profile document created\n * by an admin through the org-manager editor rather than by provisioning.\n * 2. Failing that, locate the org's metadata container by its deterministic\n * system slot and read whichever profile document is linked there. Keying on\n * the system slot (rather than the document kind) keeps it correct even\n * before the projected document kind has been rebuilt from a freshly-synced\n * snapshot, and it still works before the read model has been projected.\n */\nasync function readLocalOrganizationName(\n execSql: ExecSql,\n organizationId: string,\n organizationContainers: ReadonlyArray<LocalContainerForNameLookup>,\n profileDocumentId: string | null,\n): Promise<string | null> {\n const aliasName = await readOrganizationNameFromDocument(\n execSql,\n getOrganizationProfileDocumentLocalId({ organizationId }),\n );\n if (aliasName !== null) {\n return aliasName;\n }\n\n if (profileDocumentId) {\n // Reach the row wherever it landed: a device that only synced the document\n // keys it under the server documentId rather than any local alias.\n const syncedLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n profileDocumentId,\n );\n const syncedName = syncedLocalId\n ? await readOrganizationNameFromDocument(execSql, syncedLocalId)\n : null;\n if (syncedName !== null) {\n return syncedName;\n }\n }\n\n const metadataSystemSlot =\n await deriveOrganizationMetadataContainerSystemSlot({ organizationId });\n const metadataContainer = organizationContainers.find(\n (container) => container.systemSlot === metadataSystemSlot,\n );\n if (!metadataContainer) {\n return null;\n }\n\n const documentLocalIds =\n await sqlDocumentsPersistence.findDocumentLocalIdsByContainerId(\n execSql,\n metadataContainer.id,\n );\n for (const documentLocalId of documentLocalIds) {\n const name = await readOrganizationNameFromDocument(\n execSql,\n documentLocalId,\n );\n if (name !== null) {\n return name;\n }\n }\n return null;\n}\n\n/**\n * Enumerates the organizations the user can manage from local state: one per\n * persisted root container. This is intentionally offline — the Explorer already\n * resolves files across organizations by effective permission, so listing the\n * organizations to manage needs no server round-trip.\n */\nexport async function listLocalOrganizations(input: {\n execSql: ExecSql;\n}): Promise<LocalOrganizationSummary[]> {\n const containers = await sqlContainerContentsPersistence.loadContainers(\n input.execSql,\n );\n // A projected read model is not a precondition for listing organizations, so\n // an unreadable one degrades to the container-derived lookups below.\n const profileDocumentIdsByOrganizationId =\n await loadOrganizationProfileDocumentIds(input.execSql).catch(\n () => new Map<string, string>(),\n );\n\n // Group every persisted container by org so name resolution can locate an\n // org's independent metadata root without a second DB scan.\n const containersByOrganizationId = new Map<\n string,\n LocalContainerForNameLookup[]\n >();\n for (const { container } of containers) {\n const entry: LocalContainerForNameLookup = {\n id: container.id,\n systemSlot: container.systemSlot ?? null,\n };\n const group = containersByOrganizationId.get(container.organizationId);\n if (group) {\n group.push(entry);\n } else {\n containersByOrganizationId.set(container.organizationId, [entry]);\n }\n }\n\n const seen = new Set<string>();\n const rootContainers = containers.filter(({ container }) => {\n if (\n container.parentId !== null ||\n container.systemSlot ||\n seen.has(container.organizationId)\n ) {\n return false;\n }\n seen.add(container.organizationId);\n return true;\n });\n rootContainers.sort(\n (left, right) =>\n (left.container.localCreatedAt ?? \"\").localeCompare(\n right.container.localCreatedAt ?? \"\",\n ) ||\n left.container.organizationId.localeCompare(\n right.container.organizationId,\n ) ||\n left.container.id.localeCompare(right.container.id),\n );\n\n // Read each organization's profile name concurrently; readLocalOrganizationName\n // already falls back to null per organization, so a single corrupt profile\n // cannot reject the batch.\n return Promise.all(\n rootContainers.map(async ({ container }) => ({\n name: await readLocalOrganizationName(\n input.execSql,\n container.organizationId,\n containersByOrganizationId.get(container.organizationId) ?? [],\n profileDocumentIdsByOrganizationId.get(container.organizationId) ??\n null,\n ),\n organizationId: container.organizationId,\n rootContainerId: container.id,\n })),\n );\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { organizationDataUsageSnapshots } from "../../../data/sqlite/schema/organizationDataUsageSchema.js";
3
+ import { organizationPresentationDenials, organizationReadModelContainerGrants, organizationReadModelDirectoryUsers, organizationReadModelGroupMembers, organizationReadModelGroups, organizationReadModelRequesters, organizationReadModelState, } from "../../../data/sqlite/schema/organizationReadModelSchema.js";
4
+ // Organization Read Models' part of a remote reset: the sync remote reset runs
5
+ // inside `runOrganizationPresentationReset` and calls this in its transaction.
6
+ export { runOrganizationPresentationReset } from "./organizationPresentationAccessState.js";
7
+ /** Deletes every read model and presentation denial cached for the organization. */
8
+ export async function clearOrganizationReadModelsForRemoteReset(tx, organizationId) {
9
+ for (const table of [
10
+ organizationDataUsageSnapshots,
11
+ organizationReadModelContainerGrants,
12
+ organizationReadModelGroupMembers,
13
+ organizationReadModelDirectoryUsers,
14
+ organizationReadModelGroups,
15
+ organizationReadModelRequesters,
16
+ organizationReadModelState,
17
+ organizationPresentationDenials,
18
+ ]) {
19
+ await tx
20
+ .delete(table)
21
+ .where(eq(table.organizationId, organizationId))
22
+ .run();
23
+ }
24
+ }
25
+ //# sourceMappingURL=organizationRemoteReset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organizationRemoteReset.js","sourceRoot":"","sources":["organizationRemoteReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,8BAA8B,EAAE,MAAM,yDAAyD,CAAC;AACzG,OAAO,EACL,+BAA+B,EAC/B,oCAAoC,EACpC,mCAAmC,EACnC,iCAAiC,EACjC,2BAA2B,EAC3B,+BAA+B,EAC/B,0BAA0B,GAC3B,MAAM,yDAAyD,CAAC;AAGjE,+EAA+E;AAC/E,+EAA+E;AAC/E,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AAEzF,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,yCAAyC,CAC7D,EAAgC,EAChC,cAAsB;IAEtB,KAAK,MAAM,KAAK,IAAI;QAClB,8BAA8B;QAC9B,oCAAoC;QACpC,iCAAiC;QACjC,mCAAmC;QACnC,2BAA2B;QAC3B,+BAA+B;QAC/B,0BAA0B;QAC1B,+BAA+B;KACvB,EAAE,CAAC;QACX,MAAM,EAAE;aACL,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;aAC/C,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport { organizationDataUsageSnapshots } from \"../../../data/sqlite/schema/organizationDataUsageSchema\";\nimport {\n organizationPresentationDenials,\n organizationReadModelContainerGrants,\n organizationReadModelDirectoryUsers,\n organizationReadModelGroupMembers,\n organizationReadModelGroups,\n organizationReadModelRequesters,\n organizationReadModelState,\n} from \"../../../data/sqlite/schema/organizationReadModelSchema\";\nimport type { ClientSQLiteTransactionScope } from \"../../../data/sqlite/sqlitePersistenceRuntime\";\n\n// Organization Read Models' part of a remote reset: the sync remote reset runs\n// inside `runOrganizationPresentationReset` and calls this in its transaction.\nexport { runOrganizationPresentationReset } from \"./organizationPresentationAccessState\";\n\n/** Deletes every read model and presentation denial cached for the organization. */\nexport async function clearOrganizationReadModelsForRemoteReset(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<void> {\n for (const table of [\n organizationDataUsageSnapshots,\n organizationReadModelContainerGrants,\n organizationReadModelGroupMembers,\n organizationReadModelDirectoryUsers,\n organizationReadModelGroups,\n organizationReadModelRequesters,\n organizationReadModelState,\n organizationPresentationDenials,\n ] as const) {\n await tx\n .delete(table)\n .where(eq(table.organizationId, organizationId))\n .run();\n }\n}\n"]}
@@ -2,8 +2,8 @@ import type { ContainerSystemSlot } from "../../internal/validators/containerSys
2
2
  import type { PrincipalPolicyBundleResponse } from "../../internal/validators/response/index.js";
3
3
  import type { DocumentProjectorRegistryInput } from "../../data/documents/documentKinds.js";
4
4
  import { type AuthoredDiscoveryHead } from "../../data/persistence/documents/documentDiscoveryEvidencePersistence.js";
5
+ import type { DocumentRecord } from "../../data/persistence/documents/records/index.js";
5
6
  import { type LocallyAcknowledgedAccessManifestHead } from "../../data/persistence/keyingCheckpoints/locallyAcknowledgedCheckpointPersistence.js";
6
- import type { DocumentRecord } from "../../data/sqlite/documentPersistence/index.js";
7
7
  import { type ExecSql, type ExecSqlClientLike } from "../../data/sqlite/sqlSchema.js";
8
8
  interface ProvisionedContainerBootstrapInput {
9
9
  accessEpoch: number;
@@ -1 +1 @@
1
- {"version":3,"file":"persistRegistrationBootstrap.js","sourceRoot":"","sources":["persistRegistrationBootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createDocument,\n encodeVersionVector,\n importUpdates,\n} from \"@tearleads/loro\";\nimport type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport type { DocumentProjectorRegistryInput } from \"../../data/documents/documentKinds\";\nimport { createPendingUpdateFields } from \"../../data/documents/documentSync\";\nimport {\n type ContainerMetadataRecord,\n sqlContainerContentsPersistence,\n} from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n type AuthoredDiscoveryHead,\n primeAuthoredDocumentDiscoveryHeads,\n} from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\nimport {\n DOCUMENTS_APP_KIND,\n sqlDocumentsPersistence,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport {\n advanceLocallyAcknowledgedAccessManifestHeadsAtomically,\n type LocallyAcknowledgedAccessManifestHead,\n} from \"../../data/persistence/keyingCheckpoints/locallyAcknowledgedCheckpointPersistence\";\nimport type { DocumentRecord } from \"../../data/sqlite/documentPersistence\";\nimport { documentContainerProjectionTables } from \"../../data/sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport {\n createExecSql,\n type ExecSql,\n type ExecSqlClientLike,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../data/sqlite/sqlSchema\";\nimport { getScopedPeerSeed } from \"../../data/sync/crdtPeerSeed\";\nimport { persistDocumentState } from \"../documents/persistence\";\nimport { ORGANIZATION_PROFILE_DOCUMENT_KIND } from \"../organizations/organizationProfile\";\nimport {\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n ROSTER_PROFILE_DOCUMENT_KIND,\n} from \"../organizations/rosterProfileContainer\";\nimport { enqueueInitialContainerMetadataUpdate } from \"./registrationBootstrapPendingUpdates\";\nimport { persistRegistrationPrincipalPolicies } from \"./registrationPrincipalPolicyPersistence\";\n\ninterface ProvisionedContainerBootstrapInput {\n accessEpoch: number;\n accessStateHash: string;\n containerId: string;\n createdAt: string;\n metadataDocumentId: string;\n metadataSnapshot: string;\n metadataState: Pick<\n DocumentRecord,\n | \"documentId\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\"\n >;\n systemSlot: ContainerSystemSlot;\n updatedAt: string;\n}\n\ninterface ProvisionedProfileDocumentBootstrapInput {\n accessEpoch: number;\n accessStateHash: string;\n containerId: string;\n documentId: string;\n documentState: ProvisionedContainerBootstrapInput[\"metadataState\"];\n initialUpdate: Uint8Array;\n initialUpdateCommitted: boolean;\n localId: string;\n}\n\nexport interface RegistrationBootstrapInput {\n acknowledgedAccessHeads: readonly LocallyAcknowledgedAccessManifestHead[];\n /** Seeded documents' acknowledged signed heads; see the discovery cache. */\n authoredDiscoveryHeads: readonly AuthoredDiscoveryHead[];\n /** Checked inside the mutation queue claim; false skips every write. */\n canStartDurableMutation?: (() => boolean) | undefined;\n /**\n * @internal Test-only synchronization seam. Invoked synchronously,\n * immediately before this persist joins the serialized mutation queue —\n * no interleaving can separate the two. Lets identity-race tests\n * deterministically place an identity replacement inside the queue-wait\n * window instead of sleeping.\n */\n onPersistQueued?: (() => void) | undefined;\n containerId: string;\n initialAdminGroupPolicy: PrincipalPolicyBundleResponse;\n initialMemberGroupPolicy: PrincipalPolicyBundleResponse;\n initialOrganizationPolicy: PrincipalPolicyBundleResponse;\n rootMetadataAccessEpoch: number;\n rootMetadataAccessStateHash: string;\n rootContainerServerTimestamp: string;\n rootMetadataDocumentId: string;\n rootMetadataInitialUpdate: Uint8Array;\n rootMetadataInitialUpdateCommitted?: boolean | undefined;\n rootMetadataSnapshot: string;\n rootMetadataState: ProvisionedContainerBootstrapInput[\"metadataState\"];\n rosterProfileContainer?: ProvisionedContainerBootstrapInput & {\n metadataInitialUpdate: Uint8Array;\n metadataInitialUpdateCommitted?: boolean | undefined;\n };\n organizationMetadataContainer?: ProvisionedContainerBootstrapInput & {\n metadataInitialUpdate: Uint8Array;\n metadataInitialUpdateCommitted?: boolean | undefined;\n };\n organizationProfileDocument?: ProvisionedProfileDocumentBootstrapInput;\n rosterProfileDocument?: ProvisionedProfileDocumentBootstrapInput;\n // Additional app-owned system containers provisioned with the organization\n // (e.g. a trash bin). Each carries its own display name and icon (unlike the\n // roster/organization-metadata containers, whose names are fixed), since the\n // caller declares them.\n systemContainers?: Array<\n ProvisionedContainerBootstrapInput & {\n icon: string | null;\n name: string;\n }\n >;\n documentProjectors?: DocumentProjectorRegistryInput | undefined;\n organizationId: string;\n userId: string;\n}\nasync function persistProvisionedContainerBootstrap(\n execSql: ExecSql,\n input: {\n container: ProvisionedContainerBootstrapInput;\n icon: string | null;\n name: string;\n organizationId: string;\n parentId: string | null;\n },\n): Promise<void> {\n const { container } = input;\n const metadataState = container.metadataState;\n const record: ContainerMetadataRecord = {\n accessEpoch: container.accessEpoch,\n accessStateHash: container.accessStateHash,\n documentId: container.metadataDocumentId,\n id: container.containerId,\n lastCommitLsn: null,\n metadataUpdates: container.metadataSnapshot,\n snapshotEndVersion: \"\",\n contentKeyBundle: metadataState.contentKeyBundle ?? null,\n documentKekTargets: metadataState.documentKekTargets ?? null,\n documentManifestBundle: metadataState.documentManifestBundle ?? null,\n };\n await sqlContainerContentsPersistence.saveContainer(\n execSql,\n {\n id: container.containerId,\n effectiveAccessLevel: \"admin\",\n organizationId: input.organizationId,\n parentId: input.parentId,\n metadataDocumentId: container.metadataDocumentId,\n systemSlot: container.systemSlot,\n name: input.name,\n icon: input.icon,\n },\n record,\n {\n localUpdatedAt: container.updatedAt,\n serverTimestamps: {\n createdAt: container.createdAt,\n updatedAt: container.updatedAt,\n },\n },\n );\n}\n\nasync function persistRootContainerBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n): Promise<void> {\n const rootRecord: ContainerMetadataRecord = {\n accessEpoch: input.rootMetadataAccessEpoch,\n accessStateHash: input.rootMetadataAccessStateHash,\n documentId: input.rootMetadataDocumentId,\n id: input.containerId,\n lastCommitLsn: null,\n metadataUpdates: input.rootMetadataSnapshot,\n snapshotEndVersion: \"\",\n contentKeyBundle: input.rootMetadataState.contentKeyBundle ?? null,\n documentKekTargets: input.rootMetadataState.documentKekTargets ?? null,\n documentManifestBundle:\n input.rootMetadataState.documentManifestBundle ?? null,\n };\n await sqlContainerContentsPersistence.saveContainer(\n execSql,\n {\n id: input.containerId,\n effectiveAccessLevel: \"admin\",\n organizationId: input.organizationId,\n parentId: null,\n metadataDocumentId: input.rootMetadataDocumentId,\n name: \"/\",\n icon: null,\n },\n rootRecord,\n {\n localUpdatedAt: input.rootContainerServerTimestamp,\n serverTimestamps: {\n createdAt: input.rootContainerServerTimestamp,\n updatedAt: input.rootContainerServerTimestamp,\n },\n },\n );\n await enqueueInitialContainerMetadataUpdate(\n execSql,\n input.containerId,\n input.rootMetadataInitialUpdate,\n input.rootMetadataInitialUpdateCommitted,\n );\n}\n\n// Persist reserved profile containers using their fixed topology: roster profiles\n// inherit the personal root; shared organization metadata has an independent root.\nasync function persistNamedChildContainerBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n container: RegistrationBootstrapInput[\"rosterProfileContainer\"],\n name: string,\n): Promise<void> {\n if (!container) {\n return;\n }\n\n await persistProvisionedContainerBootstrap(execSql, {\n container,\n icon: null,\n name,\n organizationId: input.organizationId,\n parentId:\n container === input.organizationMetadataContainer\n ? null\n : input.containerId,\n });\n await enqueueInitialContainerMetadataUpdate(\n execSql,\n container.containerId,\n container.metadataInitialUpdate,\n container.metadataInitialUpdateCommitted,\n );\n}\n\nasync function persistSystemContainersBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n): Promise<void> {\n const systemContainers = input.systemContainers;\n if (!systemContainers) {\n return;\n }\n\n for (const systemContainer of systemContainers) {\n await persistProvisionedContainerBootstrap(execSql, {\n container: systemContainer,\n icon: systemContainer.icon,\n name: systemContainer.name,\n organizationId: input.organizationId,\n parentId: input.containerId,\n });\n // Provisioned system-container metadata is already committed remotely in\n // the organization transaction. Persist the initialized snapshot locally,\n // but do not queue a duplicate write with a second update id.\n }\n}\n\n// The ONE persist shape for the provisioned profile documents (organization\n// profile and roster profile): the input carries exactly the bootstrap\n// fields, so only the document kind and the host's projectors join it.\nasync function persistProfileDocumentBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n profileDocument: ProvisionedProfileDocumentBootstrapInput | undefined,\n documentKind: string,\n): Promise<void> {\n if (!profileDocument) {\n return;\n }\n\n await persistInitialDocumentBootstrap(execSql, {\n ...profileDocument,\n documentKind,\n documentProjectors: input.documentProjectors,\n });\n}\n\nexport async function persistInitialDocumentBootstrap(\n execSql: ExecSql,\n input: {\n accessEpoch: number;\n accessStateHash: string;\n containerId: string;\n documentId: string;\n documentKind: string;\n documentProjectors: DocumentProjectorRegistryInput | undefined;\n documentState: Pick<\n DocumentRecord,\n \"contentKeyBundle\" | \"documentKekTargets\" | \"documentManifestBundle\"\n >;\n initialUpdate: Uint8Array;\n initialUpdateCommitted: boolean;\n localId: string;\n },\n): Promise<void> {\n const doc = await createDocument(await getScopedPeerSeed(DOCUMENTS_APP_KIND));\n importUpdates(doc, [input.initialUpdate]);\n const pendingUpdate = input.initialUpdateCommitted\n ? undefined\n : (createPendingUpdateFields(input.initialUpdate) ?? undefined);\n\n await persistDocumentState({\n currentDoc: doc,\n currentRecord: null,\n documentProjectors: input.documentProjectors ?? [],\n execSql,\n localId: input.localId,\n patch: {\n accessEpoch: input.accessEpoch,\n accessStateHash: input.accessStateHash,\n containerId: input.containerId,\n contentKeyBundle: input.documentState.contentKeyBundle ?? null,\n documentId: input.documentId,\n // Successful provisioning makes this device's user the founding admin.\n // Stores can open before discovery returns the same access level.\n effectiveAccessLevel: \"admin\",\n documentKekTargets: input.documentState.documentKekTargets ?? null,\n documentKind: input.documentKind,\n documentManifestBundle:\n input.documentState.documentManifestBundle ?? null,\n // The create-only persistence primitive stores this frontier and the\n // full-history checkpoint in one transaction.\n snapshotEndVersion: encodeVersionVector(doc),\n },\n pendingUpdate,\n persistence: sqlDocumentsPersistence,\n });\n}\n\n/**\n * Persists the local root-container bootstrap created during successful\n * registration so container contents can initialize from SQLite on first\n * login — atomically: every write lands inside ONE transaction whose last\n * act re-checks identity currency, so an identity replaced anywhere between\n * the queue claim and the commit rolls the entire bootstrap back instead of\n * leaving a partial one. Resolves false when either currency check rejected\n * the write, so callers do not report a bootstrap that was never persisted.\n */\nexport async function persistRegistrationBootstrapFromExecSql(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n): Promise<boolean> {\n input.onPersistQueued?.();\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n // In-mutex currency check, adjacent to the serialized-mutation claim\n // (see persistDocumentState): the identity can be replaced while this\n // persist waits for the queue, and its bootstrap must not be written\n // through a client the replacement closed or renewed.\n if (input.canStartDurableMutation && !input.canStartDurableMutation()) {\n return false;\n }\n // Idempotent DDL stays outside the atomic boundary.\n await sqlContainerContentsPersistence.ensureSchema(lockedExecSql);\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n // Pre-commit currency guard: the write sequence awaits real work, so\n // the identity can be replaced mid-sequence. The guard runs\n // synchronously with the COMMIT dispatch, so a refusal rolls the whole\n // write set back and a pass cannot go stale before the commit is sent —\n // the partial-persist window a single entry check leaves open.\n const { committed } = await getClientSQLitePersistenceRuntime(\n lockedExecSql,\n ).guardedTransaction(\n async () => {\n await advanceLocallyAcknowledgedAccessManifestHeadsAtomically({\n execSql: lockedExecSql,\n heads: input.acknowledgedAccessHeads,\n });\n await persistRegistrationPrincipalPolicies({\n adminGroup: input.initialAdminGroupPolicy,\n execSql: lockedExecSql,\n memberGroup: input.initialMemberGroupPolicy,\n organization: input.initialOrganizationPolicy,\n });\n await persistRootContainerBootstrap(lockedExecSql, input);\n await persistNamedChildContainerBootstrap(\n lockedExecSql,\n input,\n input.rosterProfileContainer,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n );\n await persistProfileDocumentBootstrap(\n lockedExecSql,\n input,\n input.rosterProfileDocument,\n ROSTER_PROFILE_DOCUMENT_KIND,\n );\n await persistNamedChildContainerBootstrap(\n lockedExecSql,\n input,\n input.organizationMetadataContainer,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n );\n await persistProfileDocumentBootstrap(\n lockedExecSql,\n input,\n input.organizationProfileDocument,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n );\n await persistSystemContainersBootstrap(lockedExecSql, input);\n // After the checkpoints above: discovery reuses a cached head only\n // while its access-manifest checkpoint still matches.\n await primeAuthoredDocumentDiscoveryHeads(\n lockedExecSql,\n input.authoredDiscoveryHeads,\n );\n },\n () => !input.canStartDurableMutation || input.canStartDurableMutation(),\n );\n return committed;\n });\n}\n\nexport async function persistRegistrationBootstrap(\n client: ExecSqlClientLike,\n input: RegistrationBootstrapInput,\n): Promise<void> {\n await persistRegistrationBootstrapFromExecSql(createExecSql(client), input);\n}\n"]}
1
+ {"version":3,"file":"persistRegistrationBootstrap.js","sourceRoot":"","sources":["persistRegistrationBootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createDocument,\n encodeVersionVector,\n importUpdates,\n} from \"@tearleads/loro\";\nimport type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport type { DocumentProjectorRegistryInput } from \"../../data/documents/documentKinds\";\nimport { createPendingUpdateFields } from \"../../data/documents/documentSync\";\nimport {\n type ContainerMetadataRecord,\n sqlContainerContentsPersistence,\n} from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n type AuthoredDiscoveryHead,\n primeAuthoredDocumentDiscoveryHeads,\n} from \"../../data/persistence/documents/documentDiscoveryEvidencePersistence\";\nimport {\n DOCUMENTS_APP_KIND,\n sqlDocumentsPersistence,\n} from \"../../data/persistence/documents/documentsPersistence\";\nimport type { DocumentRecord } from \"../../data/persistence/documents/records\";\nimport {\n advanceLocallyAcknowledgedAccessManifestHeadsAtomically,\n type LocallyAcknowledgedAccessManifestHead,\n} from \"../../data/persistence/keyingCheckpoints/locallyAcknowledgedCheckpointPersistence\";\nimport { documentContainerProjectionTables } from \"../../data/sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../../data/sqlite/sqlitePersistenceRuntime\";\nimport {\n createExecSql,\n type ExecSql,\n type ExecSqlClientLike,\n ensureSqlTables,\n runSerializedSqlMutation,\n} from \"../../data/sqlite/sqlSchema\";\nimport { getScopedPeerSeed } from \"../../data/sync/crdtPeerSeed\";\nimport { persistDocumentState } from \"../documents/persistence\";\nimport { ORGANIZATION_PROFILE_DOCUMENT_KIND } from \"../organizations/organizationProfile\";\nimport {\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n ROSTER_PROFILE_DOCUMENT_KIND,\n} from \"../organizations/rosterProfileContainer\";\nimport { enqueueInitialContainerMetadataUpdate } from \"./registrationBootstrapPendingUpdates\";\nimport { persistRegistrationPrincipalPolicies } from \"./registrationPrincipalPolicyPersistence\";\n\ninterface ProvisionedContainerBootstrapInput {\n accessEpoch: number;\n accessStateHash: string;\n containerId: string;\n createdAt: string;\n metadataDocumentId: string;\n metadataSnapshot: string;\n metadataState: Pick<\n DocumentRecord,\n | \"documentId\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\"\n >;\n systemSlot: ContainerSystemSlot;\n updatedAt: string;\n}\n\ninterface ProvisionedProfileDocumentBootstrapInput {\n accessEpoch: number;\n accessStateHash: string;\n containerId: string;\n documentId: string;\n documentState: ProvisionedContainerBootstrapInput[\"metadataState\"];\n initialUpdate: Uint8Array;\n initialUpdateCommitted: boolean;\n localId: string;\n}\n\nexport interface RegistrationBootstrapInput {\n acknowledgedAccessHeads: readonly LocallyAcknowledgedAccessManifestHead[];\n /** Seeded documents' acknowledged signed heads; see the discovery cache. */\n authoredDiscoveryHeads: readonly AuthoredDiscoveryHead[];\n /** Checked inside the mutation queue claim; false skips every write. */\n canStartDurableMutation?: (() => boolean) | undefined;\n /**\n * @internal Test-only synchronization seam. Invoked synchronously,\n * immediately before this persist joins the serialized mutation queue —\n * no interleaving can separate the two. Lets identity-race tests\n * deterministically place an identity replacement inside the queue-wait\n * window instead of sleeping.\n */\n onPersistQueued?: (() => void) | undefined;\n containerId: string;\n initialAdminGroupPolicy: PrincipalPolicyBundleResponse;\n initialMemberGroupPolicy: PrincipalPolicyBundleResponse;\n initialOrganizationPolicy: PrincipalPolicyBundleResponse;\n rootMetadataAccessEpoch: number;\n rootMetadataAccessStateHash: string;\n rootContainerServerTimestamp: string;\n rootMetadataDocumentId: string;\n rootMetadataInitialUpdate: Uint8Array;\n rootMetadataInitialUpdateCommitted?: boolean | undefined;\n rootMetadataSnapshot: string;\n rootMetadataState: ProvisionedContainerBootstrapInput[\"metadataState\"];\n rosterProfileContainer?: ProvisionedContainerBootstrapInput & {\n metadataInitialUpdate: Uint8Array;\n metadataInitialUpdateCommitted?: boolean | undefined;\n };\n organizationMetadataContainer?: ProvisionedContainerBootstrapInput & {\n metadataInitialUpdate: Uint8Array;\n metadataInitialUpdateCommitted?: boolean | undefined;\n };\n organizationProfileDocument?: ProvisionedProfileDocumentBootstrapInput;\n rosterProfileDocument?: ProvisionedProfileDocumentBootstrapInput;\n // Additional app-owned system containers provisioned with the organization\n // (e.g. a trash bin). Each carries its own display name and icon (unlike the\n // roster/organization-metadata containers, whose names are fixed), since the\n // caller declares them.\n systemContainers?: Array<\n ProvisionedContainerBootstrapInput & {\n icon: string | null;\n name: string;\n }\n >;\n documentProjectors?: DocumentProjectorRegistryInput | undefined;\n organizationId: string;\n userId: string;\n}\nasync function persistProvisionedContainerBootstrap(\n execSql: ExecSql,\n input: {\n container: ProvisionedContainerBootstrapInput;\n icon: string | null;\n name: string;\n organizationId: string;\n parentId: string | null;\n },\n): Promise<void> {\n const { container } = input;\n const metadataState = container.metadataState;\n const record: ContainerMetadataRecord = {\n accessEpoch: container.accessEpoch,\n accessStateHash: container.accessStateHash,\n documentId: container.metadataDocumentId,\n id: container.containerId,\n lastCommitLsn: null,\n metadataUpdates: container.metadataSnapshot,\n snapshotEndVersion: \"\",\n contentKeyBundle: metadataState.contentKeyBundle ?? null,\n documentKekTargets: metadataState.documentKekTargets ?? null,\n documentManifestBundle: metadataState.documentManifestBundle ?? null,\n };\n await sqlContainerContentsPersistence.saveContainer(\n execSql,\n {\n id: container.containerId,\n effectiveAccessLevel: \"admin\",\n organizationId: input.organizationId,\n parentId: input.parentId,\n metadataDocumentId: container.metadataDocumentId,\n systemSlot: container.systemSlot,\n name: input.name,\n icon: input.icon,\n },\n record,\n {\n localUpdatedAt: container.updatedAt,\n serverTimestamps: {\n createdAt: container.createdAt,\n updatedAt: container.updatedAt,\n },\n },\n );\n}\n\nasync function persistRootContainerBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n): Promise<void> {\n const rootRecord: ContainerMetadataRecord = {\n accessEpoch: input.rootMetadataAccessEpoch,\n accessStateHash: input.rootMetadataAccessStateHash,\n documentId: input.rootMetadataDocumentId,\n id: input.containerId,\n lastCommitLsn: null,\n metadataUpdates: input.rootMetadataSnapshot,\n snapshotEndVersion: \"\",\n contentKeyBundle: input.rootMetadataState.contentKeyBundle ?? null,\n documentKekTargets: input.rootMetadataState.documentKekTargets ?? null,\n documentManifestBundle:\n input.rootMetadataState.documentManifestBundle ?? null,\n };\n await sqlContainerContentsPersistence.saveContainer(\n execSql,\n {\n id: input.containerId,\n effectiveAccessLevel: \"admin\",\n organizationId: input.organizationId,\n parentId: null,\n metadataDocumentId: input.rootMetadataDocumentId,\n name: \"/\",\n icon: null,\n },\n rootRecord,\n {\n localUpdatedAt: input.rootContainerServerTimestamp,\n serverTimestamps: {\n createdAt: input.rootContainerServerTimestamp,\n updatedAt: input.rootContainerServerTimestamp,\n },\n },\n );\n await enqueueInitialContainerMetadataUpdate(\n execSql,\n input.containerId,\n input.rootMetadataInitialUpdate,\n input.rootMetadataInitialUpdateCommitted,\n );\n}\n\n// Persist reserved profile containers using their fixed topology: roster profiles\n// inherit the personal root; shared organization metadata has an independent root.\nasync function persistNamedChildContainerBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n container: RegistrationBootstrapInput[\"rosterProfileContainer\"],\n name: string,\n): Promise<void> {\n if (!container) {\n return;\n }\n\n await persistProvisionedContainerBootstrap(execSql, {\n container,\n icon: null,\n name,\n organizationId: input.organizationId,\n parentId:\n container === input.organizationMetadataContainer\n ? null\n : input.containerId,\n });\n await enqueueInitialContainerMetadataUpdate(\n execSql,\n container.containerId,\n container.metadataInitialUpdate,\n container.metadataInitialUpdateCommitted,\n );\n}\n\nasync function persistSystemContainersBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n): Promise<void> {\n const systemContainers = input.systemContainers;\n if (!systemContainers) {\n return;\n }\n\n for (const systemContainer of systemContainers) {\n await persistProvisionedContainerBootstrap(execSql, {\n container: systemContainer,\n icon: systemContainer.icon,\n name: systemContainer.name,\n organizationId: input.organizationId,\n parentId: input.containerId,\n });\n // Provisioned system-container metadata is already committed remotely in\n // the organization transaction. Persist the initialized snapshot locally,\n // but do not queue a duplicate write with a second update id.\n }\n}\n\n// The ONE persist shape for the provisioned profile documents (organization\n// profile and roster profile): the input carries exactly the bootstrap\n// fields, so only the document kind and the host's projectors join it.\nasync function persistProfileDocumentBootstrap(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n profileDocument: ProvisionedProfileDocumentBootstrapInput | undefined,\n documentKind: string,\n): Promise<void> {\n if (!profileDocument) {\n return;\n }\n\n await persistInitialDocumentBootstrap(execSql, {\n ...profileDocument,\n documentKind,\n documentProjectors: input.documentProjectors,\n });\n}\n\nexport async function persistInitialDocumentBootstrap(\n execSql: ExecSql,\n input: {\n accessEpoch: number;\n accessStateHash: string;\n containerId: string;\n documentId: string;\n documentKind: string;\n documentProjectors: DocumentProjectorRegistryInput | undefined;\n documentState: Pick<\n DocumentRecord,\n \"contentKeyBundle\" | \"documentKekTargets\" | \"documentManifestBundle\"\n >;\n initialUpdate: Uint8Array;\n initialUpdateCommitted: boolean;\n localId: string;\n },\n): Promise<void> {\n const doc = await createDocument(await getScopedPeerSeed(DOCUMENTS_APP_KIND));\n importUpdates(doc, [input.initialUpdate]);\n const pendingUpdate = input.initialUpdateCommitted\n ? undefined\n : (createPendingUpdateFields(input.initialUpdate) ?? undefined);\n\n await persistDocumentState({\n currentDoc: doc,\n currentRecord: null,\n documentProjectors: input.documentProjectors ?? [],\n execSql,\n localId: input.localId,\n patch: {\n accessEpoch: input.accessEpoch,\n accessStateHash: input.accessStateHash,\n containerId: input.containerId,\n contentKeyBundle: input.documentState.contentKeyBundle ?? null,\n documentId: input.documentId,\n // Successful provisioning makes this device's user the founding admin.\n // Stores can open before discovery returns the same access level.\n effectiveAccessLevel: \"admin\",\n documentKekTargets: input.documentState.documentKekTargets ?? null,\n documentKind: input.documentKind,\n documentManifestBundle:\n input.documentState.documentManifestBundle ?? null,\n // The create-only persistence primitive stores this frontier and the\n // full-history checkpoint in one transaction.\n snapshotEndVersion: encodeVersionVector(doc),\n },\n pendingUpdate,\n persistence: sqlDocumentsPersistence,\n });\n}\n\n/**\n * Persists the local root-container bootstrap created during successful\n * registration so container contents can initialize from SQLite on first\n * login — atomically: every write lands inside ONE transaction whose last\n * act re-checks identity currency, so an identity replaced anywhere between\n * the queue claim and the commit rolls the entire bootstrap back instead of\n * leaving a partial one. Resolves false when either currency check rejected\n * the write, so callers do not report a bootstrap that was never persisted.\n */\nexport async function persistRegistrationBootstrapFromExecSql(\n execSql: ExecSql,\n input: RegistrationBootstrapInput,\n): Promise<boolean> {\n input.onPersistQueued?.();\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n // In-mutex currency check, adjacent to the serialized-mutation claim\n // (see persistDocumentState): the identity can be replaced while this\n // persist waits for the queue, and its bootstrap must not be written\n // through a client the replacement closed or renewed.\n if (input.canStartDurableMutation && !input.canStartDurableMutation()) {\n return false;\n }\n // Idempotent DDL stays outside the atomic boundary.\n await sqlContainerContentsPersistence.ensureSchema(lockedExecSql);\n await sqlDocumentsPersistence.ensureSchema(lockedExecSql);\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n // Pre-commit currency guard: the write sequence awaits real work, so\n // the identity can be replaced mid-sequence. The guard runs\n // synchronously with the COMMIT dispatch, so a refusal rolls the whole\n // write set back and a pass cannot go stale before the commit is sent —\n // the partial-persist window a single entry check leaves open.\n const { committed } = await getClientSQLitePersistenceRuntime(\n lockedExecSql,\n ).guardedTransaction(\n async () => {\n await advanceLocallyAcknowledgedAccessManifestHeadsAtomically({\n execSql: lockedExecSql,\n heads: input.acknowledgedAccessHeads,\n });\n await persistRegistrationPrincipalPolicies({\n adminGroup: input.initialAdminGroupPolicy,\n execSql: lockedExecSql,\n memberGroup: input.initialMemberGroupPolicy,\n organization: input.initialOrganizationPolicy,\n });\n await persistRootContainerBootstrap(lockedExecSql, input);\n await persistNamedChildContainerBootstrap(\n lockedExecSql,\n input,\n input.rosterProfileContainer,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n );\n await persistProfileDocumentBootstrap(\n lockedExecSql,\n input,\n input.rosterProfileDocument,\n ROSTER_PROFILE_DOCUMENT_KIND,\n );\n await persistNamedChildContainerBootstrap(\n lockedExecSql,\n input,\n input.organizationMetadataContainer,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n );\n await persistProfileDocumentBootstrap(\n lockedExecSql,\n input,\n input.organizationProfileDocument,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n );\n await persistSystemContainersBootstrap(lockedExecSql, input);\n // After the checkpoints above: discovery reuses a cached head only\n // while its access-manifest checkpoint still matches.\n await primeAuthoredDocumentDiscoveryHeads(\n lockedExecSql,\n input.authoredDiscoveryHeads,\n );\n },\n () => !input.canStartDurableMutation || input.canStartDurableMutation(),\n );\n return committed;\n });\n}\n\nexport async function persistRegistrationBootstrap(\n client: ExecSqlClientLike,\n input: RegistrationBootstrapInput,\n): Promise<void> {\n await persistRegistrationBootstrapFromExecSql(createExecSql(client), input);\n}\n"]}
@@ -1,247 +1,78 @@
1
- import { and, eq, inArray, or } from "drizzle-orm";
2
- import { deleteDocumentPlacementRowsByContainerIds, deleteDocumentPlacementRowsByDocumentIds, } from "../../data/persistence/container-contents/documentContainerProjectionPersistence.js";
3
- import { recordSupersededContainerBindingsInTransaction } from "../../data/persistence/container-contents/supersededContainerBindings.js";
4
- import { clearDocumentDiscoveryEvidenceOnRemoteReset } from "../../data/persistence/documents/documentDiscoveryReset.js";
5
- import { queuedUpdateRow, unqueueDocumentScopesInTransaction, } from "../../data/sqlite/documentPersistence/documentPendingUpdatePersistence.js";
6
- import { CLEARED_DOCUMENT_SYNC_FAILURE } from "../../data/sqlite/documentPersistence/documentSyncFailurePersistence.js";
7
- import { clientSqlTables, containerHydrationTombstones, containers, documentAttachmentBlobProjection, documentHistoryUpdates, documentPendingAttachments, documentProjection, documents, dormantContainerMetadata, dormantMetadataSweepRequests, inContainerIntentLanes, inLocalIntentLane, LOCAL_INTENT_LANES, localIntents, } from "../../data/sqlite/schema/index.js";
8
- import { documentIntentLinkTargets } from "../../data/sqlite/schema/documentPlacementIntentSchema.js";
9
- import { organizationDataUsageSnapshots } from "../../data/sqlite/schema/organizationDataUsageSchema.js";
10
- import { organizationPresentationDenials, organizationReadModelContainerGrants, organizationReadModelDirectoryUsers, organizationReadModelGroupMembers, organizationReadModelGroups, organizationReadModelRequesters, organizationReadModelState, } from "../../data/sqlite/schema/organizationReadModelSchema.js";
11
- import { verifiedAccessManifestBundles } from "../../data/sqlite/schema/verifiedManifestBundleSchema.js";
1
+ import { clearRemoteResetPrincipalRows } from "../../data/persistence/principalPolicy/principalPolicyRemoteReset.js";
2
+ import { deleteVerifiedManifestBundlesForOrganization } from "../../data/persistence/verifiedManifestBundlePersistence.js";
3
+ import { clientSqlTables } from "../../data/sqlite/schema/index.js";
12
4
  import { getClientSQLitePersistenceRuntime, } from "../../data/sqlite/sqlitePersistenceRuntime.js";
13
5
  import { ensureSqlTables } from "../../data/sqlite/sqlTableSchema.js";
14
- import { runOrganizationPresentationReset } from "../organizations/readModel/organizationPresentationAccessState.js";
15
- import { clearResetPendingAttachments } from "./remoteResetAttachments.js";
16
- import { remoteResetBatches } from "./remoteResetBatches.js";
17
- import { clearRemoteResetSyncCursors } from "./remoteResetCursorScope.js";
18
- import { buildResetPlans, } from "./remoteResetPlans.js";
19
- import { clearRemoteResetPrincipalRows } from "./remoteResetPrincipalScope.js";
6
+ import { clearContainerRowsForRemoteReset, clearDocumentPlacementsForRemoteReset, clearDormantContainerMetadataForRemoteReset, clearRemoteResetSyncCursors, queueContainerCreatesForRemoteReset, resetContainerServerIdentity, } from "../container-contents/remoteReset/containerRemoteReset.js";
7
+ import { buildResetPlans, clearDocumentDiscoveryEvidenceOnRemoteReset, clearDocumentRowsForRemoteReset, queueAttachmentReuploadsForRemoteReset, queueDocumentRepublishForRemoteReset, resetDocumentServerIdentity, } from "../documents/remoteReset/documentRemoteReset.js";
8
+ import { clearOrganizationReadModelsForRemoteReset, runOrganizationPresentationReset, } from "../organizations/readModel/organizationRemoteReset.js";
20
9
  import { readRemoteSyncStateSnapshot, } from "./remoteResetScope.js";
21
- const CONTAINER_CREATE_INTENT_TYPE = "container.create";
22
- async function clearOrganizationPresentationRows(tx, organizationId) {
23
- for (const table of [
24
- organizationDataUsageSnapshots,
25
- organizationReadModelContainerGrants,
26
- organizationReadModelGroupMembers,
27
- organizationReadModelDirectoryUsers,
28
- organizationReadModelGroups,
29
- organizationReadModelRequesters,
30
- organizationReadModelState,
31
- organizationPresentationDenials,
32
- ]) {
33
- await tx
34
- .delete(table)
35
- .where(eq(table.organizationId, organizationId))
36
- .run();
37
- }
38
- }
39
- async function clearScopedContainerRows(input) {
40
- for (const containerBatch of remoteResetBatches(input.snapshot.containerIds)) {
41
- await deleteDocumentPlacementRowsByContainerIds(input.tx, containerBatch);
42
- await input.tx
43
- .delete(localIntents)
44
- .where(and(inContainerIntentLanes(), inArray(localIntents.subjectId, containerBatch)))
45
- .run();
46
- await input.tx
47
- .delete(containerHydrationTombstones)
48
- .where(inArray(containerHydrationTombstones.containerId, containerBatch))
49
- .run();
50
- }
51
- }
52
- async function clearScopedDocumentRows(input) {
53
- const { snapshot, tx } = input;
54
- for (const documentIdBatch of remoteResetBatches(snapshot.oldDocumentIds)) {
55
- await deleteDocumentPlacementRowsByDocumentIds(tx, documentIdBatch);
56
- }
57
- await clearResetPendingAttachments({
58
- attachmentUploads: input.attachmentUploads,
10
+ // Each subsystem resets its own tables; this runs their steps in one
11
+ // transaction. Steps on different tables are independent, and each subsystem
12
+ // clears its rows before it queues new ones.
13
+ async function clearRemoteSyncStateInTransaction(input) {
14
+ const now = new Date().toISOString();
15
+ const { plans, reset, snapshot, tx } = input;
16
+ const { organizationId } = reset;
17
+ // Forget what the server told this device about the organization.
18
+ await clearOrganizationReadModelsForRemoteReset(tx, organizationId);
19
+ await clearDormantContainerMetadataForRemoteReset(tx, organizationId);
20
+ await deleteVerifiedManifestBundlesForOrganization(tx, organizationId);
21
+ await clearDocumentDiscoveryEvidenceOnRemoteReset(tx, {
22
+ containerIds: snapshot.containerIds,
23
+ documentIds: snapshot.oldDocumentIds,
24
+ });
25
+ await clearRemoteResetPrincipalRows({ organizationId, snapshot, tx });
26
+ await clearContainerRowsForRemoteReset({
27
+ containerIds: snapshot.containerIds,
28
+ tx,
29
+ });
30
+ await clearDocumentPlacementsForRemoteReset({
59
31
  documentLocalIds: snapshot.documentLocalIds,
32
+ oldDocumentIds: snapshot.oldDocumentIds,
60
33
  tx,
61
34
  });
62
- for (const localIdBatch of remoteResetBatches(snapshot.documentLocalIds)) {
63
- const placementIntents = and(inLocalIntentLane(LOCAL_INTENT_LANES.documentPlacement), inArray(localIntents.localId, localIdBatch));
64
- await tx
65
- .delete(documentIntentLinkTargets)
66
- .where(inArray(documentIntentLinkTargets.intentId, tx
67
- .select({ id: localIntents.id })
68
- .from(localIntents)
69
- .where(placementIntents)))
70
- .run();
71
- await tx.delete(localIntents).where(placementIntents).run();
72
- }
73
- // Sync failures clear with the document columns in resetRemoteColumns.
74
- for (const documentBatch of remoteResetBatches(snapshot.documentRows)) {
75
- await unqueueDocumentScopesInTransaction(tx, documentBatch);
76
- }
77
- }
78
- async function clearScopedRemoteRows(input) {
79
- const { organizationId, tx } = input;
80
- await clearOrganizationPresentationRows(tx, organizationId);
81
- for (const table of [
82
- dormantContainerMetadata,
83
- dormantMetadataSweepRequests,
84
- verifiedAccessManifestBundles,
85
- ]) {
86
- await tx
87
- .delete(table)
88
- .where(eq(table.organizationId, organizationId))
89
- .run();
90
- }
91
- await clearDocumentDiscoveryEvidenceOnRemoteReset(tx, {
92
- containerIds: input.snapshot.containerIds,
93
- documentIds: input.snapshot.oldDocumentIds,
35
+ await clearDocumentRowsForRemoteReset({
36
+ attachmentUploads: plans.attachmentUploads,
37
+ documentLocalIds: snapshot.documentLocalIds,
38
+ documentRows: snapshot.documentRows,
39
+ tx,
94
40
  });
95
- await clearRemoteResetPrincipalRows(input);
96
- await clearScopedContainerRows(input);
97
- await clearScopedDocumentRows(input);
98
41
  await clearRemoteResetSyncCursors({
99
- containerIds: input.snapshot.containerIds,
42
+ containerIds: snapshot.containerIds,
100
43
  tx,
101
44
  });
102
- }
103
- async function resetRemoteColumns(input) {
104
- const { now, reset, snapshot, tx } = input;
105
- for (const row of snapshot.documentRows) {
106
- await tx
107
- .update(documents)
108
- .set({
109
- accessEpoch: 1,
110
- accessStateHash: null,
111
- contentKeyBundle: null,
112
- documentId: null,
113
- documentKekTargets: null,
114
- documentManifestBundle: null,
115
- lastCommitLsn: null,
116
- pullContinuation: null,
117
- recoveryDocumentId: row.documentId ?? row.recoveryDocumentId,
118
- ...CLEARED_DOCUMENT_SYNC_FAILURE,
119
- updatedAt: now,
120
- })
121
- .where(and(eq(documents.appKind, row.appKind), eq(documents.localId, row.localId)))
122
- .run();
123
- }
124
- for (const localIdBatch of remoteResetBatches(snapshot.documentLocalIds)) {
125
- await tx
126
- .update(documentProjection)
127
- .set({
128
- documentId: null,
129
- organizationId: reset.replacement?.organizationId ?? reset.organizationId,
130
- })
131
- .where(inArray(documentProjection.localId, localIdBatch))
132
- .run();
133
- }
134
- // Replacement re-homes folders under their ids; the purged organization
135
- // can never bind them again on this device.
136
- for (const containerIds of reset.replacement
137
- ? remoteResetBatches(snapshot.containerIds)
138
- : []) {
139
- await recordSupersededContainerBindingsInTransaction(tx, {
140
- containerIds,
141
- organizationId: reset.organizationId,
142
- supersededAt: now,
143
- });
144
- }
145
- for (const row of snapshot.containerRows) {
146
- await tx
147
- .update(containers)
148
- .set({
149
- metadataDocumentId: null,
150
- organizationId: reset.replacement?.organizationId ?? reset.organizationId,
151
- parentId: reset.replacement && row.parentId === null
152
- ? reset.replacement.rootContainerId
153
- : row.parentId,
154
- serverCreatedAt: null,
155
- serverUpdatedAt: null,
156
- ...(reset.replacement ? { systemSlot: null } : {}),
157
- localUpdatedAt: now,
158
- })
159
- .where(eq(containers.id, row.id))
160
- .run();
161
- }
162
- }
163
- async function queueResetDocumentUpdates(input) {
164
- for (const updateBatch of remoteResetBatches(input.documentUpdates)) {
165
- await input.tx
166
- .insert(documentHistoryUpdates)
167
- .values(updateBatch.map((update) => queuedUpdateRow({
168
- createdAt: input.now,
169
- origin: "outbox",
170
- pendingUpdate: update,
171
- scope: update,
172
- updateId: crypto.randomUUID(),
173
- })))
174
- .run();
175
- }
176
- }
177
- async function queueResetContainerCreates(input) {
178
- const rows = input.snapshot.containerRows.flatMap((row) => {
179
- const parentId = row.parentId ?? input.reset.replacement?.rootContainerId ?? null;
180
- return parentId ? [{ id: row.id, parentId }] : [];
45
+ // Strip server identity from the rows the device keeps.
46
+ await resetDocumentServerIdentity({
47
+ documentLocalIds: snapshot.documentLocalIds,
48
+ documentRows: snapshot.documentRows,
49
+ now,
50
+ organizationId: reset.replacement?.organizationId ?? organizationId,
51
+ tx,
181
52
  });
182
- if (rows.length === 0)
183
- return 0;
184
- for (const rowBatch of remoteResetBatches(rows)) {
185
- await input.tx
186
- .insert(localIntents)
187
- .values(rowBatch.map((row) => ({
188
- id: crypto.randomUUID(),
189
- lane: LOCAL_INTENT_LANES.containerCreate,
190
- subjectId: row.id,
191
- targetContainerId: row.parentId,
192
- intentType: CONTAINER_CREATE_INTENT_TYPE,
193
- syncStatus: "pending",
194
- remoteContainerId: null,
195
- remoteMetadataAccessStateHash: null,
196
- remoteMetadataDocumentId: null,
197
- lastError: null,
198
- createdAt: input.now,
199
- updatedAt: input.now,
200
- })))
201
- .run();
202
- }
203
- return rows.length;
204
- }
205
- async function queueResetAttachmentUploads(input) {
206
- for (const attachmentBatch of remoteResetBatches(input.attachmentUploads)) {
207
- await input.tx
208
- .insert(documentPendingAttachments)
209
- .values(attachmentBatch.map((attachment) => ({
210
- ...attachment,
211
- createdAt: input.now,
212
- })))
213
- .run();
214
- await input.tx
215
- .delete(documentAttachmentBlobProjection)
216
- .where(or(...attachmentBatch.map((attachment) => and(eq(documentAttachmentBlobProjection.localId, attachment.localId), eq(documentAttachmentBlobProjection.slotId, attachment.slotId)))))
217
- .run();
218
- }
219
- }
220
- async function clearRemoteSyncStateInTransaction(input) {
221
- const now = new Date().toISOString();
222
- const { snapshot } = input;
223
- await clearScopedRemoteRows({
224
- attachmentUploads: input.plans.attachmentUploads,
225
- organizationId: input.reset.organizationId,
226
- snapshot,
227
- tx: input.tx,
53
+ await resetContainerServerIdentity({
54
+ containerIds: snapshot.containerIds,
55
+ containerRows: snapshot.containerRows,
56
+ now,
57
+ reset,
58
+ tx,
228
59
  });
229
- await resetRemoteColumns({ now, reset: input.reset, snapshot, tx: input.tx });
230
- await queueResetDocumentUpdates({
231
- documentUpdates: input.plans.documentUpdates,
60
+ // Queue the local content to be published again.
61
+ await queueDocumentRepublishForRemoteReset({
62
+ documentUpdates: plans.documentUpdates,
232
63
  now,
233
- tx: input.tx,
64
+ tx,
234
65
  });
235
- const queuedContainerCreateCount = await queueResetContainerCreates({
66
+ const queuedContainerCreateCount = await queueContainerCreatesForRemoteReset({
67
+ containerRows: snapshot.containerRows,
236
68
  now,
237
- reset: input.reset,
238
- snapshot,
239
- tx: input.tx,
69
+ reset,
70
+ tx,
240
71
  });
241
- await queueResetAttachmentUploads({
242
- attachmentUploads: input.plans.attachmentUploads,
72
+ await queueAttachmentReuploadsForRemoteReset({
73
+ attachmentUploads: plans.attachmentUploads,
243
74
  now,
244
- tx: input.tx,
75
+ tx,
245
76
  });
246
77
  return {
247
78
  clearedContainerCreateIntentCount: snapshot.clearedContainerCreateIntentCount,
@@ -249,9 +80,9 @@ async function clearRemoteSyncStateInTransaction(input) {
249
80
  clearedDocumentMoveIntentCount: snapshot.clearedDocumentMoveIntentCount,
250
81
  clearedPrincipalPolicyCount: snapshot.clearedPrincipalPolicyCount,
251
82
  clearedSyncCursorCount: snapshot.clearedSyncCursorCount,
252
- queuedAttachmentUploadCount: input.plans.attachmentUploads.length,
83
+ queuedAttachmentUploadCount: plans.attachmentUploads.length,
253
84
  queuedContainerCreateCount,
254
- queuedDocumentUpdateCount: input.plans.documentUpdates.length,
85
+ queuedDocumentUpdateCount: plans.documentUpdates.length,
255
86
  resetContainerCount: snapshot.containerRows.length,
256
87
  resetDocumentCount: snapshot.documentRows.length,
257
88
  };