1.0.3 • Published 8 months ago

@se-puu/qpack v1.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

QPack Library

A versatile and lightweight JavaScript library offering a robust API.

Overview

QPack Library provides robust features for both data encoding and decoding, simplifying complex data manipulation tasks for modern web and server-side applications.

The library’s encoder transforms intricate data structures into compact, optimized formats for efficient transmission and storage. Conversely, the decoder reconstructs the original data from these encoded formats, ensuring integrity and consistency throughout the process.

Whether you need to compress data for fast network transfers or quickly restore original data for processing, QPack’s encoder and decoder functionalities deliver performance and reliability.

supported

  • javascript
  • C/C++ (coming soon)
  • Rust (coming soon)
  • Python (coming soon)

Table of Contents

Installation

Install via npm:

npm install @se-puu/qpack

API Documentation

EncodeableBinary

QEncoder and QDecoder supported binary types.

  • Uint8ClampedArray
  • Uint8Array
  • Uint16Array
  • Uint32Array
  • BigUint64Array
  • Int8Array
  • Int16Array
  • Int32Array
  • BigInt64Array
  • Float32Array
  • Float64Array
  • DataView

Encodeable

This is supported data types for QEncoder and QDecoder.

QEncoder

Creates an encoder instance that maintains its own configuration. Each instance stores settings independently, allowing for tailored behavior without impacting other encoders.

static create(option?: QEncoderOption): QEncoder

Create encoder instance with option.

encode(data: Encodeable): Uint8Array

Encode the data and return the copied encoded buffer.

encodeOnly(data: Encodeable): number

Encode the data and return the length of encoded data without exporting encoded data.

export(): Uint8Array | undefined

Export copied encoded data.

exportInto(target: Uint8Array):void

Copy encoded data into the target buffer. Target buffer must be larger than the encoded data.

length: number

The length of the current encoded buffer.

reset()

Reset the encoder state.Release the hold buffer and other data inside encoder.

write(data: Encodeable): boolean

Manually write encodable data into the encoder. Returns true if successful; otherwise, returns false.

writeNull(): boolean

Manually write undefined into the encoder. If success, will return true. Other case will retrun false.

writeBoolean(data: boolean): boolean

Manually write boolean into the encoder. If success, will return true. Other case will retrun false.

writeNumber(data: number): boolean

Manually write number into the encoder. If success, will return true. Other case will retrun false.

writeString(data: string): boolean

Manually write string into the encoder. If success, will return true. Other case will retrun false.

writeBigInt(data: bigint): boolean

Manually write bigint into the encoder. If success, will return true. Other case will retrun false.

writeTimestamp(data: Date): boolean

Manually write timestamp in milisecond into the encoder. If success, will return true. Other case will retrun false.

writeBinary(data: EncodeableBinary): boolean

Manually write binary into the encoder. If success, will return true. Other case will retrun false.

writeArray(data: Encodeable[]): boolean

Manually write an array into the encoder. If success, will return true. Other case will retrun false.

writeObject(data: object): boolean

Manually write an object into the encoder. If success, will return true. Other case will retrun false.

writeMap(data: Map): boolean

Manually write an javascript Map into the encoder. If success, will return true. Other case will retrun false.

changeExtRegistry(reg: ExtRegistry)

Change the internal extension registry to encode extension.

QEncoderOption

An option to configure and optimise the returned encoder instance.

initSize: number

The initial size of buffer that will be used by encoder.If this is not set, the encoder will use default initial buffer size. The default initial size is 2KB.

extRegistry: ExtRegistry

The extension registry to match extension with ext code.

onExpand?: < T extends boolean|undefined,U extends T extends true ? Uint8Array : undefined,V extendsT extends true ? number : undefined >(encoder:QEncoder,requiredSize:number,isInitial:T,oldBuf: U, offset:V) => Uint8Array;

Custom function to handle when current buffer is not enough to write encoded data.

onRelease?: (buf: Uint8Array) => void;

Custom function to handle released buffer when encoder is reset.

import { QEncoder } from "@se-puu/qpack";

// create encoder instance.
const encoder=QEncoder.create();
// encode some data.
const encodedData=encoder.encode({data:12,someStr:"someString"});
// encoded data is ready to transfer over network or store as file.

QDecoder

Creates an decoder instance that maintains its own configuration. Each instance stores settings independently, allowing for tailored behavior without impacting other decoders.

static create(option?: QDecoderOption): QDecoder

decode< Type >(data: Uint8Array): Type

Call setBuffer to provide buffer to the decoder and decode the data from this buffer.

setBuffer(data: Uint8Array): Type

Provide buffer to the decoder.

read< Type >( ): Type

Manually read data from the buffer with each call until the data is completely consumed.

changeExtRegistry(reg: ExtRegistry)

Change the internal extension registry to decode extension.

isEnd():boolean

The reading process of data is ended or not.

QDecoderOption

extRegistry: ExtRegistry

An option to configure and optimise the returned decoder instance.

import { QDecoder } from "@se-puu/qpack";

// create decoder instance
const decoder=QDecoder.create();
// buf is already received by some methods.
const decodedObj=decoder.decode(buf);
// decodedObj is ready to use.

ExtRegistry

A registry for storing extensions that maps between the extension and their corresponding extension codes. It maintains its own configuration. Each instance stores settings independently, allowing for tailored behavior without impacting other registry.

static create(): ExtRegistry

Create a extension registry instance.

register< Ext extends ExtEntry >(ext: Ext,option?: ExtRegisterOption): boolean

Register an extension by supplying its extension code, encoder, and decoder to the extension registry. If the extension code is already registered, the registration process will fail.The extension code can be overwritten by providing overwrite option.

unregister(extCode: number): boolean

Unregister an extension from extension registry.

ExtRegisterOption

overWrite?: boolean

Forces the overwriting of the extension code if it already exists.

import { ExtRegistry, QEncoder, QDecoder } from "@se-puu/qpack";

const ereg=ExtRegistry.create();
const encoder=QEncoder.create({extRegistry:ereg});
const decoder=QDecoder.create({extRegistry:ereg});
// MyExt is a ExtEntry class that represents custom extension.
ereg.register(MyExt);
const someData={
    num:12,
    someStr:"data",
    someExt:new MyExt()
};
// this is encoded buffer
const encodedData=encoder.encode(someData);
// transfer or store encoded data. receive or read again encoded data and then decode it.
// decodedObj will be same as someData.
const decodedObj=decoder.decode(encodedData);

ExtEntry

Extension entry class. The class must have the following static methods.

static extCode: number

the representation of code for this extension entry.

static encode(encoder: QEncoder): void

The function will be called by encoder when the data is instance of this class during encoding.

static decode(decoder: QDecoder): ExtEntry

The function will be called by decoder when the encoded ext code is found during decoding.

class MyExt{
    randomNum!:number;
    someStr!:string;
    static readonly extCode=1200;
    static encode(encoder:QEncoder,data:MyExt):void{
        encoder.writeNumber(data.randomNum);
        encoder.writeString(data.someStr);
    }
    static decode(decoder:QDecoder):MyExt{
        const retIns=new MyExt();
        retIns.randomNum=decoder.read();
        retIns.someStr=decoder.read();
    }
    constructor(){
        this.randomNum=Math.random();
        this.someStr="someString";
    }
}

Example

simple encode, decode without performance considerations.

import { QEncoder, QDecoder } from "@se-puu/qpack";

const object={
    some:"data",
    value:12345678,
    arr:[12345,54321,56789,98765]
};
const encoder = QEncoder.create();
const buffer = encoder.encode(object);
// buffer is sent over network or store and retrive from stroage. Then decode,
const decoder = QDecoder.create();
// resultObj will be same as object.
const resultObj = decoder.decode(buffer);

optimised encode, decode with high performance without using extensions.

Encoding and decoding an entire object can take significantly longer than processing individual data of this object, which may affect data access latency. Normal way.Accessing data is high latency.

import { QEncoder, QDecoder } from "@se-puu/qpack";

const itemShowCase=[
    {
        name: "item1",
        price:10 // 10$
    },
    {
        name: "item2",
        price:11
    },
    {
        name: "item3",
        price:9
    },
];
const encoder=QEncoder.create();
// encoding the whole itemShowCase
const encodedData=encoder.encode(itemShowCase);
// transfer data overnetwork
const decoder=QDecoder.create();
// decoding the whole itemShowCase
const itemArr=decoder.decode(encodedData);
// Accessing itemArr occurs after decoding all item data from itemShowCase.
itemArr.forEach(item=>{
    // process or render item in html.
});

Optimised way.Accessing data is low latency for large array.Small array may not be seen difference.

import { QEncoder, QDecoder } from "@se-puu/qpack";

const itemShowCase=[
    {
        name: "item1",
        price:10 // 10$
    },
    {
        name: "item2",
        price:11
    },
    {
        name: "item3",
        price:9
    }, 
    // ... more items
];
const encoder=QEncoder.create();
itemShowCase.forEach(item=>encoder.write(item));
const encodedData=encoder.export();
// transfer data overnetwork
const decoder=QDecoder.create();
const itemArr=decoder.decode(encodedData);
// Accessing itemArr occurs after decoding all item data from itemShowCase.
while(!decoder.isEnd()){
    // You can access each item quickly without waiting for the entire array to be decoded.accessing each item is low latency.
    const item = decoder.read();
    // Process or render the item in HTML.
}

View others in example folder.

Tests

Run light test with:

npm test

Run full data test with:

npm run test-heavy

License

Distributed under the MIT License. See LICENSE for more details.

Changelog

Refer to CHANGELOG.md for version history and updates.

Acknowledgements

Special thanks to all contributors and the open-source community for their support and feedback.

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago

1.0.0

8 months ago