cesr
Version:
[](https://www.npmjs.com/package/cesr) [](https://github.com/lenkan/cesr-js/blob/main/LICENSE)
252 lines (251 loc) • 11.9 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Parser_instances, _Parser_buffer, _Parser_stack, _Parser_genus, _Parser_matter, _Parser_indexer, _Parser_readJSON, _Parser_readCesr, _Parser_processReadResult, _Parser_read;
import { CountCode_10, CountCode_20, IndexTable, MatterTable } from "./codes.js";
import { decodeUtf8, encodeUtf8 } from "./encoding-utf8.js";
import { decodeGenus, decodeVersionString } from "./encoding.js";
import { concat } from "./array-utils.js";
import { CodeTable } from "./code-table.js";
function isContextFinished(version, context) {
if (version === 1) {
switch (context.code) {
case CountCode_10.ControllerIdxSigs:
case CountCode_10.WitnessIdxSigs:
return context.frames === context.count;
case CountCode_10.SealSourceCouples:
case CountCode_10.FirstSeenReplayCouples:
case CountCode_10.NonTransReceiptCouples:
return context.frames === context.count * 2;
case CountCode_10.SealSourceTriples:
return context.frames === context.count * 3;
case CountCode_10.TransReceiptQuadruples:
return context.frames === context.count * 4;
case CountCode_10.TransIdxSigGroups:
// |pre|snu|dig|group of controller sigs
// So, we assume that this group is finished for simplicity, higher level code
// needs to verify the signatures anyway
return context.frames === context.count * 3;
case CountCode_10.TransLastIdxSigGroups:
// |pre|group of controller sigs
// So, we assume that this group is finished for simplicity, higher level code
// needs to verify the signatures anyway
return context.frames === context.count;
case CountCode_10.AttachmentGroup:
case CountCode_10.BigAttachmentGroup:
return context.n === context.count;
case CountCode_10.PathedMaterialGroup:
case CountCode_10.BigPathedMaterialGroup:
return context.n === context.count;
default:
throw new Error(`Cannot determine if group ${context.code} is finished`);
}
}
return context.n === context.count;
}
class Parser {
constructor(options = {}) {
_Parser_instances.add(this);
_Parser_buffer.set(this, void 0);
_Parser_stack.set(this, []);
_Parser_genus.set(this, void 0);
_Parser_matter.set(this, void 0);
_Parser_indexer.set(this, void 0);
__classPrivateFieldSet(this, _Parser_buffer, new Uint8Array(0), "f");
__classPrivateFieldSet(this, _Parser_matter, new CodeTable(MatterTable), "f");
__classPrivateFieldSet(this, _Parser_indexer, new CodeTable(IndexTable, { strict: true }), "f");
__classPrivateFieldSet(this, _Parser_genus, {
genus: "AAA",
major: options.version ?? 1,
minor: 0,
}, "f");
}
*parse(source) {
__classPrivateFieldSet(this, _Parser_buffer, concat(__classPrivateFieldGet(this, _Parser_buffer, "f"), source), "f");
while (__classPrivateFieldGet(this, _Parser_buffer, "f").length > 0) {
const result = __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_read).call(this, __classPrivateFieldGet(this, _Parser_buffer, "f"));
if (!result.frame) {
return null;
}
__classPrivateFieldGet(this, _Parser_instances, "m", _Parser_processReadResult).call(this, result);
if (result.frame.code === "JSON") {
yield {
type: "message",
code: "JSON",
text: result.frame.text,
};
}
else {
yield {
type: "cesr",
code: result.frame.code,
text: result.frame.text,
};
}
}
}
get finished() {
return __classPrivateFieldGet(this, _Parser_buffer, "f").length === 0 && __classPrivateFieldGet(this, _Parser_stack, "f").length === 0;
}
}
_Parser_buffer = new WeakMap(), _Parser_stack = new WeakMap(), _Parser_genus = new WeakMap(), _Parser_matter = new WeakMap(), _Parser_indexer = new WeakMap(), _Parser_instances = new WeakSet(), _Parser_readJSON = function _Parser_readJSON(input) {
if (input.length < 25) {
return { frame: null, n: 0 };
}
const version = decodeVersionString(input.slice(0, 24));
if (input.length < version.size) {
return { frame: null, n: 0 };
}
const frame = input.slice(0, version.size);
return {
frame: {
code: "JSON",
count: 0,
index: 0,
ondex: 0,
text: decodeUtf8(frame),
raw: frame,
},
n: version.size,
};
}, _Parser_readCesr = function _Parser_readCesr(input, context) {
if (!context) {
return __classPrivateFieldGet(this, _Parser_matter, "f").read(input);
}
switch (__classPrivateFieldGet(this, _Parser_genus, "f").genus) {
case "AAA":
switch (__classPrivateFieldGet(this, _Parser_genus, "f").major) {
case 1:
switch (context.code) {
case CountCode_10.ControllerIdxSigs:
case CountCode_10.WitnessIdxSigs:
return __classPrivateFieldGet(this, _Parser_indexer, "f").read(input);
default:
return __classPrivateFieldGet(this, _Parser_matter, "f").read(input);
}
default: {
switch (context.code) {
case CountCode_20.WitnessIdxSigs:
case CountCode_20.BigWitnessIdxSigs:
case CountCode_20.TransIdxSigGroups:
case CountCode_20.BigTransIdxSigGroups:
case CountCode_20.TransLastIdxSigGroups:
case CountCode_20.BigTransLastIdxSigGroups:
case CountCode_20.BigControllerIdxSigs:
case CountCode_20.ControllerIdxSigs:
return __classPrivateFieldGet(this, _Parser_indexer, "f").read(input);
default:
return __classPrivateFieldGet(this, _Parser_matter, "f").read(input);
}
}
}
default:
return __classPrivateFieldGet(this, _Parser_matter, "f").read(input);
}
}, _Parser_processReadResult = function _Parser_processReadResult(result) {
if (!result.frame) {
return;
}
__classPrivateFieldSet(this, _Parser_buffer, __classPrivateFieldGet(this, _Parser_buffer, "f").slice(result.n), "f");
for (const group of __classPrivateFieldGet(this, _Parser_stack, "f")) {
group.n += result.n / 4;
group.frames += 1;
}
while (__classPrivateFieldGet(this, _Parser_stack, "f").length > 0) {
const ctx = __classPrivateFieldGet(this, _Parser_stack, "f")[__classPrivateFieldGet(this, _Parser_stack, "f").length - 1];
if (isContextFinished(__classPrivateFieldGet(this, _Parser_genus, "f").major, ctx)) {
__classPrivateFieldGet(this, _Parser_stack, "f").pop();
}
else {
break;
}
}
if (result.frame.code.startsWith("-_")) {
const genus = decodeGenus(result.frame.text);
__classPrivateFieldSet(this, _Parser_genus, genus, "f");
}
else if (result.frame.code.startsWith("-")) {
__classPrivateFieldGet(this, _Parser_stack, "f").push({
code: result.frame.code,
count: result.frame.count,
frames: 0,
n: 0,
});
}
}, _Parser_read = function _Parser_read(input) {
if (__classPrivateFieldGet(this, _Parser_stack, "f").length === 0) {
const start = input[0] >> 5;
switch (start) {
case 0b000:
throw new Error(`Unsupported cold start byte ${input[0]}, annotated streams not implemented`);
case 0b001:
return __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_readCesr).call(this, input);
case 0b010:
throw new Error(`Unsupported cold start byte ${__classPrivateFieldGet(this, _Parser_buffer, "f")[0]}, op codes not implemented`);
case 0b011:
return __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_readJSON).call(this, input);
case 0b101:
throw new Error(`Unsupported cold start byte ${__classPrivateFieldGet(this, _Parser_buffer, "f")[0]}, CBOR decoding not implemented`);
case 0b100:
case 0b110:
throw new Error(`Unsupported cold start byte ${__classPrivateFieldGet(this, _Parser_buffer, "f")[0]}, MGPK decoding not implemented`);
case 0b111:
throw new Error(`Unsupported cold start byte ${__classPrivateFieldGet(this, _Parser_buffer, "f")[0]}, binary domain decoding not implemented`);
default:
throw new Error(`Unsupported cold start byte ${__classPrivateFieldGet(this, _Parser_buffer, "f")[0]}`);
}
}
return __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_readCesr).call(this, __classPrivateFieldGet(this, _Parser_buffer, "f"), __classPrivateFieldGet(this, _Parser_stack, "f")[__classPrivateFieldGet(this, _Parser_stack, "f").length - 1]);
};
/**
* Parses CESR frames from an incoming stream of bytes.
*
* @param input Incoming stream of bytes
* @returns An iterable of CESR frames
*/
export function* parseSync(input, options = {}) {
if (typeof input === "string") {
input = encodeUtf8(input);
}
const parser = new Parser(options);
for (const frame of parser.parse(input)) {
yield frame;
}
if (!parser.finished) {
throw new Error("Unexpected end of stream");
}
}
/**
* Parses CESR frames from an incoming stream of bytes.
*
* @param input Incoming stream of bytes
* @returns An async iterable of CESR frames
*/
export async function* parse(input, options) {
const parser = new Parser(options);
for await (const chunk of resolveInput(input)) {
for (const frame of parser.parse(chunk)) {
yield frame;
}
}
if (!parser.finished) {
throw new Error("Unexpected end of stream");
}
}
function resolveInput(input) {
if (typeof input === "string") {
return ReadableStream.from([encodeUtf8(input)]);
}
if (input instanceof Uint8Array) {
return ReadableStream.from([input]);
}
return input;
}