UNPKG

@ceramicnetwork/core

Version:

Typescript implementation of the Ceramic protocol

98 lines 3.24 kB
import * as dagCBOR from '@ipld/dag-cbor'; import { create as createDigest } from 'multiformats/hashes/digest'; import * as sha256 from '@stablelib/sha256'; import * as uint8arrays from 'uint8arrays'; import { cidAsString, streamIdAsString } from '@ceramicnetwork/codecs'; import * as co from 'codeco'; class CIDAsStringMap extends co.Codec { constructor() { super('CIDAsStringMap'); } is(input) { return input instanceof Map; } encode(value) { const encoded = {}; for (const [key, val] of value.entries()) { encoded[key] = cidAsString.encode(val); } return encoded; } decode(input, context) { try { const decoded = new Map(); for (const [key, val] of Object.entries(input)) { const valValidation = cidAsString.decode(val, context); if (co.isValid(valValidation)) { decoded.set(key, valValidation.right); } else { return valValidation; } } return context.success(decoded); } catch (err) { return context.failure(err.message); } } } const cidAsStringMap = new CIDAsStringMap(); export var MsgType; (function (MsgType) { MsgType[MsgType["UPDATE"] = 0] = "UPDATE"; MsgType[MsgType["QUERY"] = 1] = "QUERY"; MsgType[MsgType["RESPONSE"] = 2] = "RESPONSE"; MsgType[MsgType["KEEPALIVE"] = 3] = "KEEPALIVE"; })(MsgType || (MsgType = {})); export const UpdateMessage = co.sparse({ typ: co.literal(MsgType.UPDATE), stream: streamIdAsString, tip: cidAsString, model: co.optional(streamIdAsString), }, 'UpdateMessage'); export const QueryMessage = co.strict({ typ: co.literal(MsgType.QUERY), id: co.string, stream: streamIdAsString, }, 'QueryMessage'); export const ResponseMessage = co.strict({ typ: co.literal(MsgType.RESPONSE), id: co.string, tips: cidAsStringMap, }, 'ResponseMessage'); export const KeepaliveMessage = co.strict({ typ: co.literal(MsgType.KEEPALIVE), ts: co.number, ver: co.string, ipfsVer: co.string, }, 'KeepaliveMessage'); export const PubsubMessage = co.union([UpdateMessage, QueryMessage, ResponseMessage, KeepaliveMessage], 'PubsubMessage'); const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder('utf-8'); function messageHash(message) { const encoded = dagCBOR.encode(message); const id = sha256.hash(encoded); return uint8arrays.toString(createDigest(0x12, id).bytes, 'base64url'); } export function buildQueryMessage(streamId) { const payload = { typ: MsgType.QUERY, stream: streamId, }; const id = messageHash({ ...payload, stream: streamId.toString() }); return { ...payload, id: id, }; } export function serialize(message) { const payload = PubsubMessage.encode(message); return textEncoder.encode(JSON.stringify(payload)); } export function deserialize(message) { const asString = textDecoder.decode(message.data); const parsed = JSON.parse(asString); return co.decode(PubsubMessage, parsed); } //# sourceMappingURL=pubsub-message.js.map