Suite of AT Protocol TypeScript libraries built on web standards
21
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 96 lines 2.5 kB view raw
1import { CID } from "multiformats/cid"; 2import { 3 check, 4 ipldToJson, 5 type IpldValue, 6 jsonToIpld, 7 type JsonValue, 8} from "@atp/common"; 9import { BlobRef, jsonBlobRef } from "./blob-refs.ts"; 10 11export type LexValue = 12 | IpldValue 13 | BlobRef 14 | Array<LexValue> 15 | { [key: string]: LexValue }; 16 17/** Record of LexValues */ 18export type RepoRecord = Record<string, LexValue>; 19 20// @NOTE avoiding use of check.is() here only because it makes 21// these implementations slow, and they often live in hot paths. 22 23export const lexToIpld = (val: LexValue): IpldValue => { 24 // walk arrays 25 if (Array.isArray(val)) { 26 return val.map((item) => lexToIpld(item)); 27 } 28 // objects 29 if (val && typeof val === "object") { 30 const obj = val as Record<string, LexValue>; 31 // convert blobs, leaving the original encoding so that we don't change CIDs on re-encode 32 if (val instanceof BlobRef) { 33 return val.original; 34 } 35 // retain cids & bytes 36 if (CID.asCID(val) || val instanceof Uint8Array) { 37 return val; 38 } 39 // walk plain objects 40 const toReturn: Record<string, IpldValue> = {}; 41 for (const key of Object.keys(val)) { 42 toReturn[key] = lexToIpld(obj[key]); 43 } 44 return toReturn; 45 } 46 // pass through 47 return val; 48}; 49 50export const ipldToLex = (val: IpldValue): LexValue => { 51 // map arrays 52 if (Array.isArray(val)) { 53 return val.map((item) => ipldToLex(item)); 54 } 55 // objects 56 if (val && typeof val === "object") { 57 // convert blobs, using hints to avoid expensive is() check 58 const obj = val as Record<string, unknown>; 59 if ( 60 (obj["$type"] === "blob" || 61 (typeof obj["cid"] === "string" && 62 typeof obj["mimeType"] === "string")) && 63 check.is(val, jsonBlobRef) 64 ) { 65 return BlobRef.fromJsonRef(val); 66 } 67 // retain cids, bytes 68 if (CID.asCID(val) || val instanceof Uint8Array) { 69 return val; 70 } 71 // map plain objects 72 const toReturn: Record<string, LexValue> = {}; 73 for (const key of Object.keys(val)) { 74 toReturn[key] = ipldToLex(obj[key]); 75 } 76 return toReturn; 77 } 78 // pass through 79 return val; 80}; 81 82export const lexToJson = (val: LexValue): JsonValue => { 83 return ipldToJson(lexToIpld(val)); 84}; 85 86export const stringifyLex = (val: LexValue): string => { 87 return JSON.stringify(lexToJson(val)); 88}; 89 90export const jsonToLex = (val: JsonValue): LexValue => { 91 return ipldToLex(jsonToIpld(val)); 92}; 93 94export const jsonStringToLex = (val: string): LexValue => { 95 return jsonToLex(JSON.parse(val)); 96};