UNPKG

@bitrix24/b24jssdk

Version:

Bitrix24 REST API JavaScript SDK

1 lines • 14.9 kB
{"version":3,"file":"wire.mjs","sources":["../../../../src/pullClient/protobuf-lite/wire.ts"],"sourcesContent":["/**\n * The protobuf wire primitives this codec needs, and nothing else.\n *\n * The schema it serves has no `required` fields, no packed repeats, no maps and\n * no 64-bit numbers — only `bytes`, `string`, `bool`, `uint32`, one `fixed32`\n * and nested messages. That is why about 5 kB minified — `wire` and `messages`\n * together — replaces the 94 kB vendored `protobuf/` directory (79 kB of it is protobuf.js itself, the rest\n * is the generated model); it is also why this file must never grow to cover protobuf\n * in general. If a new field type appears in `pull.proto`, add it here\n * deliberately. The doc records how those figures are measured.\n *\n * Restored from the box's own descriptors (`modules/pull/lib/protobuf/*.php`),\n * not reverse-engineered from traffic — see `.github/contributing/pull-protobuf.md`.\n */\n\n/**\n * The input is not a well-formed protobuf frame — and nothing else.\n *\n * A dedicated type so that a caller recovering from a damaged frame can catch\n * exactly this and let everything else through. Catching bare `Error` there\n * would also swallow a bug in a field handler, silently, on precisely the\n * inputs nobody thought to test.\n */\nexport class WireError extends Error {\n override name = 'WireError'\n}\n\nexport const WIRE_VARINT = 0\nexport const WIRE_BYTES = 2\nexport const WIRE_FIXED32 = 5\nconst WIRE_START_GROUP = 3\nconst WIRE_END_GROUP = 4\nconst MAX_GROUP_DEPTH = 64\n\n/** `key = (fieldNumber << 3) | wireType`, the tag every field is prefixed with. */\nexport function tag(fieldNumber: number, wireType: number): number {\n return (fieldNumber << 3) | wireType\n}\n\nexport class Writer {\n // A growing `Uint8Array`, not a `number[]`. The array version was measurably\n // superlinear: each of the four nesting levels copied its child byte by byte\n // through `push`, and `Uint8Array.from` then copied the lot again — 106 ms for\n // a 1000-message batch against protobuf.js's 3.4 ms, and 267 ms for a 2 MB\n // body. Irrelevant for the single-message batches this client usually sends,\n // and a main-thread stall for the ones it occasionally does.\n #buffer = new Uint8Array(64)\n #length = 0\n\n get length(): number {\n return this.#length\n }\n\n #reserve(extra: number): void {\n const needed = this.#length + extra\n if (needed <= this.#buffer.length) {\n return\n }\n let size = this.#buffer.length * 2\n while (size < needed) {\n size *= 2\n }\n const grown = new Uint8Array(size)\n grown.set(this.#buffer.subarray(0, this.#length))\n this.#buffer = grown\n }\n\n #push(byte: number): void {\n this.#reserve(1)\n this.#buffer[this.#length++] = byte\n }\n\n varint(value: number): this {\n // Values written here are lengths, tags, `uint32` fields and booleans — all\n // non-negative and within 32 bits, so no zig-zag and no 64-bit path. A\n // negative would be written as its unsigned 32-bit form rather than\n // sign-extended to ten bytes the way protobuf.js writes `int32`; nothing in\n // this schema has a signed field whose values go negative (`SenderType` is\n // 0/1/2), and that difference is recorded in `pull-protobuf.md`.\n let rest = value >>> 0\n while (rest > 0x7F) {\n this.#push((rest & 0x7F) | 0x80)\n rest >>>= 7\n }\n this.#push(rest)\n\n return this\n }\n\n fixed32(value: number): this {\n const v = value >>> 0\n this.#reserve(4)\n this.#buffer[this.#length++] = v & 0xFF\n this.#buffer[this.#length++] = (v >>> 8) & 0xFF\n this.#buffer[this.#length++] = (v >>> 16) & 0xFF\n this.#buffer[this.#length++] = (v >>> 24) & 0xFF\n\n return this\n }\n\n bytes(value: Uint8Array): this {\n this.varint(value.length)\n this.#reserve(value.length)\n this.#buffer.set(value, this.#length)\n this.#length += value.length\n\n return this\n }\n\n string(value: string): this {\n // `TextEncoder` replaces an unpaired surrogate with U+FFFD, where\n // protobuf.js emits the code point as WTF-8. Unreachable from this client —\n // the only strings encoded are `JSON.stringify` output, which escapes lone\n // surrogates since ES2019 — but it is a real difference from the oracle and\n // is written down rather than left to be discovered.\n return this.bytes(new TextEncoder().encode(value))\n }\n\n finish(): Uint8Array {\n return this.#buffer.slice(0, this.#length)\n }\n}\n\nexport class Reader {\n #view: Uint8Array\n #pos = 0\n\n constructor(view: Uint8Array) {\n this.#view = view\n }\n\n get done(): boolean {\n return this.#pos >= this.#view.length\n }\n\n /**\n * A varint of up to ten bytes — protobuf's full legal width.\n *\n * The ceiling was 35 bits, which made this codec LESS forward-compatible than\n * the library it replaces: an unknown `uint64` field above 2^35 threw, and\n * because `extractProtobufMessages` swallows the throw, the whole frame was\n * dropped where protobuf.js would have skipped the field and carried on. The\n * symptom would have been \"connected, no events\".\n *\n * Above 2^53 the value is no longer exact. That is acceptable only because\n * every caller either masks it (`uint32`) or discards it (`skip`); nothing in\n * this schema is a 64-bit field.\n */\n varint(): number {\n let result = 0\n let shift = 0\n for (;;) {\n if (this.done) {\n throw new WireError('pull protobuf: truncated varint')\n }\n const byte = this.#view[this.#pos++]!\n result += (byte & 0x7F) * 2 ** shift\n if ((byte & 0x80) === 0) {\n return result\n }\n shift += 7\n if (shift >= 70) {\n throw new WireError('pull protobuf: varint longer than ten bytes')\n }\n }\n }\n\n /**\n * A `uint32` field, truncated the way protobuf.js truncates it.\n *\n * Without the mask a wire value of 2^32 read back as 4294967296 where the\n * library gives 0 — the two codecs disagreeing on a well-formed frame.\n */\n uint32(): number {\n return this.varint() >>> 0\n }\n\n fixed32(): number {\n if (this.#pos + 4 > this.#view.length) {\n throw new WireError('pull protobuf: truncated fixed32')\n }\n const v = this.#view[this.#pos]! | (this.#view[this.#pos + 1]! << 8)\n | (this.#view[this.#pos + 2]! << 16) | (this.#view[this.#pos + 3]! << 24)\n this.#pos += 4\n\n return v >>> 0\n }\n\n bytes(): Uint8Array {\n const length = this.varint()\n if (this.#pos + length > this.#view.length) {\n throw new WireError('pull protobuf: length-delimited field runs past the end')\n }\n const out = this.#view.subarray(this.#pos, this.#pos + length)\n this.#pos += length\n\n return out\n }\n\n string(): string {\n return new TextDecoder().decode(this.bytes())\n }\n\n /**\n * Skip a field this codec does not model — the statistics branches, and\n * anything a future server adds. Unknown fields are ordinary protobuf, not an\n * error: the vendored library ignored them silently and so must this.\n *\n * The throws below are not \"give up\". `readFields` catches them and stops\n * reading that message, so a damaged tail costs the fields after it and\n * nothing else. Throwing is how this reader says \"I cannot go further\", not\n * how it reports a failure to its caller — and it is always a `WireError`,\n * which is the only thing `readFields` catches.\n */\n skip(wireType: number, depth = 0): void {\n switch (wireType) {\n case WIRE_VARINT: {\n this.varint()\n break\n }\n case WIRE_BYTES: {\n this.bytes()\n break\n }\n case WIRE_FIXED32: {\n this.fixed32()\n break\n }\n case 1: {\n // 64-bit. Nothing in this schema uses it; skipped rather than thrown so\n // an unknown future field cannot break a working connection. The bounds\n // check stays: `readFields` turns a throw here into \"stop reading this\n // message\", which keeps what parsed, where advancing the cursor past\n // the end would read garbage as the fields after it.\n if (this.#pos + 8 > this.#view.length) {\n throw new WireError('pull protobuf: truncated 64-bit field')\n }\n this.#pos += 8\n break\n }\n case WIRE_START_GROUP: {\n // Groups are deprecated and no push server sends them. They are\n // skipped anyway because protobuf.js skips them, and reporting a\n // well-formed frame as damaged — dropping the fields after it — would\n // be a divergence in the wrong direction. Skipped to the matching end\n // tag, as the library does; a lone end tag is malformed there too.\n this.#skipGroup(depth)\n break\n }\n default: {\n throw new WireError(`pull protobuf: unsupported wire type ${wireType}`)\n }\n }\n }\n\n #skipGroup(depth: number): void {\n // protobuf.js has no limit here and overflows the stack on deep nesting.\n // A frame nested this deep is malformed by any reasonable standard.\n if (depth >= MAX_GROUP_DEPTH) {\n throw new WireError('pull protobuf: groups nested too deeply')\n }\n for (;;) {\n const wireType = this.varint() & 7\n if (wireType === WIRE_END_GROUP) {\n return\n }\n this.skip(wireType, depth + 1)\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;AAuBO,MAAM,kBAAkB,KAAA,CAAM;AAAA,EAvBrC;AAuBqC,IAAA,MAAA,CAAA,IAAA,EAAA,WAAA,CAAA;AAAA;AAAA,EAC1B,IAAA,GAAO,WAAA;AAClB;AAEO,MAAM,WAAA,GAAc;AACpB,MAAM,UAAA,GAAa;AACnB,MAAM,YAAA,GAAe;AAC5B,MAAM,gBAAA,GAAmB,CAAA;AACzB,MAAM,cAAA,GAAiB,CAAA;AACvB,MAAM,eAAA,GAAkB,EAAA;AAGjB,SAAS,GAAA,CAAI,aAAqB,QAAA,EAA0B;AACjE,EAAA,OAAQ,eAAe,CAAA,GAAK,QAAA;AAC9B;AAFgB,MAAA,CAAA,GAAA,EAAA,KAAA,CAAA;AAIT,MAAM,MAAA,CAAO;AAAA,EAvCpB;AAuCoB,IAAA,MAAA,CAAA,IAAA,EAAA,QAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlB,OAAA,GAAU,IAAI,UAAA,CAAW,EAAE,CAAA;AAAA,EAC3B,OAAA,GAAU,CAAA;AAAA,EAEV,IAAI,MAAA,GAAiB;AACnB,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,SAAS,KAAA,EAAqB;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAK,OAAA,GAAU,KAAA;AAC9B,IAAA,IAAI,MAAA,IAAU,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ;AACjC,MAAA;AAAA,IACF;AACA,IAAA,IAAI,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,CAAA;AACjC,IAAA,OAAO,OAAO,MAAA,EAAQ;AACpB,MAAA,IAAA,IAAQ,CAAA;AAAA,IACV;AACA,IAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,IAAI,CAAA;AACjC,IAAA,KAAA,CAAM,IAAI,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,EAAG,IAAA,CAAK,OAAO,CAAC,CAAA;AAChD,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AAAA,EACjB;AAAA,EAEA,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAA,CAAK,SAAS,CAAC,CAAA;AACf,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAS,CAAA,GAAI,IAAA;AAAA,EACjC;AAAA,EAEA,OAAO,KAAA,EAAqB;AAO1B,IAAA,IAAI,OAAO,KAAA,KAAU,CAAA;AACrB,IAAA,OAAO,OAAO,GAAA,EAAM;AAClB,MAAA,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,GAAA,GAAQ,GAAI,CAAA;AAC/B,MAAA,IAAA,MAAU,CAAA;AAAA,IACZ;AACA,IAAA,IAAA,CAAK,MAAM,IAAI,CAAA;AAEf,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,QAAQ,KAAA,EAAqB;AAC3B,IAAA,MAAM,IAAI,KAAA,KAAU,CAAA;AACpB,IAAA,IAAA,CAAK,SAAS,CAAC,CAAA;AACf,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAS,CAAA,GAAI,CAAA,GAAI,GAAA;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAS,CAAA,GAAK,MAAM,CAAA,GAAK,GAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAS,CAAA,GAAK,MAAM,EAAA,GAAM,GAAA;AAC5C,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAS,CAAA,GAAK,MAAM,EAAA,GAAM,GAAA;AAE5C,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAA,EAAyB;AAC7B,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,MAAM,CAAA;AACxB,IAAA,IAAA,CAAK,QAAA,CAAS,MAAM,MAAM,CAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AACpC,IAAA,IAAA,CAAK,WAAW,KAAA,CAAM,MAAA;AAEtB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,OAAO,KAAA,EAAqB;AAM1B,IAAA,OAAO,KAAK,KAAA,CAAM,IAAI,aAAY,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EACnD;AAAA,EAEA,MAAA,GAAqB;AACnB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,KAAK,OAAO,CAAA;AAAA,EAC3C;AACF;AAEO,MAAM,MAAA,CAAO;AAAA,EA3HpB;AA2HoB,IAAA,MAAA,CAAA,IAAA,EAAA,QAAA,CAAA;AAAA;AAAA,EAClB,KAAA;AAAA,EACA,IAAA,GAAO,CAAA;AAAA,EAEP,YAAY,IAAA,EAAkB;AAC5B,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,EACf;AAAA,EAEA,IAAI,IAAA,GAAgB;AAClB,IAAA,OAAO,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,MAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAA,GAAiB;AACf,IAAA,IAAI,MAAA,GAAS,CAAA;AACb,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,WAAS;AACP,MAAA,IAAI,KAAK,IAAA,EAAM;AACb,QAAA,MAAM,IAAI,UAAU,iCAAiC,CAAA;AAAA,MACvD;AACA,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AACnC,MAAA,MAAA,IAAA,CAAW,IAAA,GAAO,OAAQ,CAAA,IAAK,KAAA;AAC/B,MAAA,IAAA,CAAK,IAAA,GAAO,SAAU,CAAA,EAAG;AACvB,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,KAAA,IAAS,CAAA;AACT,MAAA,IAAI,SAAS,EAAA,EAAI;AACf,QAAA,MAAM,IAAI,UAAU,6CAA6C,CAAA;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAA,GAAiB;AACf,IAAA,OAAO,IAAA,CAAK,QAAO,KAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,OAAA,GAAkB;AAChB,IAAA,IAAI,IAAA,CAAK,IAAA,GAAO,CAAA,GAAI,IAAA,CAAK,MAAM,MAAA,EAAQ;AACrC,MAAA,MAAM,IAAI,UAAU,kCAAkC,CAAA;AAAA,IACxD;AACA,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAI,IAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,CAAC,CAAA,IAAM,IAC7D,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,CAAC,CAAA,IAAM,EAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,CAAC,CAAA,IAAM,EAAA;AACxE,IAAA,IAAA,CAAK,IAAA,IAAQ,CAAA;AAEb,IAAA,OAAO,CAAA,KAAM,CAAA;AAAA,EACf;AAAA,EAEA,KAAA,GAAoB;AAClB,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,EAAO;AAC3B,IAAA,IAAI,IAAA,CAAK,IAAA,GAAO,MAAA,GAAS,IAAA,CAAK,MAAM,MAAA,EAAQ;AAC1C,MAAA,MAAM,IAAI,UAAU,yDAAyD,CAAA;AAAA,IAC/E;AACA,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAM,QAAA,CAAS,KAAK,IAAA,EAAM,IAAA,CAAK,OAAO,MAAM,CAAA;AAC7D,IAAA,IAAA,CAAK,IAAA,IAAQ,MAAA;AAEb,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,MAAA,GAAiB;AACf,IAAA,OAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,IAAA,CAAK,QAAA,EAAkB,KAAA,GAAQ,CAAA,EAAS;AACtC,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,WAAA,EAAa;AAChB,QAAA,IAAA,CAAK,MAAA,EAAO;AACZ,QAAA;AAAA,MACF;AAAA,MACA,KAAK,UAAA,EAAY;AACf,QAAA,IAAA,CAAK,KAAA,EAAM;AACX,QAAA;AAAA,MACF;AAAA,MACA,KAAK,YAAA,EAAc;AACjB,QAAA,IAAA,CAAK,OAAA,EAAQ;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,CAAA,EAAG;AAMN,QAAA,IAAI,IAAA,CAAK,IAAA,GAAO,CAAA,GAAI,IAAA,CAAK,MAAM,MAAA,EAAQ;AACrC,UAAA,MAAM,IAAI,UAAU,uCAAuC,CAAA;AAAA,QAC7D;AACA,QAAA,IAAA,CAAK,IAAA,IAAQ,CAAA;AACb,QAAA;AAAA,MACF;AAAA,MACA,KAAK,gBAAA,EAAkB;AAMrB,QAAA,IAAA,CAAK,WAAW,KAAK,CAAA;AACrB,QAAA;AAAA,MACF;AAAA,MACA,SAAS;AACP,QAAA,MAAM,IAAI,SAAA,CAAU,CAAA,qCAAA,EAAwC,QAAQ,CAAA,CAAE,CAAA;AAAA,MACxE;AAAA;AACF,EACF;AAAA,EAEA,WAAW,KAAA,EAAqB;AAG9B,IAAA,IAAI,SAAS,eAAA,EAAiB;AAC5B,MAAA,MAAM,IAAI,UAAU,yCAAyC,CAAA;AAAA,IAC/D;AACA,IAAA,WAAS;AACP,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,EAAO,GAAI,CAAA;AACjC,MAAA,IAAI,aAAa,cAAA,EAAgB;AAC/B,QAAA;AAAA,MACF;AACA,MAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,KAAA,GAAQ,CAAC,CAAA;AAAA,IAC/B;AAAA,EACF;AACF;;;;"}