···11-import * as cbor from "@ipld/dag-cbor";
22-import { cborDecode, check, cidForCbor, schema, TID } from "@atp/common";
11+import {
22+ cidForLex,
33+ decode as decodeLexCbor,
44+ encode as encodeLexCbor,
55+ type LexValue as EncodableLexValue,
66+} from "@atp/lex/cbor";
77+import { asCid, type Cid } from "@atp/lex/data";
88+import { check, schema, TID } from "@atp/common";
39import * as crypto from "@atp/crypto";
410import type { Keypair } from "@atp/crypto";
55-import {
66- ipldToLex,
77- lexToIpld,
88- type LexValue,
99- type RepoRecord,
1010-} from "@atp/lexicon";
1111+import { BlobRef as LexiconBlobRef } from "@atp/lexicon";
1112import type { DataDiff } from "./data-diff.ts";
1213import {
1314 type Commit,
1415 type LegacyV2Commit,
1616+ type LexValue,
1517 type RecordCreateDescript,
1618 type RecordDeleteDescript,
1719 type RecordPath,
1820 type RecordUpdateDescript,
1921 type RecordWriteDescript,
2222+ type RepoInputRecord,
2323+ type RepoInputValue,
2424+ type RepoRecord,
2025 type UnsignedCommit,
2126 WriteOpAction,
2227} from "./types.ts";
2323-import type { CID } from "multiformats/basics";
24282529/**
2630 * Converts a DataDiff of a repo three arrays of RecordWriteDescripts,
···100104 unsigned: UnsignedCommit,
101105 keypair: Keypair,
102106): Commit => {
103103- const encoded = cbor.encode(unsigned);
107107+ const encoded = encodeLexCbor(
108108+ lexToCborValue(unsigned) as EncodableLexValue,
109109+ );
104110 const sig = keypair.sign(encoded);
105111 return {
106112 ...unsigned,
···117123 didKey: string,
118124): boolean => {
119125 const { sig, ...rest } = commit;
120120- const encoded = cbor.encode(rest);
126126+ const encoded = encodeLexCbor(
127127+ lexToCborValue(rest) as EncodableLexValue,
128128+ );
121129 return crypto.verifySignature(didKey, encoded, sig as Uint8Array);
122130};
123131132132+export const lexToCborValue = (value: RepoInputValue): unknown => {
133133+ if (Array.isArray(value)) {
134134+ return value.map((item) => lexToCborValue(item));
135135+ }
136136+ if (value && typeof value === "object") {
137137+ if (value instanceof LexiconBlobRef) {
138138+ return value.original;
139139+ }
140140+ if (asCid(value) || value instanceof Uint8Array) {
141141+ return value;
142142+ }
143143+ const mapped: Record<string, unknown> = {};
144144+ for (const [key, item] of Object.entries(value)) {
145145+ if (item !== undefined) {
146146+ mapped[key] = lexToCborValue(item);
147147+ }
148148+ }
149149+ return mapped;
150150+ }
151151+ return value;
152152+};
153153+124154/**
125155 * Converts CBOR-encoded bytes to a LexValue using {@linkcode ipldToLex}.
126156 */
127157export const cborToLex = (val: Uint8Array): LexValue => {
128128- return ipldToLex(cborDecode(val));
158158+ return decodeLexCbor(val) as LexValue;
129159};
130160131161/**
···140170 return parsed as RepoRecord;
141171};
142172143143-export const cidForRecord = async (val: LexValue): Promise<CID> => {
144144- return await cidForCbor(lexToIpld(val));
173173+export const cidForRecord = async (val: RepoInputRecord): Promise<Cid> => {
174174+ return await cidForLex(
175175+ lexToCborValue(val) as EncodableLexValue,
176176+ );
145177};
146178147179export const ensureV3Commit = (commit: LegacyV2Commit | Commit): Commit => {
+6-7
sync/events.ts
···11-import type { CID } from "multiformats/cid";
21import type { DidDocument } from "@atp/identity";
33-import type { RepoRecord } from "@atp/lexicon";
44-import type { BlockMap } from "@atp/repo";
22+import type { Cid } from "@atp/lex/data";
33+import type { BlockMap, RepoRecord } from "@atp/repo";
54import type { AtUri } from "@atp/syntax";
6576/** Broad sync event type for all sync events */
···2423export type CommitMeta = {
2524 seq: number;
2625 time: string;
2727- commit: CID;
2626+ commit: Cid;
2827 blocks: BlockMap;
2928 rev: string;
3029 uri: AtUri;
···4039export type Create = CommitMeta & {
4140 event: "create";
4241 record: RepoRecord;
4343- cid: CID;
4242+ cid: Cid;
4443};
45444645/** {@link CommitEvt} for record updates/edits */
4746export type Update = CommitMeta & {
4847 event: "update";
4948 record: RepoRecord;
5050- cid: CID;
4949+ cid: Cid;
5150};
52515352/** {@link CommitEvt} for record deletions */
···7271 time: string;
7372 event: "sync";
7473 did: string;
7575- cid: CID;
7474+ cid: Cid;
7675 rev: string;
7776 blocks: BlockMap;
7877};
+2-2
sync/firehose/index.ts
···11-import type { CID } from "multiformats/cid";
11+import type { Cid } from "@atp/lex/data";
22import type { WebSocketOptions } from "@atp/xrpc-server";
33import { createDeferrable, type Deferrable, wait } from "@atp/common";
44import {
···405405 };
406406 });
407407 const key = await idResolver.did.resolveAtprotoKey(did, forceKeyRefresh);
408408- const verifiedCids: Record<string, CID | null> = {};
408408+ const verifiedCids: Record<string, Cid | null> = {};
409409 try {
410410 const results = await verifyProofs(evt.blocks, claims, did, key);
411411 results.verified.forEach((op) => {
+5-5
sync/firehose/lexicons.ts
···11import type { IncomingMessage } from "node:http";
22-import type { CID } from "multiformats/cid";
22+import type { Cid } from "@atp/lex/data";
33import { type LexiconDoc, Lexicons } from "@atp/lexicon";
44import type { Auth, ErrorFrame } from "@atp/xrpc-server";
55···5151 /** The repo this event comes from. */
5252 repo: string;
5353 /** Repo commit object CID. */
5454- commit: CID;
5454+ commit: Cid;
5555 /** DEPRECATED -- unused. WARNING -- nullable and optional; stick with optional to ensure golang interoperability. */
5656- prev?: CID | null;
5656+ prev?: Cid | null;
5757 /** The rev of the emitted commit. Note that this information is also in the commit object included in blocks, unless this is a tooBig event. */
5858 rev: string;
5959 /** The rev of the last emitted commit from this repo (if any). */
···6161 /** CAR file containing relevant blocks, as a diff since the previous repo state. */
6262 blocks: Uint8Array;
6363 ops: RepoOp[];
6464- blobs: CID[];
6464+ blobs: Cid[];
6565 /** Timestamp of when this message was originally broadcast. */
6666 time: string;
6767 [k: string]: unknown;
···155155 action: "create" | "update" | "delete" | string;
156156 path: string;
157157 /** For creates and updates, the new record CID. For deletions, null. */
158158- cid: CID | null;
158158+ cid: Cid | null;
159159 [k: string]: unknown;
160160}
161161
+3-3
sync/tests/mock-relay.ts
···11-import type { CID } from "multiformats/cid";
11+import type { Cid } from "@atp/lex/data";
22import type { RepoEvent } from "../firehose/lexicons.ts";
3344export interface MockFirehoseServerOptions {
···167167 seq,
168168 time: new Date().toISOString(),
169169 repo,
170170- commit: mockCID as unknown as CID,
170170+ commit: mockCID as unknown as Cid,
171171 rev: `rev-${seq}`,
172172 ops: [{
173173 action,
174174 path: `${collection}/${rkey}`,
175175- cid: action === "delete" ? null : mockCID as unknown as CID,
175175+ cid: action === "delete" ? null : mockCID as unknown as Cid,
176176 }],
177177 blocks: new Uint8Array(
178178 JSON.stringify(record).split("").map((c) => c.charCodeAt(0)),