@tearleads/client-sdk 0.1.84 → 0.1.86

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 (36) hide show
  1. package/data/persistence/container-contents/containerDocumentReassignment.js +7 -9
  2. package/data/persistence/container-contents/containerDocumentReassignment.js.map +1 -1
  3. package/data/persistence/container-contents/containerMetadataRows.js +3 -19
  4. package/data/persistence/container-contents/containerMetadataRows.js.map +1 -1
  5. package/data/persistence/container-contents/containerRebindPersistence.js +4 -17
  6. package/data/persistence/container-contents/containerRebindPersistence.js.map +1 -1
  7. package/data/persistence/container-contents/containerStructuralRepair.js +5 -11
  8. package/data/persistence/container-contents/containerStructuralRepair.js.map +1 -1
  9. package/data/persistence/container-contents/documentContainerProjectionPersistence.js +34 -9
  10. package/data/persistence/container-contents/documentContainerProjectionPersistence.js.map +1 -1
  11. package/data/persistence/container-contents/dormantContainerMetadata.js +4 -14
  12. package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
  13. package/data/persistence/documents/documentDiscoveryEvidencePersistence.js +5 -9
  14. package/data/persistence/documents/documentDiscoveryEvidencePersistence.js.map +1 -1
  15. package/data/persistence/documents/documentProjectionContainers.js +28 -0
  16. package/data/persistence/documents/documentProjectionContainers.js.map +1 -0
  17. package/data/persistence/documents/documentsPersistence.js +3 -7
  18. package/data/persistence/documents/documentsPersistence.js.map +1 -1
  19. package/data/persistence/documents/internal/containerDocumentTombstones.js +4 -11
  20. package/data/persistence/documents/internal/containerDocumentTombstones.js.map +1 -1
  21. package/data/persistence/documents/internal/documentDeletionPersistence.js +6 -20
  22. package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
  23. package/data/persistence/documents/records/documentRowsInTransaction.js +68 -0
  24. package/data/persistence/documents/records/documentRowsInTransaction.js.map +1 -0
  25. package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.d.ts +2 -0
  26. package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js +9 -0
  27. package/data/persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js.map +1 -1
  28. package/data/persistence/keyingCheckpoints/keyingCheckpointPersistence.js +9 -0
  29. package/data/persistence/keyingCheckpoints/keyingCheckpointPersistence.js.map +1 -1
  30. package/data/persistence/principalPolicy/principalPolicyPersistence.js +3 -9
  31. package/data/persistence/principalPolicy/principalPolicyPersistence.js.map +1 -1
  32. package/data/persistence/principalPolicy/principalPolicyRemoteReset.js +10 -7
  33. package/data/persistence/principalPolicy/principalPolicyRemoteReset.js.map +1 -1
  34. package/package.json +3 -3
  35. package/sqlite/sqlite3.wasm +0 -0
  36. package/sqlite/worker.js +4 -4
@@ -7,4 +7,6 @@ export interface DocumentPurgeCheckpoint {
7
7
  readonly purgeEventHash: string;
8
8
  }
9
9
  export declare function loadDocumentPurgeCheckpoint(execSql: ExecSql, documentId: string): Promise<DocumentPurgeCheckpoint | null>;
10
+ /** Whether the document was permanently purged, read in the caller's transaction. */
11
+ export declare function hasDocumentPurgeCheckpointInTransaction(tx: ClientSQLiteTransactionScope, documentId: string): Promise<boolean>;
10
12
  export declare function storeDocumentPurgeCheckpointInTransaction(tx: ClientSQLiteTransactionScope, checkpoint: DocumentPurgeCheckpoint, updatedAt: string): Promise<void>;
@@ -17,6 +17,15 @@ export async function loadDocumentPurgeCheckpoint(execSql, documentId) {
17
17
  .limit(1);
18
18
  return row ?? null;
19
19
  }
20
+ /** Whether the document was permanently purged, read in the caller's transaction. */
21
+ export async function hasDocumentPurgeCheckpointInTransaction(tx, documentId) {
22
+ const [row] = await tx
23
+ .select({ documentId: documentPurgeCheckpoints.documentId })
24
+ .from(documentPurgeCheckpoints)
25
+ .where(eq(documentPurgeCheckpoints.documentId, documentId))
26
+ .limit(1);
27
+ return row !== undefined;
28
+ }
20
29
  export async function storeDocumentPurgeCheckpointInTransaction(tx, checkpoint, updatedAt) {
21
30
  const [stored] = await tx
22
31
  .select({
@@ -1 +1 @@
1
- {"version":3,"file":"documentPurgeCheckpointPersistence.js","sourceRoot":"","sources":["documentPurgeCheckpointPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAgB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AASvE,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAgB,EAChB,UAAkB;IAElB,MAAM,eAAe,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,iCAAiC,CAAC,OAAO,CAAC;SAC3D,EAAE,CAAC,MAAM,CAAC;QACT,UAAU,EAAE,wBAAwB,CAAC,UAAU;QAC/C,oBAAoB,EAAE,wBAAwB,CAAC,oBAAoB;QACnE,cAAc,EAAE,wBAAwB,CAAC,cAAc;QACvD,cAAc,EAAE,wBAAwB,CAAC,cAAc;KACxD,CAAC;SACD,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;SAC1D,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yCAAyC,CAC7D,EAAgC,EAChC,UAAmC,EACnC,SAAiB;IAEjB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;SACtB,MAAM,CAAC;QACN,oBAAoB,EAAE,wBAAwB,CAAC,oBAAoB;QACnE,cAAc,EAAE,wBAAwB,CAAC,cAAc;QACvD,cAAc,EAAE,wBAAwB,CAAC,cAAc;KACxD,CAAC;SACD,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;SACrE,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,MAAM,EAAE,CAAC;QACX,IACE,MAAM,CAAC,oBAAoB,KAAK,UAAU,CAAC,oBAAoB;YAC/D,MAAM,CAAC,cAAc,KAAK,UAAU,CAAC,cAAc;YACnD,MAAM,CAAC,cAAc,KAAK,UAAU,CAAC,cAAc,EACnD,CAAC;YACD,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,sEAAsE,CACvE,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IACD,MAAM,EAAE;SACL,MAAM,CAAC,wBAAwB,CAAC;SAChC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,CAAC;SACpC,GAAG,EAAE,CAAC;AACX,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { eq } from \"drizzle-orm\";\nimport {\n documentPurgeCheckpoints,\n keyingCheckpointTables,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\n\nexport interface DocumentPurgeCheckpoint {\n readonly documentId: string;\n readonly documentManifestHash: string;\n readonly organizationId: string;\n readonly purgeEventHash: string;\n}\n\nexport async function loadDocumentPurgeCheckpoint(\n execSql: ExecSql,\n documentId: string,\n): Promise<DocumentPurgeCheckpoint | null> {\n await ensureSqlTables(execSql, keyingCheckpointTables);\n const [row] = await getClientSQLitePersistenceRuntime(execSql)\n .db.select({\n documentId: documentPurgeCheckpoints.documentId,\n documentManifestHash: documentPurgeCheckpoints.documentManifestHash,\n organizationId: documentPurgeCheckpoints.organizationId,\n purgeEventHash: documentPurgeCheckpoints.purgeEventHash,\n })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, documentId))\n .limit(1);\n return row ?? null;\n}\n\nexport async function storeDocumentPurgeCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n checkpoint: DocumentPurgeCheckpoint,\n updatedAt: string,\n): Promise<void> {\n const [stored] = await tx\n .select({\n documentManifestHash: documentPurgeCheckpoints.documentManifestHash,\n organizationId: documentPurgeCheckpoints.organizationId,\n purgeEventHash: documentPurgeCheckpoints.purgeEventHash,\n })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, checkpoint.documentId))\n .limit(1);\n if (stored) {\n if (\n stored.documentManifestHash !== checkpoint.documentManifestHash ||\n stored.organizationId !== checkpoint.organizationId ||\n stored.purgeEventHash !== checkpoint.purgeEventHash\n ) {\n throw new KeyingVerificationError(\n \"equivocation\",\n \"Document purge checkpoint conflicts with the verified terminal event\",\n );\n }\n return;\n }\n await tx\n .insert(documentPurgeCheckpoints)\n .values({ ...checkpoint, updatedAt })\n .run();\n}\n"]}
1
+ {"version":3,"file":"documentPurgeCheckpointPersistence.js","sourceRoot":"","sources":["documentPurgeCheckpointPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAgB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AASvE,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAgB,EAChB,UAAkB;IAElB,MAAM,eAAe,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,iCAAiC,CAAC,OAAO,CAAC;SAC3D,EAAE,CAAC,MAAM,CAAC;QACT,UAAU,EAAE,wBAAwB,CAAC,UAAU;QAC/C,oBAAoB,EAAE,wBAAwB,CAAC,oBAAoB;QACnE,cAAc,EAAE,wBAAwB,CAAC,cAAc;QACvD,cAAc,EAAE,wBAAwB,CAAC,cAAc;KACxD,CAAC;SACD,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;SAC1D,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,GAAG,IAAI,IAAI,CAAC;AACrB,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,uCAAuC,CAC3D,EAAgC,EAChC,UAAkB;IAElB,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;SACnB,MAAM,CAAC,EAAE,UAAU,EAAE,wBAAwB,CAAC,UAAU,EAAE,CAAC;SAC3D,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;SAC1D,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,GAAG,KAAK,SAAS,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yCAAyC,CAC7D,EAAgC,EAChC,UAAmC,EACnC,SAAiB;IAEjB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;SACtB,MAAM,CAAC;QACN,oBAAoB,EAAE,wBAAwB,CAAC,oBAAoB;QACnE,cAAc,EAAE,wBAAwB,CAAC,cAAc;QACvD,cAAc,EAAE,wBAAwB,CAAC,cAAc;KACxD,CAAC;SACD,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;SACrE,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,MAAM,EAAE,CAAC;QACX,IACE,MAAM,CAAC,oBAAoB,KAAK,UAAU,CAAC,oBAAoB;YAC/D,MAAM,CAAC,cAAc,KAAK,UAAU,CAAC,cAAc;YACnD,MAAM,CAAC,cAAc,KAAK,UAAU,CAAC,cAAc,EACnD,CAAC;YACD,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,sEAAsE,CACvE,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IACD,MAAM,EAAE;SACL,MAAM,CAAC,wBAAwB,CAAC;SAChC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,CAAC;SACpC,GAAG,EAAE,CAAC;AACX,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { eq } from \"drizzle-orm\";\nimport {\n documentPurgeCheckpoints,\n keyingCheckpointTables,\n} from \"../../sqlite/schema\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { getClientSQLitePersistenceRuntime } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\n\nexport interface DocumentPurgeCheckpoint {\n readonly documentId: string;\n readonly documentManifestHash: string;\n readonly organizationId: string;\n readonly purgeEventHash: string;\n}\n\nexport async function loadDocumentPurgeCheckpoint(\n execSql: ExecSql,\n documentId: string,\n): Promise<DocumentPurgeCheckpoint | null> {\n await ensureSqlTables(execSql, keyingCheckpointTables);\n const [row] = await getClientSQLitePersistenceRuntime(execSql)\n .db.select({\n documentId: documentPurgeCheckpoints.documentId,\n documentManifestHash: documentPurgeCheckpoints.documentManifestHash,\n organizationId: documentPurgeCheckpoints.organizationId,\n purgeEventHash: documentPurgeCheckpoints.purgeEventHash,\n })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, documentId))\n .limit(1);\n return row ?? null;\n}\n\n/** Whether the document was permanently purged, read in the caller's transaction. */\nexport async function hasDocumentPurgeCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n documentId: string,\n): Promise<boolean> {\n const [row] = await tx\n .select({ documentId: documentPurgeCheckpoints.documentId })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, documentId))\n .limit(1);\n return row !== undefined;\n}\n\nexport async function storeDocumentPurgeCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n checkpoint: DocumentPurgeCheckpoint,\n updatedAt: string,\n): Promise<void> {\n const [stored] = await tx\n .select({\n documentManifestHash: documentPurgeCheckpoints.documentManifestHash,\n organizationId: documentPurgeCheckpoints.organizationId,\n purgeEventHash: documentPurgeCheckpoints.purgeEventHash,\n })\n .from(documentPurgeCheckpoints)\n .where(eq(documentPurgeCheckpoints.documentId, checkpoint.documentId))\n .limit(1);\n if (stored) {\n if (\n stored.documentManifestHash !== checkpoint.documentManifestHash ||\n stored.organizationId !== checkpoint.organizationId ||\n stored.purgeEventHash !== checkpoint.purgeEventHash\n ) {\n throw new KeyingVerificationError(\n \"equivocation\",\n \"Document purge checkpoint conflicts with the verified terminal event\",\n );\n }\n return;\n }\n await tx\n .insert(documentPurgeCheckpoints)\n .values({ ...checkpoint, updatedAt })\n .run();\n}\n"]}
@@ -55,6 +55,15 @@ export async function loadStoredPrincipalPolicyCheckpoint(handle, identity) {
55
55
  }
56
56
  : null;
57
57
  }
58
+ /** Every principal with a durable policy checkpoint. */
59
+ export function listPrincipalPolicyCheckpointPrincipals(handle) {
60
+ return handle
61
+ .selectDistinct({
62
+ id: principalPolicyCheckpoints.principalId,
63
+ type: principalPolicyCheckpoints.principalType,
64
+ })
65
+ .from(principalPolicyCheckpoints);
66
+ }
58
67
  export async function upsertAccessManifestCheckpointInTransaction(tx, checkpoint, updatedAt) {
59
68
  const row = { ...checkpoint, updatedAt };
60
69
  await tx
@@ -1 +1 @@
1
- {"version":3,"file":"keyingCheckpointPersistence.js","sourceRoot":"","sources":["keyingCheckpointPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccessManifestCheckpoint,\n AccessObjectKind,\n ManagedPrincipalKind,\n PrincipalPolicyCheckpoint,\n} from \"@tearleads/crypto\";\nimport { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport {\n accessManifestCheckpoints,\n keyingCheckpointTables,\n principalPolicyCheckpoints,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteDatabase,\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\nimport { recordPrincipalPolicyOrganizationInTransaction } from \"../principalPolicy/principalPolicyOrganizationPersistence\";\n\ntype CheckpointHandle = ClientSQLiteDatabase | ClientSQLiteTransactionScope;\n\ntype AccessManifestCheckpointIdentity = Pick<\n AccessManifestCheckpoint,\n \"objectKind\" | \"organizationId\" | \"objectId\"\n>;\n\ntype PrincipalPolicyCheckpointIdentity = Pick<\n PrincipalPolicyCheckpoint,\n \"principalType\" | \"principalId\"\n>;\n\n/** One key format per checkpoint identity, shared by every batch validator. */\nexport function accessManifestObjectKey(\n identity: AccessManifestCheckpointIdentity,\n): string {\n return JSON.stringify([\n identity.objectKind,\n identity.organizationId,\n identity.objectId,\n ]);\n}\n\nexport function principalPolicyKey(\n identity: PrincipalPolicyCheckpointIdentity,\n): string {\n return JSON.stringify([identity.principalType, identity.principalId]);\n}\n\nasync function loadAccessManifestCheckpointRow(\n handle: CheckpointHandle,\n identity: AccessManifestCheckpointIdentity,\n): Promise<Pick<AccessManifestCheckpoint, \"epoch\" | \"manifestHash\"> | null> {\n const rows = await handle\n .select({\n epoch: accessManifestCheckpoints.epoch,\n manifestHash: accessManifestCheckpoints.manifestHash,\n })\n .from(accessManifestCheckpoints)\n .where(\n and(\n eq(accessManifestCheckpoints.objectKind, identity.objectKind),\n eq(accessManifestCheckpoints.organizationId, identity.organizationId),\n eq(accessManifestCheckpoints.objectId, identity.objectId),\n ),\n )\n .limit(1);\n return rows[0] ?? null;\n}\n\nasync function loadPrincipalPolicyCheckpointRow(\n handle: CheckpointHandle,\n identity: PrincipalPolicyCheckpointIdentity,\n): Promise<Pick<PrincipalPolicyCheckpoint, \"version\" | \"stateHash\"> | null> {\n const rows = await handle\n .select({\n version: principalPolicyCheckpoints.version,\n stateHash: principalPolicyCheckpoints.stateHash,\n })\n .from(principalPolicyCheckpoints)\n .where(\n and(\n eq(principalPolicyCheckpoints.principalType, identity.principalType),\n eq(principalPolicyCheckpoints.principalId, identity.principalId),\n ),\n )\n .limit(1);\n return rows[0] ?? null;\n}\n\n/**\n * A loaded checkpoint row merged back with the identity it was looked up by —\n * the full checkpoint shape every comparison consumes.\n */\nexport async function loadStoredAccessManifestCheckpoint(\n handle: CheckpointHandle,\n checkpoint: AccessManifestCheckpoint,\n): Promise<AccessManifestCheckpoint | null> {\n const row = await loadAccessManifestCheckpointRow(handle, checkpoint);\n return row ? { ...checkpoint, ...row } : null;\n}\n\nexport async function loadStoredPrincipalPolicyCheckpoint(\n handle: CheckpointHandle,\n identity: PrincipalPolicyCheckpointIdentity,\n): Promise<PrincipalPolicyCheckpoint | null> {\n const row = await loadPrincipalPolicyCheckpointRow(handle, identity);\n return row\n ? {\n principalType: identity.principalType,\n principalId: identity.principalId,\n ...row,\n }\n : null;\n}\n\nexport async function upsertAccessManifestCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n checkpoint: AccessManifestCheckpoint,\n updatedAt: string,\n): Promise<void> {\n const row = { ...checkpoint, updatedAt };\n await tx\n .insert(accessManifestCheckpoints)\n .values(row)\n .onConflictDoUpdate({\n target: [\n accessManifestCheckpoints.objectKind,\n accessManifestCheckpoints.organizationId,\n accessManifestCheckpoints.objectId,\n ],\n set: row,\n })\n .run();\n}\n\nexport async function upsertPrincipalPolicyCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n checkpoint: PrincipalPolicyCheckpoint,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n await recordPrincipalPolicyOrganizationInTransaction(tx, {\n organizationId,\n principalId: checkpoint.principalId,\n principalType: checkpoint.principalType,\n });\n const row = { ...checkpoint, updatedAt };\n await tx\n .insert(principalPolicyCheckpoints)\n .values(row)\n .onConflictDoUpdate({\n target: [\n principalPolicyCheckpoints.principalType,\n principalPolicyCheckpoints.principalId,\n ],\n set: row,\n })\n .run();\n}\n\n// Lazily create the checkpoint tables on first access. Every load/save below\n// calls this, so the tables exist on demand; it is intentionally module-private\n// (no caller outside this file needs it, and exporting it tripped knip).\nasync function ensureKeyingCheckpointTables(execSql: ExecSql): Promise<void> {\n await ensureSqlTables(execSql, keyingCheckpointTables);\n}\n\nexport async function loadAccessManifestCheckpoint(\n execSql: ExecSql,\n objectKind: AccessObjectKind,\n organizationId: string,\n objectId: string,\n): Promise<AccessManifestCheckpoint | null> {\n await ensureKeyingCheckpointTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const row = await loadAccessManifestCheckpointRow(db, {\n objectKind,\n organizationId,\n objectId,\n });\n\n return row ? { objectKind, objectId, organizationId, ...row } : null;\n}\n\nexport async function loadPrincipalPolicyCheckpoint(\n execSql: ExecSql,\n principalType: ManagedPrincipalKind,\n principalId: string,\n): Promise<PrincipalPolicyCheckpoint | null> {\n await ensureKeyingCheckpointTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const row = await loadPrincipalPolicyCheckpointRow(db, {\n principalType,\n principalId,\n });\n\n return row ? { principalType, principalId, ...row } : null;\n}\n/**\n * The shared shape/ownership guard every checkpoint comparison runs before\n * trusting a durable pin: the pin must belong to the compared principal and\n * carry a well-formed version and hash.\n */\nexport function assertPrincipalPolicyCheckpointShape(\n checkpoint: PrincipalPolicyCheckpoint,\n head: PrincipalPolicyCheckpointIdentity,\n): void {\n if (\n checkpoint.principalType !== head.principalType ||\n checkpoint.principalId !== head.principalId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"principal policy checkpoint belongs to another principal\",\n );\n }\n if (\n !Number.isInteger(checkpoint.version) ||\n checkpoint.version < 1 ||\n checkpoint.stateHash.length === 0\n ) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"principal policy checkpoint is malformed\",\n );\n }\n}\n"]}
1
+ {"version":3,"file":"keyingCheckpointPersistence.js","sourceRoot":"","sources":["keyingCheckpointPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccessManifestCheckpoint,\n AccessObjectKind,\n ManagedPrincipalKind,\n PrincipalPolicyCheckpoint,\n} from \"@tearleads/crypto\";\nimport { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport {\n accessManifestCheckpoints,\n keyingCheckpointTables,\n principalPolicyCheckpoints,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteDatabase,\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\nimport { recordPrincipalPolicyOrganizationInTransaction } from \"../principalPolicy/principalPolicyOrganizationPersistence\";\n\ntype CheckpointHandle = ClientSQLiteDatabase | ClientSQLiteTransactionScope;\n\ntype AccessManifestCheckpointIdentity = Pick<\n AccessManifestCheckpoint,\n \"objectKind\" | \"organizationId\" | \"objectId\"\n>;\n\ntype PrincipalPolicyCheckpointIdentity = Pick<\n PrincipalPolicyCheckpoint,\n \"principalType\" | \"principalId\"\n>;\n\n/** One key format per checkpoint identity, shared by every batch validator. */\nexport function accessManifestObjectKey(\n identity: AccessManifestCheckpointIdentity,\n): string {\n return JSON.stringify([\n identity.objectKind,\n identity.organizationId,\n identity.objectId,\n ]);\n}\n\nexport function principalPolicyKey(\n identity: PrincipalPolicyCheckpointIdentity,\n): string {\n return JSON.stringify([identity.principalType, identity.principalId]);\n}\n\nasync function loadAccessManifestCheckpointRow(\n handle: CheckpointHandle,\n identity: AccessManifestCheckpointIdentity,\n): Promise<Pick<AccessManifestCheckpoint, \"epoch\" | \"manifestHash\"> | null> {\n const rows = await handle\n .select({\n epoch: accessManifestCheckpoints.epoch,\n manifestHash: accessManifestCheckpoints.manifestHash,\n })\n .from(accessManifestCheckpoints)\n .where(\n and(\n eq(accessManifestCheckpoints.objectKind, identity.objectKind),\n eq(accessManifestCheckpoints.organizationId, identity.organizationId),\n eq(accessManifestCheckpoints.objectId, identity.objectId),\n ),\n )\n .limit(1);\n return rows[0] ?? null;\n}\n\nasync function loadPrincipalPolicyCheckpointRow(\n handle: CheckpointHandle,\n identity: PrincipalPolicyCheckpointIdentity,\n): Promise<Pick<PrincipalPolicyCheckpoint, \"version\" | \"stateHash\"> | null> {\n const rows = await handle\n .select({\n version: principalPolicyCheckpoints.version,\n stateHash: principalPolicyCheckpoints.stateHash,\n })\n .from(principalPolicyCheckpoints)\n .where(\n and(\n eq(principalPolicyCheckpoints.principalType, identity.principalType),\n eq(principalPolicyCheckpoints.principalId, identity.principalId),\n ),\n )\n .limit(1);\n return rows[0] ?? null;\n}\n\n/**\n * A loaded checkpoint row merged back with the identity it was looked up by —\n * the full checkpoint shape every comparison consumes.\n */\nexport async function loadStoredAccessManifestCheckpoint(\n handle: CheckpointHandle,\n checkpoint: AccessManifestCheckpoint,\n): Promise<AccessManifestCheckpoint | null> {\n const row = await loadAccessManifestCheckpointRow(handle, checkpoint);\n return row ? { ...checkpoint, ...row } : null;\n}\n\nexport async function loadStoredPrincipalPolicyCheckpoint(\n handle: CheckpointHandle,\n identity: PrincipalPolicyCheckpointIdentity,\n): Promise<PrincipalPolicyCheckpoint | null> {\n const row = await loadPrincipalPolicyCheckpointRow(handle, identity);\n return row\n ? {\n principalType: identity.principalType,\n principalId: identity.principalId,\n ...row,\n }\n : null;\n}\n\n/** Every principal with a durable policy checkpoint. */\nexport function listPrincipalPolicyCheckpointPrincipals(\n handle: CheckpointHandle,\n): Promise<{ id: string; type: string }[]> {\n return handle\n .selectDistinct({\n id: principalPolicyCheckpoints.principalId,\n type: principalPolicyCheckpoints.principalType,\n })\n .from(principalPolicyCheckpoints);\n}\n\nexport async function upsertAccessManifestCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n checkpoint: AccessManifestCheckpoint,\n updatedAt: string,\n): Promise<void> {\n const row = { ...checkpoint, updatedAt };\n await tx\n .insert(accessManifestCheckpoints)\n .values(row)\n .onConflictDoUpdate({\n target: [\n accessManifestCheckpoints.objectKind,\n accessManifestCheckpoints.organizationId,\n accessManifestCheckpoints.objectId,\n ],\n set: row,\n })\n .run();\n}\n\nexport async function upsertPrincipalPolicyCheckpointInTransaction(\n tx: ClientSQLiteTransactionScope,\n checkpoint: PrincipalPolicyCheckpoint,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n await recordPrincipalPolicyOrganizationInTransaction(tx, {\n organizationId,\n principalId: checkpoint.principalId,\n principalType: checkpoint.principalType,\n });\n const row = { ...checkpoint, updatedAt };\n await tx\n .insert(principalPolicyCheckpoints)\n .values(row)\n .onConflictDoUpdate({\n target: [\n principalPolicyCheckpoints.principalType,\n principalPolicyCheckpoints.principalId,\n ],\n set: row,\n })\n .run();\n}\n\n// Lazily create the checkpoint tables on first access. Every load/save below\n// calls this, so the tables exist on demand; it is intentionally module-private\n// (no caller outside this file needs it, and exporting it tripped knip).\nasync function ensureKeyingCheckpointTables(execSql: ExecSql): Promise<void> {\n await ensureSqlTables(execSql, keyingCheckpointTables);\n}\n\nexport async function loadAccessManifestCheckpoint(\n execSql: ExecSql,\n objectKind: AccessObjectKind,\n organizationId: string,\n objectId: string,\n): Promise<AccessManifestCheckpoint | null> {\n await ensureKeyingCheckpointTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const row = await loadAccessManifestCheckpointRow(db, {\n objectKind,\n organizationId,\n objectId,\n });\n\n return row ? { objectKind, objectId, organizationId, ...row } : null;\n}\n\nexport async function loadPrincipalPolicyCheckpoint(\n execSql: ExecSql,\n principalType: ManagedPrincipalKind,\n principalId: string,\n): Promise<PrincipalPolicyCheckpoint | null> {\n await ensureKeyingCheckpointTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const row = await loadPrincipalPolicyCheckpointRow(db, {\n principalType,\n principalId,\n });\n\n return row ? { principalType, principalId, ...row } : null;\n}\n/**\n * The shared shape/ownership guard every checkpoint comparison runs before\n * trusting a durable pin: the pin must belong to the compared principal and\n * carry a well-formed version and hash.\n */\nexport function assertPrincipalPolicyCheckpointShape(\n checkpoint: PrincipalPolicyCheckpoint,\n head: PrincipalPolicyCheckpointIdentity,\n): void {\n if (\n checkpoint.principalType !== head.principalType ||\n checkpoint.principalId !== head.principalId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"principal policy checkpoint belongs to another principal\",\n );\n }\n if (\n !Number.isInteger(checkpoint.version) ||\n checkpoint.version < 1 ||\n checkpoint.stateHash.length === 0\n ) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"principal policy checkpoint is malformed\",\n );\n }\n}\n"]}
@@ -1,9 +1,10 @@
1
1
  import { KeyingVerificationError } from "../../../internal/crypto/index.js";
2
2
  import { isPrincipalPolicyBundleResponse } from "../../../internal/validators/response/index.js";
3
3
  import { and, asc, eq } from "drizzle-orm";
4
- import { keyingCheckpointTables, principalPolicies, principalPolicyBundleHistory, principalPolicyCheckpoints, principalPolicyTables, } from "../../sqlite/schema/index.js";
4
+ import { keyingCheckpointTables, principalPolicies, principalPolicyBundleHistory, principalPolicyTables, } from "../../sqlite/schema/index.js";
5
5
  import { getClientSQLitePersistenceRuntime, } from "../../sqlite/sqlitePersistenceRuntime.js";
6
6
  import { ensureSqlTables } from "../../sqlite/sqlSchema.js";
7
+ import { loadStoredPrincipalPolicyCheckpoint } from "../keyingCheckpoints/keyingCheckpointPersistence.js";
7
8
  import { assertSameHeadPrincipalPolicyBundle } from "./principalPolicyBundleIntegrity.js";
8
9
  import { recordPrincipalPolicyBundleOrganizationInTransaction, recordPrincipalPolicyOrganizationInTransaction, } from "./principalPolicyOrganizationPersistence.js";
9
10
  import { indexPrincipalPolicyBundleInTransaction } from "./principalPolicyReferenceIndexPersistence.js";
@@ -164,14 +165,7 @@ async function writePrincipalPolicyBundle(tx, bundle, nextRow, incomingHead) {
164
165
  .from(principalPolicies)
165
166
  .where(wherePrincipal)
166
167
  .limit(1);
167
- const [durableCheckpoint] = await tx
168
- .select({
169
- stateHash: principalPolicyCheckpoints.stateHash,
170
- version: principalPolicyCheckpoints.version,
171
- })
172
- .from(principalPolicyCheckpoints)
173
- .where(and(eq(principalPolicyCheckpoints.principalType, nextRow.principalType), eq(principalPolicyCheckpoints.principalId, nextRow.principalId)))
174
- .limit(1);
168
+ const durableCheckpoint = await loadStoredPrincipalPolicyCheckpoint(tx, nextRow);
175
169
  const storedHead = storedPolicy
176
170
  ? parseStoredPrincipalPolicyHead(storedPolicy.currentStateJson)
177
171
  : null;
@@ -1 +1 @@
1
- {"version":3,"file":"principalPolicyPersistence.js","sourceRoot":"","sources":["principalPolicyPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { isPrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { and, asc, eq } from \"drizzle-orm\";\nimport {\n keyingCheckpointTables,\n principalPolicies,\n principalPolicyBundleHistory,\n principalPolicyCheckpoints,\n principalPolicyTables,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\nimport { assertSameHeadPrincipalPolicyBundle } from \"./principalPolicyBundleIntegrity\";\nimport {\n recordPrincipalPolicyBundleOrganizationInTransaction,\n recordPrincipalPolicyOrganizationInTransaction,\n} from \"./principalPolicyOrganizationPersistence\";\nimport { indexPrincipalPolicyBundleInTransaction } from \"./principalPolicyReferenceIndexPersistence\";\nimport { storedPrincipalPolicyBundleFromJson } from \"./storedPrincipalPolicyBundle\";\n\ninterface PrincipalPolicyRow {\n principalType: \"group\" | \"organization\";\n principalId: string;\n stateHash: string;\n currentStateJson: string;\n currentPayloadJson: string;\n currentProjectionJson: string;\n currentGrantsJson: string;\n currentMemberEnvelopesJson: string;\n previousStatesJson: string;\n updatedAt: string;\n}\n\nexport interface SelectedPrincipalPolicyRow {\n principalType: string;\n principalId: string;\n stateHash: string;\n currentStateJson: string;\n currentPayloadJson: string;\n currentProjectionJson: string;\n currentGrantsJson: string;\n currentMemberEnvelopesJson: string;\n previousStatesJson: string;\n updatedAt: string;\n}\n\ninterface StoredPrincipalPolicyHead {\n readonly stateHash: string;\n readonly version: number;\n}\n\nfunction isManagedPrincipalType(\n value: string,\n): value is PrincipalStateResponse[\"principalType\"] {\n return value === \"group\" || value === \"organization\";\n}\n\nfunction parsePrincipalPolicyRow(\n row: SelectedPrincipalPolicyRow,\n): PrincipalPolicyRow | null {\n if (!isManagedPrincipalType(row.principalType)) {\n return null;\n }\n\n return {\n principalType: row.principalType,\n principalId: row.principalId,\n stateHash: row.stateHash,\n currentStateJson: row.currentStateJson,\n currentPayloadJson: row.currentPayloadJson,\n currentProjectionJson: row.currentProjectionJson,\n currentGrantsJson: row.currentGrantsJson,\n currentMemberEnvelopesJson: row.currentMemberEnvelopesJson,\n previousStatesJson: row.previousStatesJson,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction parseStoredPrincipalPolicyHead(\n currentStateJson: string,\n): StoredPrincipalPolicyHead | null {\n try {\n const value: unknown = JSON.parse(currentStateJson);\n if (!value || typeof value !== \"object\") {\n return null;\n }\n const stateHash = Reflect.get(value, \"stateHash\");\n const version = Reflect.get(value, \"version\");\n return typeof stateHash === \"string\" && typeof version === \"number\"\n ? { stateHash, version }\n : null;\n } catch {\n return null;\n }\n}\n\nfunction parsePrincipalPolicyBundle(\n row: PrincipalPolicyRow,\n): PrincipalPolicyBundleResponse {\n const bundle = storedPrincipalPolicyBundleFromJson(row);\n\n if (!isPrincipalPolicyBundleResponse(bundle)) {\n throw new Error(\"Stored principal policy bundle is invalid\");\n }\n\n return bundle;\n}\n\nexport async function ensurePrincipalPolicyTables(\n execSql: ExecSql,\n): Promise<void> {\n await ensureSqlTables(execSql, principalPolicyTables);\n}\n\ntype PrincipalPolicyBundleTable =\n | typeof principalPolicies\n | typeof principalPolicyBundleHistory;\n\n/**\n * The ONE select shape for a stored principal-policy bundle row, over either\n * the mutable-head table or the retained-history table.\n */\nexport function principalPolicyBundleSelection(\n table: PrincipalPolicyBundleTable,\n) {\n return {\n principalType: table.principalType,\n principalId: table.principalId,\n stateHash: table.stateHash,\n currentStateJson: table.currentStateJson,\n currentPayloadJson: table.currentPayloadJson,\n currentProjectionJson: table.currentProjectionJson,\n currentGrantsJson: table.currentGrantsJson,\n currentMemberEnvelopesJson: table.currentMemberEnvelopesJson,\n previousStatesJson: table.previousStatesJson,\n updatedAt: table.updatedAt,\n };\n}\n\nexport async function loadPrincipalPolicyBundle(\n execSql: ExecSql,\n principalType: PrincipalStateResponse[\"principalType\"],\n principalId: string,\n): Promise<PrincipalPolicyBundleResponse | null> {\n await ensurePrincipalPolicyTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, principalType),\n eq(principalPolicies.principalId, principalId),\n ),\n )\n .limit(1);\n\n const row = rows[0] ? parsePrincipalPolicyRow(rows[0]) : null;\n return row ? parsePrincipalPolicyBundle(row) : null;\n}\n\nexport async function loadAllPrincipalPolicyBundles(\n execSql: ExecSql,\n): Promise<PrincipalPolicyBundleResponse[]> {\n await ensurePrincipalPolicyTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .orderBy(\n asc(principalPolicies.principalType),\n asc(principalPolicies.principalId),\n );\n const historyRows = await db\n .select(principalPolicyBundleSelection(principalPolicyBundleHistory))\n .from(principalPolicyBundleHistory)\n .orderBy(\n asc(principalPolicyBundleHistory.principalType),\n asc(principalPolicyBundleHistory.principalId),\n asc(principalPolicyBundleHistory.stateHash),\n );\n\n const bundles: PrincipalPolicyBundleResponse[] = [];\n\n for (const rawRow of [...rows, ...historyRows]) {\n const row = parsePrincipalPolicyRow(rawRow);\n\n if (!row) {\n continue;\n }\n\n bundles.push(parsePrincipalPolicyBundle(row));\n }\n\n return bundles;\n}\n\nexport async function loadPrincipalPolicyStateHash(\n execSql: ExecSql,\n principalType: PrincipalStateResponse[\"principalType\"],\n principalId: string,\n): Promise<string | null> {\n await ensurePrincipalPolicyTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ stateHash: principalPolicies.stateHash })\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, principalType),\n eq(principalPolicies.principalId, principalId),\n ),\n )\n .limit(1);\n\n return rows[0]?.stateHash ?? null;\n}\n\nfunction policyBundleRow(\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n): PrincipalPolicyRow {\n return {\n principalType: bundle.currentState.principalType,\n principalId: bundle.currentState.principalId,\n stateHash: bundle.currentState.stateHash,\n currentStateJson: JSON.stringify(bundle.currentState),\n currentPayloadJson: JSON.stringify(bundle.currentPayload),\n currentProjectionJson: JSON.stringify(bundle.currentProjection),\n currentGrantsJson: JSON.stringify(bundle.currentGrants),\n currentMemberEnvelopesJson: JSON.stringify(bundle.currentMemberEnvelopes),\n previousStatesJson: JSON.stringify(bundle.previousStates),\n updatedAt,\n };\n}\n\nfunction assertNoHeadConflict(\n incoming: StoredPrincipalPolicyHead,\n checkpoint: StoredPrincipalPolicyHead | null,\n): void {\n if (\n checkpoint &&\n incoming.version === checkpoint.version &&\n incoming.stateHash !== checkpoint.stateHash\n ) {\n throw new KeyingVerificationError(\n \"equivocation\",\n \"principal policy bundle conflicts with the cached head at one version\",\n );\n }\n}\n\nasync function archiveOlderPolicyBundle(\n tx: ClientSQLiteTransactionScope,\n storedPolicy: SelectedPrincipalPolicyRow | undefined,\n storedHead: StoredPrincipalPolicyHead | null,\n incomingHead: StoredPrincipalPolicyHead,\n): Promise<void> {\n if (\n !storedPolicy ||\n !storedHead ||\n storedHead.version >= incomingHead.version\n ) {\n return;\n }\n const archiveRow = parsePrincipalPolicyRow(storedPolicy);\n if (!archiveRow) {\n return;\n }\n try {\n parsePrincipalPolicyBundle(archiveRow);\n await tx\n .insert(principalPolicyBundleHistory)\n .values(archiveRow)\n .onConflictDoNothing()\n .run();\n } catch {\n // A corrupt cache row is replaced, never retained as key material.\n }\n}\n\nasync function writePrincipalPolicyBundle(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n nextRow: PrincipalPolicyRow,\n incomingHead: StoredPrincipalPolicyHead,\n): Promise<void> {\n const wherePrincipal = and(\n eq(principalPolicies.principalType, nextRow.principalType),\n eq(principalPolicies.principalId, nextRow.principalId),\n );\n const [storedPolicy] = await tx\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(wherePrincipal)\n .limit(1);\n const [durableCheckpoint] = await tx\n .select({\n stateHash: principalPolicyCheckpoints.stateHash,\n version: principalPolicyCheckpoints.version,\n })\n .from(principalPolicyCheckpoints)\n .where(\n and(\n eq(principalPolicyCheckpoints.principalType, nextRow.principalType),\n eq(principalPolicyCheckpoints.principalId, nextRow.principalId),\n ),\n )\n .limit(1);\n const storedHead = storedPolicy\n ? parseStoredPrincipalPolicyHead(storedPolicy.currentStateJson)\n : null;\n if (\n storedPolicy &&\n storedHead?.version === incomingHead.version &&\n storedHead.stateHash === incomingHead.stateHash\n ) {\n assertSameHeadPrincipalPolicyBundle(storedPolicy, nextRow);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n return;\n }\n const [retainedPolicy] = await tx\n .select(principalPolicyBundleSelection(principalPolicyBundleHistory))\n .from(principalPolicyBundleHistory)\n .where(\n and(\n eq(principalPolicyBundleHistory.principalType, nextRow.principalType),\n eq(principalPolicyBundleHistory.principalId, nextRow.principalId),\n eq(principalPolicyBundleHistory.stateHash, nextRow.stateHash),\n ),\n )\n .limit(1);\n if (retainedPolicy) {\n assertSameHeadPrincipalPolicyBundle(retainedPolicy, nextRow);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n }\n const effectiveHead =\n durableCheckpoint &&\n (!storedHead || durableCheckpoint.version >= storedHead.version)\n ? durableCheckpoint\n : storedHead;\n assertNoHeadConflict(incomingHead, storedHead);\n assertNoHeadConflict(incomingHead, durableCheckpoint ?? null);\n if (effectiveHead && incomingHead.version < effectiveHead.version) {\n return;\n }\n\n await archiveOlderPolicyBundle(tx, storedPolicy, storedHead, incomingHead);\n await tx\n .insert(principalPolicies)\n .values(nextRow)\n .onConflictDoUpdate({\n target: [principalPolicies.principalType, principalPolicies.principalId],\n set: nextRow,\n })\n .run();\n await tx\n .delete(principalPolicyBundleHistory)\n .where(\n and(\n eq(principalPolicyBundleHistory.principalType, nextRow.principalType),\n eq(principalPolicyBundleHistory.principalId, nextRow.principalId),\n eq(principalPolicyBundleHistory.stateHash, nextRow.stateHash),\n ),\n )\n .run();\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n}\n\nexport async function writePrincipalPolicyBundleInTransaction(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n await recordPrincipalPolicyBundleOrganizationInTransaction(\n tx,\n bundle,\n organizationId,\n );\n await writePrincipalPolicyBundle(\n tx,\n bundle,\n policyBundleRow(bundle, updatedAt),\n bundle.currentState,\n );\n}\n\nexport async function assertPrincipalPolicyBundleStoredInTransaction(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n): Promise<void> {\n const expected = policyBundleRow(bundle, bundle.currentState.createdAt);\n const [stored] = await tx\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, expected.principalType),\n eq(principalPolicies.principalId, expected.principalId),\n ),\n )\n .limit(1);\n if (!stored) {\n throw new Error(\"Verified principal policy bundle was not persisted\");\n }\n assertSameHeadPrincipalPolicyBundle(stored, expected);\n}\n\nexport async function retainPrincipalPolicyBundleInTransaction(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n const row = policyBundleRow(bundle, updatedAt);\n await recordPrincipalPolicyOrganizationInTransaction(tx, {\n organizationId,\n principalId: row.principalId,\n principalType: row.principalType,\n });\n const [current] = await tx\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, row.principalType),\n eq(principalPolicies.principalId, row.principalId),\n ),\n )\n .limit(1);\n if (current?.stateHash === row.stateHash) {\n assertSameHeadPrincipalPolicyBundle(current, row);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n return;\n }\n const [retained] = await tx\n .select(principalPolicyBundleSelection(principalPolicyBundleHistory))\n .from(principalPolicyBundleHistory)\n .where(\n and(\n eq(principalPolicyBundleHistory.principalType, row.principalType),\n eq(principalPolicyBundleHistory.principalId, row.principalId),\n eq(principalPolicyBundleHistory.stateHash, row.stateHash),\n ),\n )\n .limit(1);\n if (retained) {\n assertSameHeadPrincipalPolicyBundle(retained, row);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n return;\n }\n await tx.insert(principalPolicyBundleHistory).values(row).run();\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n}\n\nexport async function savePrincipalPolicyBundle(\n execSql: ExecSql,\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n organizationId: string,\n options?: { stillCurrent?: (() => boolean) | undefined } | undefined,\n): Promise<void> {\n await ensureSqlTables(execSql, [\n ...principalPolicyTables,\n ...keyingCheckpointTables,\n ]);\n\n const runtime = getClientSQLitePersistenceRuntime(execSql);\n const save = (tx: ClientSQLiteTransactionScope) =>\n writePrincipalPolicyBundleInTransaction(\n tx,\n bundle,\n updatedAt,\n organizationId,\n );\n if (options?.stillCurrent) {\n await runtime.guardedTransaction(save, options.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(save, { behavior: \"immediate\" });\n}\n"]}
1
+ {"version":3,"file":"principalPolicyPersistence.js","sourceRoot":"","sources":["principalPolicyPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { isPrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { and, asc, eq } from \"drizzle-orm\";\nimport {\n keyingCheckpointTables,\n principalPolicies,\n principalPolicyBundleHistory,\n principalPolicyTables,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../../sqlite/sqlSchema\";\nimport { loadStoredPrincipalPolicyCheckpoint } from \"../keyingCheckpoints/keyingCheckpointPersistence\";\nimport { assertSameHeadPrincipalPolicyBundle } from \"./principalPolicyBundleIntegrity\";\nimport {\n recordPrincipalPolicyBundleOrganizationInTransaction,\n recordPrincipalPolicyOrganizationInTransaction,\n} from \"./principalPolicyOrganizationPersistence\";\nimport { indexPrincipalPolicyBundleInTransaction } from \"./principalPolicyReferenceIndexPersistence\";\nimport { storedPrincipalPolicyBundleFromJson } from \"./storedPrincipalPolicyBundle\";\n\ninterface PrincipalPolicyRow {\n principalType: \"group\" | \"organization\";\n principalId: string;\n stateHash: string;\n currentStateJson: string;\n currentPayloadJson: string;\n currentProjectionJson: string;\n currentGrantsJson: string;\n currentMemberEnvelopesJson: string;\n previousStatesJson: string;\n updatedAt: string;\n}\n\nexport interface SelectedPrincipalPolicyRow {\n principalType: string;\n principalId: string;\n stateHash: string;\n currentStateJson: string;\n currentPayloadJson: string;\n currentProjectionJson: string;\n currentGrantsJson: string;\n currentMemberEnvelopesJson: string;\n previousStatesJson: string;\n updatedAt: string;\n}\n\ninterface StoredPrincipalPolicyHead {\n readonly stateHash: string;\n readonly version: number;\n}\n\nfunction isManagedPrincipalType(\n value: string,\n): value is PrincipalStateResponse[\"principalType\"] {\n return value === \"group\" || value === \"organization\";\n}\n\nfunction parsePrincipalPolicyRow(\n row: SelectedPrincipalPolicyRow,\n): PrincipalPolicyRow | null {\n if (!isManagedPrincipalType(row.principalType)) {\n return null;\n }\n\n return {\n principalType: row.principalType,\n principalId: row.principalId,\n stateHash: row.stateHash,\n currentStateJson: row.currentStateJson,\n currentPayloadJson: row.currentPayloadJson,\n currentProjectionJson: row.currentProjectionJson,\n currentGrantsJson: row.currentGrantsJson,\n currentMemberEnvelopesJson: row.currentMemberEnvelopesJson,\n previousStatesJson: row.previousStatesJson,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction parseStoredPrincipalPolicyHead(\n currentStateJson: string,\n): StoredPrincipalPolicyHead | null {\n try {\n const value: unknown = JSON.parse(currentStateJson);\n if (!value || typeof value !== \"object\") {\n return null;\n }\n const stateHash = Reflect.get(value, \"stateHash\");\n const version = Reflect.get(value, \"version\");\n return typeof stateHash === \"string\" && typeof version === \"number\"\n ? { stateHash, version }\n : null;\n } catch {\n return null;\n }\n}\n\nfunction parsePrincipalPolicyBundle(\n row: PrincipalPolicyRow,\n): PrincipalPolicyBundleResponse {\n const bundle = storedPrincipalPolicyBundleFromJson(row);\n\n if (!isPrincipalPolicyBundleResponse(bundle)) {\n throw new Error(\"Stored principal policy bundle is invalid\");\n }\n\n return bundle;\n}\n\nexport async function ensurePrincipalPolicyTables(\n execSql: ExecSql,\n): Promise<void> {\n await ensureSqlTables(execSql, principalPolicyTables);\n}\n\ntype PrincipalPolicyBundleTable =\n | typeof principalPolicies\n | typeof principalPolicyBundleHistory;\n\n/**\n * The ONE select shape for a stored principal-policy bundle row, over either\n * the mutable-head table or the retained-history table.\n */\nexport function principalPolicyBundleSelection(\n table: PrincipalPolicyBundleTable,\n) {\n return {\n principalType: table.principalType,\n principalId: table.principalId,\n stateHash: table.stateHash,\n currentStateJson: table.currentStateJson,\n currentPayloadJson: table.currentPayloadJson,\n currentProjectionJson: table.currentProjectionJson,\n currentGrantsJson: table.currentGrantsJson,\n currentMemberEnvelopesJson: table.currentMemberEnvelopesJson,\n previousStatesJson: table.previousStatesJson,\n updatedAt: table.updatedAt,\n };\n}\n\nexport async function loadPrincipalPolicyBundle(\n execSql: ExecSql,\n principalType: PrincipalStateResponse[\"principalType\"],\n principalId: string,\n): Promise<PrincipalPolicyBundleResponse | null> {\n await ensurePrincipalPolicyTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, principalType),\n eq(principalPolicies.principalId, principalId),\n ),\n )\n .limit(1);\n\n const row = rows[0] ? parsePrincipalPolicyRow(rows[0]) : null;\n return row ? parsePrincipalPolicyBundle(row) : null;\n}\n\nexport async function loadAllPrincipalPolicyBundles(\n execSql: ExecSql,\n): Promise<PrincipalPolicyBundleResponse[]> {\n await ensurePrincipalPolicyTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .orderBy(\n asc(principalPolicies.principalType),\n asc(principalPolicies.principalId),\n );\n const historyRows = await db\n .select(principalPolicyBundleSelection(principalPolicyBundleHistory))\n .from(principalPolicyBundleHistory)\n .orderBy(\n asc(principalPolicyBundleHistory.principalType),\n asc(principalPolicyBundleHistory.principalId),\n asc(principalPolicyBundleHistory.stateHash),\n );\n\n const bundles: PrincipalPolicyBundleResponse[] = [];\n\n for (const rawRow of [...rows, ...historyRows]) {\n const row = parsePrincipalPolicyRow(rawRow);\n\n if (!row) {\n continue;\n }\n\n bundles.push(parsePrincipalPolicyBundle(row));\n }\n\n return bundles;\n}\n\nexport async function loadPrincipalPolicyStateHash(\n execSql: ExecSql,\n principalType: PrincipalStateResponse[\"principalType\"],\n principalId: string,\n): Promise<string | null> {\n await ensurePrincipalPolicyTables(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ stateHash: principalPolicies.stateHash })\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, principalType),\n eq(principalPolicies.principalId, principalId),\n ),\n )\n .limit(1);\n\n return rows[0]?.stateHash ?? null;\n}\n\nfunction policyBundleRow(\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n): PrincipalPolicyRow {\n return {\n principalType: bundle.currentState.principalType,\n principalId: bundle.currentState.principalId,\n stateHash: bundle.currentState.stateHash,\n currentStateJson: JSON.stringify(bundle.currentState),\n currentPayloadJson: JSON.stringify(bundle.currentPayload),\n currentProjectionJson: JSON.stringify(bundle.currentProjection),\n currentGrantsJson: JSON.stringify(bundle.currentGrants),\n currentMemberEnvelopesJson: JSON.stringify(bundle.currentMemberEnvelopes),\n previousStatesJson: JSON.stringify(bundle.previousStates),\n updatedAt,\n };\n}\n\nfunction assertNoHeadConflict(\n incoming: StoredPrincipalPolicyHead,\n checkpoint: StoredPrincipalPolicyHead | null,\n): void {\n if (\n checkpoint &&\n incoming.version === checkpoint.version &&\n incoming.stateHash !== checkpoint.stateHash\n ) {\n throw new KeyingVerificationError(\n \"equivocation\",\n \"principal policy bundle conflicts with the cached head at one version\",\n );\n }\n}\n\nasync function archiveOlderPolicyBundle(\n tx: ClientSQLiteTransactionScope,\n storedPolicy: SelectedPrincipalPolicyRow | undefined,\n storedHead: StoredPrincipalPolicyHead | null,\n incomingHead: StoredPrincipalPolicyHead,\n): Promise<void> {\n if (\n !storedPolicy ||\n !storedHead ||\n storedHead.version >= incomingHead.version\n ) {\n return;\n }\n const archiveRow = parsePrincipalPolicyRow(storedPolicy);\n if (!archiveRow) {\n return;\n }\n try {\n parsePrincipalPolicyBundle(archiveRow);\n await tx\n .insert(principalPolicyBundleHistory)\n .values(archiveRow)\n .onConflictDoNothing()\n .run();\n } catch {\n // A corrupt cache row is replaced, never retained as key material.\n }\n}\n\nasync function writePrincipalPolicyBundle(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n nextRow: PrincipalPolicyRow,\n incomingHead: StoredPrincipalPolicyHead,\n): Promise<void> {\n const wherePrincipal = and(\n eq(principalPolicies.principalType, nextRow.principalType),\n eq(principalPolicies.principalId, nextRow.principalId),\n );\n const [storedPolicy] = await tx\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(wherePrincipal)\n .limit(1);\n const durableCheckpoint = await loadStoredPrincipalPolicyCheckpoint(\n tx,\n nextRow,\n );\n const storedHead = storedPolicy\n ? parseStoredPrincipalPolicyHead(storedPolicy.currentStateJson)\n : null;\n if (\n storedPolicy &&\n storedHead?.version === incomingHead.version &&\n storedHead.stateHash === incomingHead.stateHash\n ) {\n assertSameHeadPrincipalPolicyBundle(storedPolicy, nextRow);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n return;\n }\n const [retainedPolicy] = await tx\n .select(principalPolicyBundleSelection(principalPolicyBundleHistory))\n .from(principalPolicyBundleHistory)\n .where(\n and(\n eq(principalPolicyBundleHistory.principalType, nextRow.principalType),\n eq(principalPolicyBundleHistory.principalId, nextRow.principalId),\n eq(principalPolicyBundleHistory.stateHash, nextRow.stateHash),\n ),\n )\n .limit(1);\n if (retainedPolicy) {\n assertSameHeadPrincipalPolicyBundle(retainedPolicy, nextRow);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n }\n const effectiveHead =\n durableCheckpoint &&\n (!storedHead || durableCheckpoint.version >= storedHead.version)\n ? durableCheckpoint\n : storedHead;\n assertNoHeadConflict(incomingHead, storedHead);\n assertNoHeadConflict(incomingHead, durableCheckpoint ?? null);\n if (effectiveHead && incomingHead.version < effectiveHead.version) {\n return;\n }\n\n await archiveOlderPolicyBundle(tx, storedPolicy, storedHead, incomingHead);\n await tx\n .insert(principalPolicies)\n .values(nextRow)\n .onConflictDoUpdate({\n target: [principalPolicies.principalType, principalPolicies.principalId],\n set: nextRow,\n })\n .run();\n await tx\n .delete(principalPolicyBundleHistory)\n .where(\n and(\n eq(principalPolicyBundleHistory.principalType, nextRow.principalType),\n eq(principalPolicyBundleHistory.principalId, nextRow.principalId),\n eq(principalPolicyBundleHistory.stateHash, nextRow.stateHash),\n ),\n )\n .run();\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n}\n\nexport async function writePrincipalPolicyBundleInTransaction(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n await recordPrincipalPolicyBundleOrganizationInTransaction(\n tx,\n bundle,\n organizationId,\n );\n await writePrincipalPolicyBundle(\n tx,\n bundle,\n policyBundleRow(bundle, updatedAt),\n bundle.currentState,\n );\n}\n\nexport async function assertPrincipalPolicyBundleStoredInTransaction(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n): Promise<void> {\n const expected = policyBundleRow(bundle, bundle.currentState.createdAt);\n const [stored] = await tx\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, expected.principalType),\n eq(principalPolicies.principalId, expected.principalId),\n ),\n )\n .limit(1);\n if (!stored) {\n throw new Error(\"Verified principal policy bundle was not persisted\");\n }\n assertSameHeadPrincipalPolicyBundle(stored, expected);\n}\n\nexport async function retainPrincipalPolicyBundleInTransaction(\n tx: ClientSQLiteTransactionScope,\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n const row = policyBundleRow(bundle, updatedAt);\n await recordPrincipalPolicyOrganizationInTransaction(tx, {\n organizationId,\n principalId: row.principalId,\n principalType: row.principalType,\n });\n const [current] = await tx\n .select(principalPolicyBundleSelection(principalPolicies))\n .from(principalPolicies)\n .where(\n and(\n eq(principalPolicies.principalType, row.principalType),\n eq(principalPolicies.principalId, row.principalId),\n ),\n )\n .limit(1);\n if (current?.stateHash === row.stateHash) {\n assertSameHeadPrincipalPolicyBundle(current, row);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n return;\n }\n const [retained] = await tx\n .select(principalPolicyBundleSelection(principalPolicyBundleHistory))\n .from(principalPolicyBundleHistory)\n .where(\n and(\n eq(principalPolicyBundleHistory.principalType, row.principalType),\n eq(principalPolicyBundleHistory.principalId, row.principalId),\n eq(principalPolicyBundleHistory.stateHash, row.stateHash),\n ),\n )\n .limit(1);\n if (retained) {\n assertSameHeadPrincipalPolicyBundle(retained, row);\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n return;\n }\n await tx.insert(principalPolicyBundleHistory).values(row).run();\n await indexPrincipalPolicyBundleInTransaction(tx, bundle);\n}\n\nexport async function savePrincipalPolicyBundle(\n execSql: ExecSql,\n bundle: PrincipalPolicyBundleResponse,\n updatedAt: string,\n organizationId: string,\n options?: { stillCurrent?: (() => boolean) | undefined } | undefined,\n): Promise<void> {\n await ensureSqlTables(execSql, [\n ...principalPolicyTables,\n ...keyingCheckpointTables,\n ]);\n\n const runtime = getClientSQLitePersistenceRuntime(execSql);\n const save = (tx: ClientSQLiteTransactionScope) =>\n writePrincipalPolicyBundleInTransaction(\n tx,\n bundle,\n updatedAt,\n organizationId,\n );\n if (options?.stillCurrent) {\n await runtime.guardedTransaction(save, options.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(save, { behavior: \"immediate\" });\n}\n"]}
@@ -1,10 +1,11 @@
1
1
  import { and, eq, or } from "drizzle-orm";
2
- import { principalPolicies, principalPolicyBundleHistory, principalPolicyBundleReferences, principalPolicyCheckpoints, principalPolicyOrganizations, } from "../../sqlite/schema/index.js";
2
+ import { principalPolicies, principalPolicyBundleHistory, principalPolicyBundleReferences, principalPolicyOrganizations, } from "../../sqlite/schema/index.js";
3
3
  import { principalHistoryEntries, principalHistoryNodes, principalHistoryPrefixes, } from "../../sqlite/schema/principalHistoryEvidenceSchema.js";
4
4
  import { principalHistoryNodeReferences, principalHistoryRootOwners, } from "../../sqlite/schema/principalHistoryNodeRetentionSchema.js";
5
5
  import { principalKeyEnvelopeArchive } from "../../sqlite/schema/principalHistoryRetentionSchema.js";
6
6
  import { principalHistoryStages } from "../../sqlite/schema/principalHistoryStageSchema.js";
7
7
  import { remoteResetBatches } from "../../sqlite/sqliteBindBudget.js";
8
+ import { listPrincipalPolicyCheckpointPrincipals } from "../keyingCheckpoints/keyingCheckpointPersistence.js";
8
9
  /** Current cache writes atomically pin ownership; reset never backfills it. */
9
10
  export async function loadRemoteResetPrincipalScope(tx, organizationId) {
10
11
  const [policyRows, retainedRows, ownershipRows] = await Promise.all([
@@ -15,12 +16,14 @@ export async function loadRemoteResetPrincipalScope(tx, organizationId) {
15
16
  })
16
17
  .from(principalPolicies),
17
18
  Promise.all([
18
- principalPolicyBundleHistory,
19
- principalPolicyBundleReferences,
20
- principalPolicyCheckpoints,
21
- ].map((table) => tx
22
- .selectDistinct({ id: table.principalId, type: table.principalType })
23
- .from(table))),
19
+ ...[principalPolicyBundleHistory, principalPolicyBundleReferences].map((table) => tx
20
+ .selectDistinct({
21
+ id: table.principalId,
22
+ type: table.principalType,
23
+ })
24
+ .from(table)),
25
+ listPrincipalPolicyCheckpointPrincipals(tx),
26
+ ]),
24
27
  tx
25
28
  .select({
26
29
  organizationId: principalPolicyOrganizations.organizationId,
@@ -1 +1 @@
1
- {"version":3,"file":"principalPolicyRemoteReset.js","sourceRoot":"","sources":["principalPolicyRemoteReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,+BAA+B,EAC/B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qDAAqD,CAAC;AAClG,OAAO,EAAE,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAanE,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,EAAgC,EAChC,cAAsB;IAKtB,MAAM,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClE,EAAE;aACC,MAAM,CAAC;YACN,EAAE,EAAE,iBAAiB,CAAC,WAAW;YACjC,IAAI,EAAE,iBAAiB,CAAC,aAAa;SACtC,CAAC;aACD,IAAI,CAAC,iBAAiB,CAAC;QAC1B,OAAO,CAAC,GAAG,CACT;YACE,4BAA4B;YAC5B,+BAA+B;YAC/B,0BAA0B;SAC3B,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACd,EAAE;aACC,cAAc,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC;aACpE,IAAI,CAAC,KAAK,CAAC,CACf,CACF;QACD,EAAE;aACC,MAAM,CAAC;YACN,cAAc,EAAE,4BAA4B,CAAC,cAAc;YAC3D,WAAW,EAAE,4BAA4B,CAAC,WAAW;YACrD,aAAa,EAAE,4BAA4B,CAAC,aAAa;SAC1D,CAAC;aACD,IAAI,CAAC,4BAA4B,CAAC;KACtC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;QACzB,GAAG,GAAG,CAAC,aAAa,KAAK,GAAG,CAAC,WAAW,EAAE;QAC1C,GAAG,CAAC,cAAc;KACnB,CAAC,CACH,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,IACE,GAAG,CAAC,IAAI,KAAK,cAAc;YAC3B,KAAK,KAAK,SAAS;YACnB,KAAK,KAAK,GAAG,CAAC,EAAE,EAChB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAmC,CAAC;IACxD,IAAI,CAAC,GAAG,CAAC,iBAAiB,cAAc,EAAE,EAAE;QAC1C,WAAW,EAAE,cAAc;QAC3B,aAAa,EAAE,cAAc;KAC9B,CAAC,CAAC;IACH,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,IAAI,GAAG,CAAC,aAAa,KAAK,OAAO,IAAI,GAAG,CAAC,aAAa,KAAK,cAAc,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,cAAc,KAAK,cAAc;YAAE,SAAS;QACpD,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,aAAa,KAAK,GAAG,CAAC,WAAW,EAAE,EAAE;YACnD,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;SACjC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,KAInD;IACC,KAAK,MAAM,KAAK,IAAI;QAClB,8BAA8B;QAC9B,0BAA0B;QAC1B,uBAAuB;QACvB,qBAAqB;QACrB,wBAAwB;QACxB,2BAA2B;KAC5B;QACC,MAAM,KAAK,CAAC,EAAE;aACX,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;aACrD,GAAG,EAAE,CAAC;IACX,MAAM,KAAK,CAAC,EAAE;SACX,MAAM,CAAC,sBAAsB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;SACtE,GAAG,EAAE,CAAC;IACT,KAAK,MAAM,cAAc,IAAI,kBAAkB,CAC7C,KAAK,CAAC,QAAQ,CAAC,aAAa,CAC7B,EAAE,CAAC;QACF,KAAK,MAAM,KAAK,IAAI;YAClB,iBAAiB;YACjB,4BAA4B;YAC5B,+BAA+B;SACvB,EAAE,CAAC;YACX,MAAM,KAAK,CAAC,EAAE;iBACX,MAAM,CAAC,KAAK,CAAC;iBACb,KAAK,CACJ,EAAE,CACA,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAClC,GAAG,CACD,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,SAAS,CAAC,aAAa,CAAC,EAChD,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC,CAC7C,CACF,CACF,CACF;iBACA,GAAG,EAAE,CAAC;QACX,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { and, eq, or } from \"drizzle-orm\";\nimport {\n principalPolicies,\n principalPolicyBundleHistory,\n principalPolicyBundleReferences,\n principalPolicyCheckpoints,\n principalPolicyOrganizations,\n} from \"../../sqlite/schema\";\nimport {\n principalHistoryEntries,\n principalHistoryNodes,\n principalHistoryPrefixes,\n} from \"../../sqlite/schema/principalHistoryEvidenceSchema\";\nimport {\n principalHistoryNodeReferences,\n principalHistoryRootOwners,\n} from \"../../sqlite/schema/principalHistoryNodeRetentionSchema\";\nimport { principalKeyEnvelopeArchive } from \"../../sqlite/schema/principalHistoryRetentionSchema\";\nimport { principalHistoryStages } from \"../../sqlite/schema/principalHistoryStageSchema\";\nimport { remoteResetBatches } from \"../../sqlite/sqliteBindBudget\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\n\nexport interface RemoteResetPrincipalKey {\n readonly principalId: string;\n readonly principalType: \"group\" | \"organization\";\n}\n\ninterface PrincipalRow {\n readonly id: string;\n readonly type: string;\n}\n\n/** Current cache writes atomically pin ownership; reset never backfills it. */\nexport async function loadRemoteResetPrincipalScope(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<{\n readonly policyRows: readonly PrincipalRow[];\n readonly principalKeys: readonly RemoteResetPrincipalKey[];\n}> {\n const [policyRows, retainedRows, ownershipRows] = await Promise.all([\n tx\n .select({\n id: principalPolicies.principalId,\n type: principalPolicies.principalType,\n })\n .from(principalPolicies),\n Promise.all(\n [\n principalPolicyBundleHistory,\n principalPolicyBundleReferences,\n principalPolicyCheckpoints,\n ].map((table) =>\n tx\n .selectDistinct({ id: table.principalId, type: table.principalType })\n .from(table),\n ),\n ),\n tx\n .select({\n organizationId: principalPolicyOrganizations.organizationId,\n principalId: principalPolicyOrganizations.principalId,\n principalType: principalPolicyOrganizations.principalType,\n })\n .from(principalPolicyOrganizations),\n ]);\n const owners = new Map(\n ownershipRows.map((row) => [\n `${row.principalType}\\0${row.principalId}`,\n row.organizationId,\n ]),\n );\n for (const row of [...policyRows, ...retainedRows.flat()]) {\n const owner = owners.get(`${row.type}\\0${row.id}`);\n if (row.type === \"group\" && !owner) {\n throw new Error(\n \"Unowned group policy cache requires a local database reset before organization purge\",\n );\n }\n if (row.type !== \"group\" && row.type !== \"organization\") {\n throw new Error(\"Principal policy cache has an invalid principal type\");\n }\n if (\n row.type === \"organization\" &&\n owner !== undefined &&\n owner !== row.id\n ) {\n throw new Error(\n \"Organization policy cache ownership does not match its identity\",\n );\n }\n }\n const keys = new Map<string, RemoteResetPrincipalKey>();\n keys.set(`organization\\0${organizationId}`, {\n principalId: organizationId,\n principalType: \"organization\",\n });\n for (const row of ownershipRows) {\n if (row.principalType !== \"group\" && row.principalType !== \"organization\") {\n throw new Error(\n \"Principal policy cache ownership has an invalid principal type\",\n );\n }\n if (!row.organizationId) {\n throw new Error(\n \"Principal policy cache ownership requires a local database reset\",\n );\n }\n if (row.organizationId !== organizationId) continue;\n keys.set(`${row.principalType}\\0${row.principalId}`, {\n principalId: row.principalId,\n principalType: row.principalType,\n });\n }\n return { policyRows, principalKeys: [...keys.values()] };\n}\n\n// Trust checkpoints and their ownership survive reset. Clearing cached bundles\n// must not turn a previously observed principal or object into first sight.\nexport async function clearRemoteResetPrincipalRows(input: {\n organizationId: string;\n snapshot: { principalKeys: readonly RemoteResetPrincipalKey[] };\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const table of [\n principalHistoryNodeReferences,\n principalHistoryRootOwners,\n principalHistoryEntries,\n principalHistoryNodes,\n principalHistoryPrefixes,\n principalKeyEnvelopeArchive,\n ])\n await input.tx\n .delete(table)\n .where(eq(table.organizationId, input.organizationId))\n .run();\n await input.tx\n .delete(principalHistoryStages)\n .where(eq(principalHistoryStages.organizationId, input.organizationId))\n .run();\n for (const principalBatch of remoteResetBatches(\n input.snapshot.principalKeys,\n )) {\n for (const table of [\n principalPolicies,\n principalPolicyBundleHistory,\n principalPolicyBundleReferences,\n ] as const) {\n await input.tx\n .delete(table)\n .where(\n or(\n ...principalBatch.map((principal) =>\n and(\n eq(table.principalType, principal.principalType),\n eq(table.principalId, principal.principalId),\n ),\n ),\n ),\n )\n .run();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"principalPolicyRemoteReset.js","sourceRoot":"","sources":["principalPolicyRemoteReset.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq, or } from \"drizzle-orm\";\nimport {\n principalPolicies,\n principalPolicyBundleHistory,\n principalPolicyBundleReferences,\n principalPolicyOrganizations,\n} from \"../../sqlite/schema\";\nimport {\n principalHistoryEntries,\n principalHistoryNodes,\n principalHistoryPrefixes,\n} from \"../../sqlite/schema/principalHistoryEvidenceSchema\";\nimport {\n principalHistoryNodeReferences,\n principalHistoryRootOwners,\n} from \"../../sqlite/schema/principalHistoryNodeRetentionSchema\";\nimport { principalKeyEnvelopeArchive } from \"../../sqlite/schema/principalHistoryRetentionSchema\";\nimport { principalHistoryStages } from \"../../sqlite/schema/principalHistoryStageSchema\";\nimport { remoteResetBatches } from \"../../sqlite/sqliteBindBudget\";\nimport type { ClientSQLiteTransactionScope } from \"../../sqlite/sqlitePersistenceRuntime\";\nimport { listPrincipalPolicyCheckpointPrincipals } from \"../keyingCheckpoints/keyingCheckpointPersistence\";\n\nexport interface RemoteResetPrincipalKey {\n readonly principalId: string;\n readonly principalType: \"group\" | \"organization\";\n}\n\ninterface PrincipalRow {\n readonly id: string;\n readonly type: string;\n}\n\n/** Current cache writes atomically pin ownership; reset never backfills it. */\nexport async function loadRemoteResetPrincipalScope(\n tx: ClientSQLiteTransactionScope,\n organizationId: string,\n): Promise<{\n readonly policyRows: readonly PrincipalRow[];\n readonly principalKeys: readonly RemoteResetPrincipalKey[];\n}> {\n const [policyRows, retainedRows, ownershipRows] = await Promise.all([\n tx\n .select({\n id: principalPolicies.principalId,\n type: principalPolicies.principalType,\n })\n .from(principalPolicies),\n Promise.all([\n ...[principalPolicyBundleHistory, principalPolicyBundleReferences].map(\n (table) =>\n tx\n .selectDistinct({\n id: table.principalId,\n type: table.principalType,\n })\n .from(table),\n ),\n listPrincipalPolicyCheckpointPrincipals(tx),\n ]),\n tx\n .select({\n organizationId: principalPolicyOrganizations.organizationId,\n principalId: principalPolicyOrganizations.principalId,\n principalType: principalPolicyOrganizations.principalType,\n })\n .from(principalPolicyOrganizations),\n ]);\n const owners = new Map(\n ownershipRows.map((row) => [\n `${row.principalType}\\0${row.principalId}`,\n row.organizationId,\n ]),\n );\n for (const row of [...policyRows, ...retainedRows.flat()]) {\n const owner = owners.get(`${row.type}\\0${row.id}`);\n if (row.type === \"group\" && !owner) {\n throw new Error(\n \"Unowned group policy cache requires a local database reset before organization purge\",\n );\n }\n if (row.type !== \"group\" && row.type !== \"organization\") {\n throw new Error(\"Principal policy cache has an invalid principal type\");\n }\n if (\n row.type === \"organization\" &&\n owner !== undefined &&\n owner !== row.id\n ) {\n throw new Error(\n \"Organization policy cache ownership does not match its identity\",\n );\n }\n }\n const keys = new Map<string, RemoteResetPrincipalKey>();\n keys.set(`organization\\0${organizationId}`, {\n principalId: organizationId,\n principalType: \"organization\",\n });\n for (const row of ownershipRows) {\n if (row.principalType !== \"group\" && row.principalType !== \"organization\") {\n throw new Error(\n \"Principal policy cache ownership has an invalid principal type\",\n );\n }\n if (!row.organizationId) {\n throw new Error(\n \"Principal policy cache ownership requires a local database reset\",\n );\n }\n if (row.organizationId !== organizationId) continue;\n keys.set(`${row.principalType}\\0${row.principalId}`, {\n principalId: row.principalId,\n principalType: row.principalType,\n });\n }\n return { policyRows, principalKeys: [...keys.values()] };\n}\n\n// Trust checkpoints and their ownership survive reset. Clearing cached bundles\n// must not turn a previously observed principal or object into first sight.\nexport async function clearRemoteResetPrincipalRows(input: {\n organizationId: string;\n snapshot: { principalKeys: readonly RemoteResetPrincipalKey[] };\n tx: ClientSQLiteTransactionScope;\n}): Promise<void> {\n for (const table of [\n principalHistoryNodeReferences,\n principalHistoryRootOwners,\n principalHistoryEntries,\n principalHistoryNodes,\n principalHistoryPrefixes,\n principalKeyEnvelopeArchive,\n ])\n await input.tx\n .delete(table)\n .where(eq(table.organizationId, input.organizationId))\n .run();\n await input.tx\n .delete(principalHistoryStages)\n .where(eq(principalHistoryStages.organizationId, input.organizationId))\n .run();\n for (const principalBatch of remoteResetBatches(\n input.snapshot.principalKeys,\n )) {\n for (const table of [\n principalPolicies,\n principalPolicyBundleHistory,\n principalPolicyBundleReferences,\n ] as const) {\n await input.tx\n .delete(table)\n .where(\n or(\n ...principalBatch.map((principal) =>\n and(\n eq(table.principalType, principal.principalType),\n eq(table.principalId, principal.principalId),\n ),\n ),\n ),\n )\n .run();\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tearleads/client-sdk",
3
- "version": "0.1.84",
3
+ "version": "0.1.86",
4
4
  "description": "React-free Tearleads client runtime: local SQLite persistence, keys, sync, encrypted blobs, and domain workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -33,8 +33,8 @@
33
33
  "@noble/hashes": "^2.4.0",
34
34
  "@noble/post-quantum": "^0.7.1",
35
35
  "@scure/bip39": "^2.4.0",
36
- "drizzle-orm": "^0.45.3",
36
+ "drizzle-orm": "^0.45.4",
37
37
  "loro-crdt": "^1.16.4",
38
- "zod": "^4.6.5"
38
+ "zod": "^4.6.7"
39
39
  }
40
40
  }
Binary file