Я пытаюсь использовать некоторую библиотеку JS с ServiceWorker без доступа к функциям файловой системы Node.JS. Результат экспорта исходной библиотеки такой же.
Import * as fs from 'fs'
...
JsLib.export(result, fs.createWriteStream("res.pdf"))
Мне нужен тот же экспорт, но экспорт в байтовый массив без файловой системы. Я создал массив таким же образом
const Out = (Array as any).create("byte", mysize)
и если я вручную заполняю этот массив байтов тестовыми данными, мой алгоритм дальше работает нормально.
Но я не понимаю, как правильно создать такой же поток, как созданный Node.JS, но в памяти, в моем массиве «Out».
В MDN есть несколько примеров с WritableStream, но я не уверен, как эти примеры связаны с этой задачей. Возможно, есть дешевое решение, например
JsLib.export(result, ...Out)
Или это решение не эмулирует fs.createWriteStream? Непосредственное использование синтаксиса распространения невозможно: «Аргумент распространения должен либо иметь тип кортежа, либо быть передан в параметр rest». Но как правильно решить этот квест?
Обновление. Это ответ @l3l_aze с очень простым тестом, к сожалению, это решение не работает.
@l3l_aze, это моя общая проблема при работе с сервис-воркером. В данном случае мне нужно решить эту проблему с помощью библиотеки pureimage.
Можете ли вы включить больше кода? Это должно быть просто, но нам нужно знать, как вы получаете данные. Последний пример в README pureimage (чуть выше «Устранение неполадок») использует буфер, который выглядит примерно так, как вам хотелось бы. В JS мы бы использовали ArrayBuffer . Затем используйте DataView, чтобы проверить магическое значение/маску файла.
IDK TS или pureimage, но, возможно, стоит попробовать JsLib.export(result, new ArrayBuffer(Out)).
@l3l_aze, спасибо, я добавляю очень простой тест, к сожалению, arrayBuffer не может заменить поток выходной памяти






Как я уже сказал выше, я не знаю TS, так что это просто NodeJS/ванильный JS. Настоятельно рекомендую изучить это больше, чем пару часов, которые я потратил, поскольку, возможно, поток не закрывается должным образом, и, очевидно, не предусмотрена обработка ошибок.
Однако на выходе получается красный квадрат в формате PNG. Чтобы визуально подтвердить тест, я скопировал выходные данные и использовал расширение VSCode Hex Editor, чтобы вставить их в существующий file.png с выбранной опцией base64. Затем пришлось удалить (Del, а не Backspace) оставшиеся байты из предыдущих данных, которыми мне пришлось их заполнить, чтобы шестнадцатеричный редактор позволял вставить. Ржу не могу.
'use strict'
import * as PImage from 'pureimage'
import Stream from 'stream'
const width = 32
const height = 32
const img1 = PImage.make(width, height)
const ctx = img1.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, width, height)
const pngData = []
const dest = new Stream()
dest.writable = true
dest.write = function (data) {
for (let i = 0; i < data.length; i++) {
dest.emit('data', data[i])
}
}
// Act like a passThrough stream; in one ear and out the other.
dest.on('data', (chunk) => {
pngData.push(chunk)
})
dest.on('end', () => {})
// For
// https://github.com/joshmarinacci/node-pureimage/blob/6775bc3dedfd4247c0ee11382e1aebdf2703ca45/src/image.ts#L57
dest.end = function () {
dest.emit('finish')
}
dest.close = function () {
dest.emit('close')
}
function assert (a, b) {
if (a !== b) {
throw new Error(`${a} !== ${b}`)
} else {
return true
}
}
const buf = await PImage.encodePNGToStream(img1, dest).then(() => {
return new Uint8Array(pngData)
})
if (assert(buf[0], 0x89) &&
assert(buf[1], 0x50) &&
assert(buf[2], 0x4e) &&
assert(buf[3], 0x47)) {
console.info('buffer contains png header')
const ascii = Array.from(buf).map((b) => String.fromCharCode(b))
const b64 = btoa(ascii.join(''))
console.info(b64)
// iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAklEQVR4AewaftIAAABBSURBVMXBAQEAAAiDMKR/5xuD7QYjJDGJSUxiEpOYxCQmMYlJTGISk5jEJCYxiUlMYhKTmMQkJjGJSUxiEpOYxB4w4wI+EhsQ6
AAAAABJRU5ErkJggg==
}
Было бы хорошо указать хотя бы название библиотеки, которую вы используете. NodeJS гораздо более низкий уровень, чем JS в веб-браузере, поэтому, несмотря на то, что оба имеют потоки, они не обязательно эквивалентны. Соответствующий вопрос; видимо потоки похожи.