enhance: fix exports and extend decoder input type support

This commit is contained in:
master 2025-03-17 02:01:19 +08:00
parent 34bdb046f0
commit bbc9c86531
5 changed files with 38 additions and 23 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "konoebml", "name": "konoebml",
"version": "0.1.0-rc.1", "version": "0.1.0-rc.2",
"description": "A modern JavaScript implementation of EBML RFC8794", "description": "A modern JavaScript implementation of EBML RFC8794",
"main": "./dist/index.cjs", "main": "./dist/index.cjs",
"module": "./dist/index.js", "module": "./dist/index.js",

View File

@ -5,8 +5,15 @@ import { decodeEbmlContent } from './decode-utils';
import { StreamFlushReason, UnreachableOrLogicError } from './errors'; import { StreamFlushReason, UnreachableOrLogicError } from './errors';
import { dataViewSlice } from './tools'; import { dataViewSlice } from './tools';
export type EbmlStreamDecoderChunkType =
| Uint8Array
| ArrayBuffer
| ArrayBufferLike;
export class EbmlDecodeStreamTransformer export class EbmlDecodeStreamTransformer
implements Transformer<ArrayBuffer, EbmlTagTrait>, FileDataViewController implements
Transformer<EbmlStreamDecoderChunkType, EbmlTagTrait>,
FileDataViewController
{ {
private _offset = 0; private _offset = 0;
private _buffer: Uint8Array = new Uint8Array(0); private _buffer: Uint8Array = new Uint8Array(0);
@ -122,17 +129,17 @@ export class EbmlDecodeStreamTransformer
} }
} }
notifyIdle() { private notifyIdle() {
if (this._tickIdleCallback) { if (this._tickIdleCallback) {
this._tickIdleCallback(); this._tickIdleCallback();
} }
} }
tryEnqueueToBuffer(item: EbmlTagTrait) { private tryEnqueueToBuffer(item: EbmlTagTrait) {
this._writeBuffer.enqueue(item); this._writeBuffer.enqueue(item);
} }
waitBufferRelease( private waitBufferRelease(
ctrl: TransformStreamDefaultController<EbmlTagTrait>, ctrl: TransformStreamDefaultController<EbmlTagTrait>,
isFlush: boolean isFlush: boolean
) { ) {
@ -144,7 +151,7 @@ export class EbmlDecodeStreamTransformer
} }
} }
async tick( private async tick(
ctrl: TransformStreamDefaultController<EbmlTagTrait>, ctrl: TransformStreamDefaultController<EbmlTagTrait>,
isFlush: boolean isFlush: boolean
) { ) {
@ -191,7 +198,7 @@ export class EbmlDecodeStreamTransformer
} }
async transform( async transform(
chunk: ArrayBuffer, chunk: EbmlStreamDecoderChunkType,
ctrl: TransformStreamDefaultController<EbmlTagTrait> ctrl: TransformStreamDefaultController<EbmlTagTrait>
): Promise<void> { ): Promise<void> {
if (chunk.byteLength === 0) { if (chunk.byteLength === 0) {
@ -202,7 +209,10 @@ export class EbmlDecodeStreamTransformer
); );
newBuffer.set(this._buffer, 0); newBuffer.set(this._buffer, 0);
newBuffer.set(new Uint8Array(chunk), this._buffer.byteLength); newBuffer.set(
chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk),
this._buffer.byteLength
);
this._buffer = newBuffer; this._buffer = newBuffer;
await this.tick(ctrl, false); await this.tick(ctrl, false);
@ -214,7 +224,7 @@ export class EbmlDecodeStreamTransformer
} }
export class EbmlStreamDecoder extends TransformStream< export class EbmlStreamDecoder extends TransformStream<
ArrayBuffer, EbmlStreamDecoderChunkType,
EbmlTagTrait EbmlTagTrait
> { > {
public readonly transformer: EbmlDecodeStreamTransformer; public readonly transformer: EbmlDecodeStreamTransformer;

View File

@ -5,14 +5,14 @@ import { EbmlMasterTag } from './models/tag-master';
import { EbmlTreeMasterNotMatchError, UnreachableOrLogicError } from './errors'; import { EbmlTreeMasterNotMatchError, UnreachableOrLogicError } from './errors';
export class EbmlEncodeStreamTransformer export class EbmlEncodeStreamTransformer
implements Transformer<EbmlTagTrait, ArrayBuffer> implements Transformer<EbmlTagTrait, Uint8Array>
{ {
stack = new Stack<[EbmlMasterTag, ArrayBuffer[]]>(); stack = new Stack<[EbmlMasterTag, Uint8Array[]]>();
_writeBuffer = new Queue<ArrayBuffer>(); _writeBuffer = new Queue<Uint8Array>();
_writeBufferTask: Promise<void> | undefined; _writeBufferTask: Promise<void> | undefined;
closed = false; closed = false;
tryEnqueueToBuffer(...frag: ArrayBuffer[]) { tryEnqueueToBuffer(...frag: Uint8Array[]) {
const top = this.stack.peek(); const top = this.stack.peek();
if (top) { if (top) {
top[1].push(...frag); top[1].push(...frag);
@ -24,21 +24,22 @@ export class EbmlEncodeStreamTransformer
} }
waitBufferRelease( waitBufferRelease(
ctrl: TransformStreamDefaultController<ArrayBuffer>, ctrl: TransformStreamDefaultController<Uint8Array>,
isFlush: boolean isFlush: boolean
) { ) {
while (this._writeBuffer.size) { while (this._writeBuffer.size) {
if (ctrl.desiredSize! <= 0 && !isFlush) { if (ctrl.desiredSize! <= 0 && !isFlush) {
break; break;
} }
ctrl.enqueue(this._writeBuffer.dequeue()); const pop = this._writeBuffer.dequeue();
ctrl.enqueue(pop);
} }
} }
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation> // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
async transform( async transform(
tag: EbmlTagTrait, tag: EbmlTagTrait,
ctrl: TransformStreamDefaultController<ArrayBuffer> ctrl: TransformStreamDefaultController<Uint8Array>
) { ) {
if (!(tag instanceof EbmlTagTrait)) { if (!(tag instanceof EbmlTagTrait)) {
throw new UnreachableOrLogicError('should only accept embl tag but not'); throw new UnreachableOrLogicError('should only accept embl tag but not');
@ -74,14 +75,14 @@ export class EbmlEncodeStreamTransformer
this.waitBufferRelease(ctrl, false); this.waitBufferRelease(ctrl, false);
} }
flush(ctrl: TransformStreamDefaultController<ArrayBuffer>) { flush(ctrl: TransformStreamDefaultController<Uint8Array>) {
this.waitBufferRelease(ctrl, true); this.waitBufferRelease(ctrl, true);
} }
} }
export class EbmlStreamEncoder extends TransformStream< export class EbmlStreamEncoder extends TransformStream<
EbmlTagTrait, EbmlTagTrait,
ArrayBuffer Uint8Array
> { > {
public readonly transformer: EbmlEncodeStreamTransformer; public readonly transformer: EbmlEncodeStreamTransformer;

View File

@ -11,7 +11,11 @@ export {
decodeEbmlTagHeader, decodeEbmlTagHeader,
decodeEbmlContent, decodeEbmlContent,
} from './decode-utils'; } from './decode-utils';
export { EbmlStreamDecoder, EbmlDecodeStreamTransformer } from './decoder'; export {
EbmlStreamDecoder,
EbmlDecodeStreamTransformer,
type EbmlStreamDecoderChunkType,
} from './decoder';
export { export {
EbmlStreamEncoder, EbmlStreamEncoder,
EbmlEncodeStreamTransformer, EbmlEncodeStreamTransformer,
@ -19,7 +23,8 @@ export {
export { export {
EbmlBlockLacing, EbmlBlockLacing,
EbmlTagIdEnum, EbmlTagIdEnum,
type EbmlElementType, EbmlElementType,
EbmlTagPosition,
type EbmlBinaryDataTagIdType, type EbmlBinaryDataTagIdType,
type EbmlMasterTagIdType, type EbmlMasterTagIdType,
type EbmlBlockTagIdType, type EbmlBlockTagIdType,
@ -32,7 +37,6 @@ export {
type EbmlUintDataTagIdType, type EbmlUintDataTagIdType,
type EbmlUtf8DataTagIdType, type EbmlUtf8DataTagIdType,
type EbmlTagIdType, type EbmlTagIdType,
EbmlTagPosition,
isEbmlBinaryDataTagId, isEbmlBinaryDataTagId,
isEbmlBlockTagId, isEbmlBlockTagId,
isEbmlDateDataTagId, isEbmlDateDataTagId,

View File

@ -15,10 +15,10 @@ process.setMaxListeners(Number.POSITIVE_INFINITY);
const createReadStream = (file: string) => const createReadStream = (file: string) =>
Readable.toWeb(fs.createReadStream(file), { Readable.toWeb(fs.createReadStream(file), {
strategy: { highWaterMark: 100, size: (chunk) => chunk.byteLength }, strategy: { highWaterMark: 100, size: (chunk) => chunk.byteLength },
}) as ReadableStream<ArrayBuffer>; }) as ReadableStream<Uint8Array>;
const makeDataStreamTest = const makeDataStreamTest =
(stream: () => ReadableStream<ArrayBuffer>) => (stream: () => ReadableStream<Uint8Array>) =>
async (cb: (tag: EbmlMasterTag | EbmlDataTag, done: () => void) => void) => { async (cb: (tag: EbmlMasterTag | EbmlDataTag, done: () => void) => void) => {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
stream() stream()