@atproto/repo
Version:
atproto repo and MST implementation
228 lines (194 loc) • 4.68 kB
text/typescript
import { z } from 'zod'
import { Cid, LexMap, ifCid } from '@atproto/lex-data'
import { NsidString, RecordKeyString } from '@atproto/syntax'
import { BlockMap } from './block-map.js'
import { CidSet } from './cid-set.js'
// Repo nodes
// ---------------
const cidSchema = z.unknown().transform((input, ctx): Cid => {
const cid = ifCid(input)
if (cid) return cid
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Not a valid CID',
})
return z.NEVER
})
const _unsignedCommit = z.object({
did: z.string(),
version: z.literal(3),
data: cidSchema,
rev: z.string(),
// `prev` added for backwards compatibility with v2, no requirement of keeping around history
prev: cidSchema.nullable(),
})
export type UnsignedCommit = z.infer<typeof _unsignedCommit> & { sig?: never }
const commit = z.object({
did: z.string(),
version: z.literal(3),
data: cidSchema,
rev: z.string(),
prev: cidSchema.nullable(),
sig: z.instanceof(Uint8Array<ArrayBufferLike>),
})
export type Commit = z.infer<typeof commit>
const legacyV2Commit = z.object({
did: z.string(),
version: z.literal(2),
data: cidSchema,
rev: z.string().optional(),
prev: cidSchema.nullable(),
sig: z.instanceof(Uint8Array<ArrayBufferLike>),
})
export type LegacyV2Commit = z.infer<typeof legacyV2Commit>
const versionedCommit = z.discriminatedUnion('version', [
commit,
legacyV2Commit,
])
export type VersionedCommit = z.infer<typeof versionedCommit>
export const schema = {
cid: cidSchema,
carHeader: z.object({
version: z.literal(1),
roots: z.array(cidSchema),
}),
bytes: z.instanceof(Uint8Array<ArrayBufferLike>),
string: z.string(),
array: z.array(z.unknown()),
map: z.record(z.string(), z.unknown()),
unknown: z.unknown(),
commit,
legacyV2Commit,
versionedCommit,
}
export const def = {
cid: {
name: 'cid',
schema: schema.cid,
},
carHeader: {
name: 'CAR header',
schema: schema.carHeader,
},
bytes: {
name: 'bytes',
schema: schema.bytes,
},
string: {
name: 'string',
schema: schema.string,
},
map: {
name: 'map',
schema: schema.map,
},
unknown: {
name: 'unknown',
schema: schema.unknown,
},
commit: {
name: 'commit',
schema: schema.commit,
},
versionedCommit: {
name: 'versioned_commit',
schema: schema.versionedCommit,
},
}
// Repo Operations
// ---------------
export enum WriteOpAction {
Create = 'create',
Update = 'update',
Delete = 'delete',
}
export type RecordCreateOp = {
action: WriteOpAction.Create
collection: NsidString
rkey: RecordKeyString
record: LexMap
}
export type RecordUpdateOp = {
action: WriteOpAction.Update
collection: NsidString
rkey: RecordKeyString
record: LexMap
}
export type RecordDeleteOp = {
action: WriteOpAction.Delete
collection: NsidString
rkey: RecordKeyString
}
export type RecordWriteOp = RecordCreateOp | RecordUpdateOp | RecordDeleteOp
export type RecordCreateDescript = {
action: WriteOpAction.Create
collection: NsidString
rkey: RecordKeyString
cid: Cid
}
export type RecordUpdateDescript = {
action: WriteOpAction.Update
collection: NsidString
rkey: RecordKeyString
prev: Cid
cid: Cid
}
export type RecordDeleteDescript = {
action: WriteOpAction.Delete
collection: NsidString
rkey: RecordKeyString
cid: Cid
}
export type RecordWriteDescript =
| RecordCreateDescript
| RecordUpdateDescript
| RecordDeleteDescript
export type WriteLog = RecordWriteDescript[][]
// Updates/Commits
// ---------------
export type CommitData = {
cid: Cid
rev: string
since: string | null
prev: Cid | null
newBlocks: BlockMap
relevantBlocks: BlockMap
removedCids: CidSet
}
export type RepoUpdate = CommitData & {
ops: RecordWriteOp[]
}
export type CollectionContents = Record<string, LexMap>
export type RepoContents = Record<NsidString, CollectionContents>
export type RepoRecordWithCid = { cid: Cid; value: LexMap }
export type CollectionContentsWithCids = Record<string, RepoRecordWithCid>
export type RepoContentsWithCids = Record<string, CollectionContentsWithCids>
export type DatastoreContents = Record<string, Cid>
export type RecordPath = {
collection: string
rkey: string
}
export type RecordCidClaim = {
collection: string
rkey: string
cid: Cid | null
}
export type RecordClaim = {
collection: string
rkey: string
record: LexMap | null
}
// Sync
// ---------------
export type VerifiedDiff = {
writes: RecordWriteDescript[]
commit: CommitData
}
export type VerifiedRepo = {
creates: RecordCreateDescript[]
commit: CommitData
}
export type CarBlock = {
cid: Cid
bytes: Uint8Array
}