Skip to main content
Module

x/cbor/iterators.js

Ultra-fast CBOR encoder/decoder with extensions for records and structural cloning
Very Popular
Latest
File
import { Encoder } from './encode.js'import { Decoder } from './decode.js'
/** * Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer * If the argument is only Async Iterable, the return value will be an Async Iterable. * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object * @param {options} [options] - cbor-x Encoder options * @returns {IterableIterator|Promise.<AsyncIterableIterator>} */export function encodeIter (objectIterator, options = {}) { if (!objectIterator || typeof objectIterator !== 'object') { throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable') } else if (typeof objectIterator[Symbol.iterator] === 'function') { return encodeIterSync(objectIterator, options) } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') { return encodeIterAsync(objectIterator, options) } else { throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise') }}
function * encodeIterSync (objectIterator, options) { const encoder = new Encoder(options) for (const value of objectIterator) { yield encoder.encode(value) }}
async function * encodeIterAsync (objectIterator, options) { const encoder = new Encoder(options) for await (const value of objectIterator) { yield encoder.encode(value) }}
/** * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator. * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator * @param {object} [options] - Decoder options * @returns {IterableIterator|Promise.<AsyncIterableIterator} */export function decodeIter (bufferIterator, options = {}) { if (!bufferIterator || typeof bufferIterator !== 'object') { throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise') }
const decoder = new Decoder(options) let incomplete const parser = (chunk) => { let yields // if there's incomplete data from previous chunk, concatinate and try again if (incomplete) { chunk = Buffer.concat([incomplete, chunk]) incomplete = undefined }
try { yields = decoder.decodeMultiple(chunk) } catch (err) { if (err.incomplete) { incomplete = chunk.slice(err.lastPosition) yields = err.values } else { throw err } } return yields }
if (typeof bufferIterator[Symbol.iterator] === 'function') { return (function * iter () { for (const value of bufferIterator) { yield * parser(value) } })() } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') { return (async function * iter () { for await (const value of bufferIterator) { yield * parser(value) } })() }}