New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@yume-chan/struct

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@yume-chan/struct - npm Package Compare versions

Comparing version 0.0.17 to 0.0.18

12

CHANGELOG.json

@@ -5,2 +5,14 @@ {

{
"version": "0.0.18",
"tag": "@yume-chan/struct_v0.0.18",
"date": "Wed, 25 Jan 2023 21:33:49 GMT",
"comments": {
"none": [
{
"comment": "Refactor number types for easier extending (see `ScrcpyFloatToInt16FieldDefinition` for an example)"
}
]
}
},
{
"version": "0.0.17",

@@ -7,0 +19,0 @@ "tag": "@yume-chan/struct_v0.0.17",

9

CHANGELOG.md
# Change Log - @yume-chan/struct
This log was last generated on Tue, 18 Oct 2022 09:32:30 GMT and should not be manually modified.
This log was last generated on Wed, 25 Jan 2023 21:33:49 GMT and should not be manually modified.
## 0.0.18
Wed, 25 Jan 2023 21:33:49 GMT
### Updates
- Refactor number types for easier extending (see `ScrcpyFloatToInt16FieldDefinition` for an example)
## 0.0.17

@@ -6,0 +13,0 @@ Tue, 18 Oct 2022 09:32:30 GMT

8

esm/basic/definition.d.ts

@@ -1,5 +0,5 @@

import type { StructAsyncDeserializeStream, StructDeserializeStream } from "./stream.js";
import type { StructFieldValue } from "./field-value.js";
import type { StructValue } from "./struct-value.js";
import type { StructOptions } from "./options.js";
import { type StructFieldValue } from "./field-value.js";
import { type StructOptions } from "./options.js";
import { type StructAsyncDeserializeStream, type StructDeserializeStream } from "./stream.js";
import { type StructValue } from "./struct-value.js";
/**

@@ -6,0 +6,0 @@ * A field definition defines how to deserialize a field.

@@ -1,4 +0,4 @@

import type { StructFieldDefinition } from "./definition.js";
import type { StructOptions } from "./options.js";
import type { StructValue } from "./struct-value.js";
import { type StructFieldDefinition } from "./definition.js";
import { type StructOptions } from "./options.js";
import { type StructValue } from "./struct-value.js";
/**

@@ -18,4 +18,4 @@ * A field value defines how to serialize a field.

get hasCustomAccessors(): boolean;
protected value: TDefinition['TValue'];
constructor(definition: TDefinition, options: Readonly<StructOptions>, struct: StructValue, value: TDefinition['TValue']);
protected value: TDefinition["TValue"];
constructor(definition: TDefinition, options: Readonly<StructOptions>, struct: StructValue, value: TDefinition["TValue"]);
/**

@@ -30,7 +30,7 @@ * Gets size of this field. By default, it returns its `definition`'s size.

*/
get(): TDefinition['TValue'];
get(): TDefinition["TValue"];
/**
* When implemented in derived classes, updates current field's value.
*/
set(value: TDefinition['TValue']): void;
set(value: TDefinition["TValue"]): void;
/**

@@ -37,0 +37,0 @@ * When implemented in derived classes, serializes this field into `dataView` at `offset`

@@ -15,4 +15,4 @@ /**

get hasCustomAccessors() {
return this.get !== StructFieldValue.prototype.get ||
this.set !== StructFieldValue.prototype.set;
return (this.get !== StructFieldValue.prototype.get ||
this.set !== StructFieldValue.prototype.set);
}

@@ -19,0 +19,0 @@ value;

@@ -1,2 +0,2 @@

import type { ValueOrPromise } from "../utils.js";
import { type ValueOrPromise } from "../utils.js";
export interface StructDeserializeStream {

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

import type { StructFieldValue } from "./field-value.js";
import { type StructFieldValue } from "./field-value.js";
export declare const STRUCT_VALUE_SYMBOL: unique symbol;

@@ -11,3 +11,3 @@ /**

readonly value: Record<PropertyKey, unknown>;
constructor(prototype: any);
constructor(prototype: object);
/**

@@ -14,0 +14,0 @@ * Sets a `StructFieldValue` for `key`

@@ -17,3 +17,6 @@ export const STRUCT_VALUE_SYMBOL = Symbol("struct-value");

// but we need it to be non-enumerable
Object.defineProperty(this.value, STRUCT_VALUE_SYMBOL, { enumerable: false, value: this });
Object.defineProperty(this.value, STRUCT_VALUE_SYMBOL, {
enumerable: false,
value: this,
});
}

@@ -34,4 +37,8 @@ /**

enumerable: true,
get() { return fieldValue.get(); },
set(v) { fieldValue.set(v); },
get() {
return fieldValue.get();
},
set(v) {
fieldValue.set(v);
},
});

@@ -38,0 +45,0 @@ }

@@ -1,4 +0,4 @@

import { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructOptions } from './basic/index.js';
import { BigIntFieldType, BufferFieldSubType, FixedLengthBufferLikeFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, type FixedLengthBufferLikeFieldOptions, type LengthField, type VariableLengthBufferLikeFieldOptions } from './types/index.js';
import type { Evaluate, Identity, Overwrite } from "./utils.js";
import { type StructAsyncDeserializeStream, type StructDeserializeStream, type StructFieldDefinition, type StructOptions } from "./basic/index.js";
import { BigIntFieldType, FixedLengthBufferLikeFieldDefinition, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, type BufferFieldSubType, type FixedLengthBufferLikeFieldOptions, type LengthField, type VariableLengthBufferLikeFieldOptions } from "./types/index.js";
import { type Evaluate, type Identity, type Overwrite } from "./utils.js";
export interface StructLike<TValue> {

@@ -10,7 +10,7 @@ deserialize(stream: StructDeserializeStream | StructAsyncDeserializeStream): Promise<TValue>;

*/
export declare type StructValueType<T extends StructLike<any>> = Awaited<ReturnType<T['deserialize']>>;
export type StructValueType<T extends StructLike<unknown>> = Awaited<ReturnType<T["deserialize"]>>;
/**
* Create a new `Struct` type with `TDefinition` appended
*/
declare type AddFieldDescriptor<TFields extends object, TOmitInitKey extends PropertyKey, TExtra extends object, TPostDeserialized, TFieldName extends PropertyKey, TDefinition extends StructFieldDefinition<any, any, any>> = Identity<Struct<Evaluate<TFields & Record<TFieldName, TDefinition['TValue']>>, TOmitInitKey | TDefinition['TOmitInitKey'], TExtra, TPostDeserialized>>;
type AddFieldDescriptor<TFields extends object, TOmitInitKey extends PropertyKey, TExtra extends object, TPostDeserialized, TFieldName extends PropertyKey, TDefinition extends StructFieldDefinition<any, any, any>> = Identity<Struct<Evaluate<TFields & Record<TFieldName, TDefinition["TValue"]>>, TOmitInitKey | TDefinition["TOmitInitKey"], TExtra, TPostDeserialized>>;
/**

@@ -20,8 +20,8 @@ * Similar to `ArrayBufferLikeFieldCreator`, but bind to `TType`

interface BoundArrayBufferLikeFieldDefinitionCreator<TFields extends object, TOmitInitKey extends PropertyKey, TExtra extends object, TPostDeserialized, TType extends BufferFieldSubType<any, any>> {
<TName extends PropertyKey, TTypeScriptType = TType['TTypeScriptType']>(name: TName, options: FixedLengthBufferLikeFieldOptions, typeScriptType?: TTypeScriptType): AddFieldDescriptor<TFields, TOmitInitKey, TExtra, TPostDeserialized, TName, FixedLengthBufferLikeFieldDefinition<TType, FixedLengthBufferLikeFieldOptions, TTypeScriptType>>;
<TName extends PropertyKey, TLengthField extends LengthField<TFields>, TOptions extends VariableLengthBufferLikeFieldOptions<TFields, TLengthField>, TTypeScriptType = TType['TTypeScriptType']>(name: TName, options: TOptions, typeScriptType?: TTypeScriptType): AddFieldDescriptor<TFields, TOmitInitKey, TExtra, TPostDeserialized, TName, VariableLengthBufferLikeFieldDefinition<TType, TOptions, TTypeScriptType>>;
<TName extends PropertyKey, TTypeScriptType = TType["TTypeScriptType"]>(name: TName, options: FixedLengthBufferLikeFieldOptions, typeScriptType?: TTypeScriptType): AddFieldDescriptor<TFields, TOmitInitKey, TExtra, TPostDeserialized, TName, FixedLengthBufferLikeFieldDefinition<TType, FixedLengthBufferLikeFieldOptions, TTypeScriptType>>;
<TName extends PropertyKey, TLengthField extends LengthField<TFields>, TOptions extends VariableLengthBufferLikeFieldOptions<TFields, TLengthField>, TTypeScriptType = TType["TTypeScriptType"]>(name: TName, options: TOptions, typeScriptType?: TTypeScriptType): AddFieldDescriptor<TFields, TOmitInitKey, TExtra, TPostDeserialized, TName, VariableLengthBufferLikeFieldDefinition<TType, TOptions, TTypeScriptType>>;
}
export declare type StructPostDeserialized<TFields, TPostDeserialized> = (this: TFields, object: TFields) => TPostDeserialized;
export declare type StructDeserializedResult<TFields extends object, TExtra extends object, TPostDeserialized> = TPostDeserialized extends undefined ? Overwrite<TExtra, TFields> : TPostDeserialized;
export declare class Struct<TFields extends object = {}, TOmitInitKey extends PropertyKey = never, TExtra extends object = {}, TPostDeserialized = undefined> implements StructLike<StructDeserializedResult<TFields, TExtra, TPostDeserialized>> {
export type StructPostDeserialized<TFields, TPostDeserialized> = (this: TFields, object: TFields) => TPostDeserialized;
export type StructDeserializedResult<TFields extends object, TExtra extends object, TPostDeserialized> = TPostDeserialized extends undefined ? Overwrite<TExtra, TFields> : TPostDeserialized;
export declare class Struct<TFields extends object = Record<never, never>, TOmitInitKey extends PropertyKey = never, TExtra extends object = Record<never, never>, TPostDeserialized = undefined> implements StructLike<StructDeserializedResult<TFields, TExtra, TPostDeserialized>> {
readonly TFields: TFields;

@@ -49,3 +49,3 @@ readonly TOmitInitKey: TOmitInitKey;

*/
fields<TOther extends Struct<any, any, any, any>>(other: TOther): Struct<TFields & TOther['TFields'], TOmitInitKey | TOther['TOmitInitKey'], TExtra & TOther['TExtra'], TPostDeserialized>;
fields<TOther extends Struct<any, any, any, any>>(other: TOther): Struct<TFields & TOther["TFields"], TOmitInitKey | TOther["TOmitInitKey"], TExtra & TOther["TExtra"], TPostDeserialized>;
private number;

@@ -55,23 +55,23 @@ /**

*/
int8<TName extends PropertyKey, TTypeScriptType = (typeof NumberFieldType)['Uint8']['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
int8<TName extends PropertyKey, TTypeScriptType = number>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
/**
* Appends an `uint8` field to the `Struct`
*/
uint8<TName extends PropertyKey, TTypeScriptType = (typeof NumberFieldType)['Uint8']['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
uint8<TName extends PropertyKey, TTypeScriptType = number>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
/**
* Appends an `int16` field to the `Struct`
*/
int16<TName extends PropertyKey, TTypeScriptType = (typeof NumberFieldType)['Uint16']['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
int16<TName extends PropertyKey, TTypeScriptType = number>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
/**
* Appends an `uint16` field to the `Struct`
*/
uint16<TName extends PropertyKey, TTypeScriptType = (typeof NumberFieldType)['Uint16']['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
uint16<TName extends PropertyKey, TTypeScriptType = number>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
/**
* Appends an `int32` field to the `Struct`
*/
int32<TName extends PropertyKey, TTypeScriptType = (typeof NumberFieldType)['Int32']['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
int32<TName extends PropertyKey, TTypeScriptType = number>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
/**
* Appends an `uint32` field to the `Struct`
*/
uint32<TName extends PropertyKey, TTypeScriptType = (typeof NumberFieldType)['Uint32']['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
uint32<TName extends PropertyKey, TTypeScriptType = number>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
private bigint;

@@ -83,3 +83,3 @@ /**

*/
int64<TName extends PropertyKey, TTypeScriptType = BigIntFieldType['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
int64<TName extends PropertyKey, TTypeScriptType = BigIntFieldType["TTypeScriptType"]>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
/**

@@ -90,3 +90,3 @@ * Appends an `uint64` field to the `Struct`

*/
uint64<TName extends PropertyKey, TTypeScriptType = BigIntFieldType['TTypeScriptType']>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
uint64<TName extends PropertyKey, TTypeScriptType = BigIntFieldType["TTypeScriptType"]>(name: TName, typeScriptType?: TTypeScriptType): Struct<Evaluate<TFields & Record<TName, TTypeScriptType>>, TOmitInitKey, TExtra, TPostDeserialized>;
private arrayBufferLike;

@@ -93,0 +93,0 @@ uint8Array: BoundArrayBufferLikeFieldDefinitionCreator<TFields, TOmitInitKey, TExtra, TPostDeserialized, Uint8ArrayBufferFieldSubType>;

@@ -1,4 +0,4 @@

import { StructDefaultOptions, StructValue, STRUCT_VALUE_SYMBOL } from './basic/index.js';
import { STRUCT_VALUE_SYMBOL, StructDefaultOptions, StructValue, } from "./basic/index.js";
import { SyncPromise } from "./sync-promise.js";
import { BigIntFieldDefinition, BigIntFieldType, FixedLengthBufferLikeFieldDefinition, NumberFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition } from './types/index.js';
import { BigIntFieldDefinition, BigIntFieldType, FixedLengthBufferLikeFieldDefinition, NumberFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, } from "./types/index.js";
export class Struct {

@@ -15,3 +15,5 @@ TFields;

*/
get size() { return this._size; }
get size() {
return this._size;
}
_fields = [];

@@ -108,3 +110,3 @@ _extra = {};

arrayBufferLike = (name, type, options) => {
if ('length' in options) {
if ("length" in options) {
return this.field(name, new FixedLengthBufferLikeFieldDefinition(type, options));

@@ -146,3 +148,3 @@ }

.then(() => definition.deserialize(this.options, stream, structValue))
.then(fieldValue => {
.then((fieldValue) => {
structValue.set(name, fieldValue);

@@ -193,6 +195,6 @@ });

}
let outputType = 'number';
let outputType = "number";
if (!output) {
output = new Uint8Array(structSize);
outputType = 'Uint8Array';
outputType = "Uint8Array";
}

@@ -205,3 +207,3 @@ const dataView = new DataView(output.buffer, output.byteOffset, output.byteLength);

}
if (outputType === 'number') {
if (outputType === "number") {
return structSize;

@@ -208,0 +210,0 @@ }

@@ -6,5 +6,5 @@ export const SyncPromise = {

resolve(value) {
if (typeof value === 'object' &&
if (typeof value === "object" &&
value !== null &&
typeof value.then === 'function') {
typeof value.then === "function") {
if (value instanceof PendingSyncPromise ||

@@ -28,3 +28,3 @@ value instanceof ResolvedSyncPromise ||

}
}
},
};

@@ -48,3 +48,3 @@ class PendingSyncPromise {

}
then(onfulfilled, onrejected) {
then(onfulfilled) {
if (!onfulfilled) {

@@ -51,0 +51,0 @@ return this;

@@ -1,4 +0,4 @@

import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from "../basic/index.js";
declare type DataViewBigInt64Getter = (dataView: DataView, byteOffset: number, littleEndian: boolean | undefined) => bigint;
declare type DataViewBigInt64Setter = (dataView: DataView, byteOffset: number, value: bigint, littleEndian: boolean | undefined) => void;
import { StructFieldDefinition, StructFieldValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions, type StructValue } from "../basic/index.js";
type DataViewBigInt64Getter = (dataView: DataView, byteOffset: number, littleEndian: boolean | undefined) => bigint;
type DataViewBigInt64Setter = (dataView: DataView, byteOffset: number, value: bigint, littleEndian: boolean | undefined) => void;
export declare class BigIntFieldType {

@@ -15,3 +15,3 @@ readonly TTypeScriptType: bigint;

readonly type: TType;
constructor(type: TType, _typescriptType?: TTypeScriptType);
constructor(type: TType, typescriptType?: TTypeScriptType);
getSize(): number;

@@ -18,0 +18,0 @@ create(options: Readonly<StructOptions>, struct: StructValue, value: TTypeScriptType): BigIntFieldValue<this>;

@@ -1,3 +0,3 @@

import { getBigInt64, getBigUint64, setBigInt64, setBigUint64 } from '@yume-chan/dataview-bigint-polyfill/esm/fallback.js';
import { StructFieldDefinition, StructFieldValue } from "../basic/index.js";
import { getBigInt64, getBigUint64, setBigInt64, setBigUint64, } from "@yume-chan/dataview-bigint-polyfill/esm/fallback.js";
import { StructFieldDefinition, StructFieldValue, } from "../basic/index.js";
import { SyncPromise } from "../sync-promise.js";

@@ -19,3 +19,4 @@ export class BigIntFieldType {

type;
constructor(type, _typescriptType) {
constructor(type, typescriptType) {
void typescriptType;
super();

@@ -31,7 +32,6 @@ this.type = type;

deserialize(options, stream, struct) {
return SyncPromise
.try(() => {
return SyncPromise.try(() => {
return stream.read(this.getSize());
})
.then(array => {
.then((array) => {
const view = new DataView(array.buffer, array.byteOffset, array.byteLength);

@@ -38,0 +38,0 @@ const value = this.type.getter(view, 0, options.littleEndian);

@@ -1,2 +0,2 @@

import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from '../../basic/index.js';
import { StructFieldDefinition, StructFieldValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions, type StructValue } from "../../basic/index.js";
/**

@@ -54,3 +54,3 @@ * Base class for all types that

*/
create(options: Readonly<StructOptions>, struct: StructValue, value: TType['TTypeScriptType'], array?: Uint8Array): BufferLikeFieldValue<this>;
create(options: Readonly<StructOptions>, struct: StructValue, value: TType["TTypeScriptType"], array?: Uint8Array): BufferLikeFieldValue<this>;
deserialize(options: Readonly<StructOptions>, stream: StructDeserializeStream, struct: StructValue): BufferLikeFieldValue<this>;

@@ -61,6 +61,6 @@ deserialize(options: Readonly<StructOptions>, stream: StructAsyncDeserializeStream, struct: StructValue): Promise<BufferLikeFieldValue<this>>;

protected array: Uint8Array | undefined;
constructor(definition: TDefinition, options: Readonly<StructOptions>, struct: StructValue, value: TDefinition['TValue'], array?: Uint8Array);
set(value: TDefinition['TValue']): void;
constructor(definition: TDefinition, options: Readonly<StructOptions>, struct: StructValue, value: TDefinition["TValue"], array?: Uint8Array);
set(value: TDefinition["TValue"]): void;
serialize(dataView: DataView, offset: number): void;
}
//# sourceMappingURL=base.d.ts.map

@@ -1,2 +0,2 @@

import { StructFieldDefinition, StructFieldValue } from '../../basic/index.js';
import { StructFieldDefinition, StructFieldValue, } from "../../basic/index.js";
import { SyncPromise } from "../../sync-promise.js";

@@ -56,2 +56,3 @@ import { decodeUtf8, encodeUtf8 } from "../../utils.js";

getDeserializeSize(struct) {
void struct;
return this.getSize();

@@ -66,4 +67,3 @@ }

deserialize(options, stream, struct) {
return SyncPromise
.try(() => {
return SyncPromise.try(() => {
const size = this.getDeserializeSize(struct);

@@ -77,3 +77,3 @@ if (size === 0) {

})
.then(array => {
.then((array) => {
const value = this.type.toValue(array);

@@ -101,6 +101,5 @@ return this.create(options, struct, value, array);

}
new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength)
.set(this.array, offset);
new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength).set(this.array, offset);
}
}
//# sourceMappingURL=base.js.map

@@ -7,3 +7,2 @@ import { BufferLikeFieldDefinition } from "./base.js";

}
;
//# sourceMappingURL=fixed-length.js.map

@@ -1,5 +0,5 @@

import { StructFieldValue, type StructFieldDefinition, type StructOptions, type StructValue } from '../../basic/index.js';
import type { KeysOfType } from '../../utils.js';
import { BufferLikeFieldDefinition, BufferLikeFieldValue, type BufferFieldSubType } from './base.js';
export declare type LengthField<TFields> = KeysOfType<TFields, number | string>;
import { StructFieldValue, type StructFieldDefinition, type StructOptions, type StructValue } from "../../basic/index.js";
import { type KeysOfType } from "../../utils.js";
import { BufferLikeFieldDefinition, BufferLikeFieldValue, type BufferFieldSubType } from "./base.js";
export type LengthField<TFields> = KeysOfType<TFields, number | string>;
export interface VariableLengthBufferLikeFieldOptions<TFields = object, TLengthField extends LengthField<TFields> = any> {

@@ -20,3 +20,3 @@ /**

}
export declare class VariableLengthBufferLikeFieldDefinition<TType extends BufferFieldSubType = BufferFieldSubType, TOptions extends VariableLengthBufferLikeFieldOptions = VariableLengthBufferLikeFieldOptions, TTypeScriptType = TType["TTypeScriptType"]> extends BufferLikeFieldDefinition<TType, TOptions, TOptions['lengthField'], TTypeScriptType> {
export declare class VariableLengthBufferLikeFieldDefinition<TType extends BufferFieldSubType = BufferFieldSubType, TOptions extends VariableLengthBufferLikeFieldOptions = VariableLengthBufferLikeFieldOptions, TTypeScriptType = TType["TTypeScriptType"]> extends BufferLikeFieldDefinition<TType, TOptions, TOptions["lengthField"], TTypeScriptType> {
getSize(): number;

@@ -29,7 +29,7 @@ protected getDeserializeSize(struct: StructValue): number;

protected lengthFieldValue: VariableLengthBufferLikeFieldLengthValue;
constructor(definition: TDefinition, options: Readonly<StructOptions>, struct: StructValue, value: TDefinition['TValue'], array?: Uint8Array);
constructor(definition: TDefinition, options: Readonly<StructOptions>, struct: StructValue, value: TDefinition["TValue"], array?: Uint8Array);
getSize(): number;
set(value: unknown): void;
}
declare type VariableLengthBufferLikeFieldValueLike = StructFieldValue<StructFieldDefinition<VariableLengthBufferLikeFieldOptions, any, any>>;
type VariableLengthBufferLikeFieldValueLike = StructFieldValue<StructFieldDefinition<VariableLengthBufferLikeFieldOptions, any, any>>;
export declare class VariableLengthBufferLikeFieldLengthValue extends StructFieldValue {

@@ -36,0 +36,0 @@ protected originalField: StructFieldValue;

@@ -1,3 +0,3 @@

import { StructFieldValue } from '../../basic/index.js';
import { BufferLikeFieldDefinition, BufferLikeFieldValue } from './base.js';
import { StructFieldValue, } from "../../basic/index.js";
import { BufferLikeFieldDefinition, BufferLikeFieldValue, } from "./base.js";
export class VariableLengthBufferLikeFieldDefinition extends BufferLikeFieldDefinition {

@@ -9,3 +9,3 @@ getSize() {

let value = struct.value[this.options.lengthField];
if (typeof value === 'string') {
if (typeof value === "string") {
value = Number.parseInt(value, this.options.lengthFieldRadix ?? 10);

@@ -63,3 +63,3 @@ }

const originalValue = this.originalField.get();
if (typeof originalValue === 'string') {
if (typeof originalValue === "string") {
value = value.toString(this.bufferField.definition.options.lengthFieldRadix ?? 10);

@@ -66,0 +66,0 @@ }

@@ -1,24 +0,19 @@

import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from '../basic/index.js';
declare type NumberTypeDeserializer = (array: Uint8Array, littleEndian: boolean) => number;
export declare type DataViewSetters = {
[TKey in keyof DataView]: TKey extends `set${string}` ? TKey : never;
}[keyof DataView];
export declare class NumberFieldType {
readonly TTypeScriptType: number;
readonly signed: boolean;
readonly size: number;
readonly deserializer: NumberTypeDeserializer;
readonly convertSign: (value: number) => number;
readonly dataViewSetter: DataViewSetters;
constructor(size: number, signed: boolean, convertSign: (value: number) => number, dataViewSetter: DataViewSetters);
static readonly Int8: NumberFieldType;
static readonly Uint8: NumberFieldType;
static readonly Int16: NumberFieldType;
static readonly Uint16: NumberFieldType;
static readonly Int32: NumberFieldType;
static readonly Uint32: NumberFieldType;
import { StructFieldDefinition, StructFieldValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions, type StructValue } from "../basic/index.js";
export interface NumberFieldType {
signed: boolean;
size: number;
deserialize(array: Uint8Array, littleEndian: boolean): number;
serialize(dataView: DataView, offset: number, value: number, littleEndian: boolean): void;
}
export declare class NumberFieldDefinition<TType extends NumberFieldType = NumberFieldType, TTypeScriptType = TType["TTypeScriptType"]> extends StructFieldDefinition<void, TTypeScriptType> {
export declare namespace NumberFieldType {
const Uint8: NumberFieldType;
const Int8: NumberFieldType;
const Uint16: NumberFieldType;
const Int16: NumberFieldType;
const Uint32: NumberFieldType;
const Int32: NumberFieldType;
}
export declare class NumberFieldDefinition<TType extends NumberFieldType = NumberFieldType, TTypeScriptType = number> extends StructFieldDefinition<void, TTypeScriptType> {
readonly type: TType;
constructor(type: TType, _typescriptType?: TTypeScriptType);
constructor(type: TType, typescriptType?: TTypeScriptType);
getSize(): number;

@@ -32,3 +27,2 @@ create(options: Readonly<StructOptions>, struct: StructValue, value: TTypeScriptType): NumberFieldValue<this>;

}
export {};
//# sourceMappingURL=number.d.ts.map

@@ -1,34 +0,89 @@

import { StructFieldDefinition, StructFieldValue } from '../basic/index.js';
import { StructFieldDefinition, StructFieldValue, } from "../basic/index.js";
import { SyncPromise } from "../sync-promise.js";
const DESERIALIZERS = {
1: (array, littleEndian) => array[0],
2: (array, littleEndian) => ((array[1] << 8) | array[0]) * littleEndian |
((array[0] << 8) | array[1]) * !littleEndian,
4: (array, littleEndian) => ((array[3] << 24) | (array[2] << 16) | (array[1] << 8) | array[0]) * littleEndian |
((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]) * !littleEndian,
};
export class NumberFieldType {
TTypeScriptType;
signed;
size;
deserializer;
convertSign;
dataViewSetter;
constructor(size, signed, convertSign, dataViewSetter) {
this.size = size;
this.signed = signed;
this.deserializer = DESERIALIZERS[size];
this.convertSign = convertSign;
this.dataViewSetter = dataViewSetter;
}
static Int8 = new NumberFieldType(1, true, value => value << 24 >> 24, 'setInt8');
static Uint8 = new NumberFieldType(1, false, value => value, 'setUint8');
static Int16 = new NumberFieldType(2, true, value => value << 16 >> 16, 'setInt16');
static Uint16 = new NumberFieldType(2, false, value => value, 'setUint16');
static Int32 = new NumberFieldType(4, true, value => value, 'setInt32');
static Uint32 = new NumberFieldType(4, false, value => value >>> 0, 'setUint32');
}
// eslint-disable-next-line @typescript-eslint/no-namespace
export var NumberFieldType;
(function (NumberFieldType) {
NumberFieldType.Uint8 = {
signed: false,
size: 1,
deserialize(array) {
return array[0];
},
serialize(dataView, offset, value) {
dataView.setUint8(offset, value);
},
};
NumberFieldType.Int8 = {
signed: true,
size: 1,
deserialize(array) {
const value = NumberFieldType.Uint8.deserialize(array, false);
return (value << 24) >> 24;
},
serialize(dataView, offset, value) {
dataView.setInt8(offset, value);
},
};
NumberFieldType.Uint16 = {
signed: false,
size: 2,
deserialize(array, littleEndian) {
// PERF: Chrome's `DataView#getUint16` uses inefficient operations,
// including branching, bit extending and 32-bit bit swapping.
// The best way should use 16-bit bit rotation and conditional move,
// like LLVM does for code similar to the below one.
// This code is much faster on V8, but the actual generated assembly is unknown.
return ((((array[1] << 8) | array[0]) * littleEndian) |
(((array[0] << 8) | array[1]) * !littleEndian));
},
serialize(dataView, offset, value, littleEndian) {
dataView.setUint16(offset, value, littleEndian);
},
};
NumberFieldType.Int16 = {
signed: true,
size: 2,
deserialize(array, littleEndian) {
const value = NumberFieldType.Uint16.deserialize(array, littleEndian);
return (value << 16) >> 16;
},
serialize(dataView, offset, value, littleEndian) {
dataView.setInt16(offset, value, littleEndian);
},
};
NumberFieldType.Uint32 = {
signed: false,
size: 4,
deserialize(array, littleEndian) {
const value = NumberFieldType.Int32.deserialize(array, littleEndian);
return value >>> 0;
},
serialize(dataView, offset, value, littleEndian) {
dataView.setUint32(offset, value, littleEndian);
},
};
NumberFieldType.Int32 = {
signed: true,
size: 4,
deserialize(array, littleEndian) {
return ((((array[3] << 24) |
(array[2] << 16) |
(array[1] << 8) |
array[0]) *
littleEndian) |
(((array[0] << 24) |
(array[1] << 16) |
(array[2] << 8) |
array[3]) *
!littleEndian));
},
serialize(dataView, offset, value, littleEndian) {
dataView.setInt32(offset, value, littleEndian);
},
};
})(NumberFieldType = NumberFieldType || (NumberFieldType = {}));
export class NumberFieldDefinition extends StructFieldDefinition {
type;
constructor(type, _typescriptType) {
constructor(type, typescriptType) {
void typescriptType;
super();

@@ -44,10 +99,7 @@ this.type = type;

deserialize(options, stream, struct) {
return SyncPromise
.try(() => {
return SyncPromise.try(() => {
return stream.read(this.getSize());
})
.then(array => {
let value;
value = this.type.deserializer(array, options.littleEndian);
value = this.type.convertSign(value);
.then((array) => {
const value = this.type.deserialize(array, options.littleEndian);
return this.create(options, struct, value);

@@ -60,8 +112,5 @@ })

serialize(dataView, offset) {
// `setBigInt64` requires a `bigint` while others require `number`
// So `dataView[DataViewSetters]` requires `bigint & number`
// and that is, `never`
dataView[this.definition.type.dataViewSetter](offset, this.value, this.options.littleEndian);
this.definition.type.serialize(dataView, offset, this.value, this.options.littleEndian);
}
}
//# sourceMappingURL=number.js.map

@@ -18,7 +18,7 @@ /**

*/
export declare type Identity<T> = T;
export type Identity<T> = T;
/**
* Collapse an intersection type (`{ foo: string } & { bar: number }`) to a simple type (`{ foo: string, bar: number }`)
*/
export declare type Evaluate<T> = T extends infer U ? {
export type Evaluate<T> = T extends infer U ? {
[K in keyof U]: U[K];

@@ -29,7 +29,7 @@ } : never;

*/
export declare type Overwrite<TBase extends object, TNew extends object> = Evaluate<Omit<TBase, keyof TNew> & TNew>;
export type Overwrite<TBase extends object, TNew extends object> = Evaluate<Omit<TBase, keyof TNew> & TNew>;
/**
* Remove fields with `never` type
*/
export declare type OmitNever<T> = Pick<T, {
export type OmitNever<T> = Pick<T, {
[K in keyof T]: [T[K]] extends [never] ? never : K;

@@ -40,6 +40,6 @@ }[keyof T]>;

*/
export declare type KeysOfType<T, TValue> = {
export type KeysOfType<T, TValue> = {
[TKey in keyof T]: T[TKey] extends TValue ? TKey : never;
}[keyof T];
export declare type ValueOrPromise<T> = T | PromiseLike<T>;
export type ValueOrPromise<T> = T | PromiseLike<T>;
/**

@@ -46,0 +46,0 @@ * Returns a (fake) value of the given type.

@@ -7,11 +7,4 @@ /**

}
// This library can't use `@types/node` or `lib: dom`
// because they will pollute the global scope
// So `TextEncoder` and `TextDecoder` are not available
// Node.js 8.3 ships `TextEncoder` and `TextDecoder` in `util` module.
// But using top level await to load them requires Node.js 14.1.
// So there is no point to do that. Let's just assume they exist in global.
// @ts-expect-error
const { TextEncoder, TextDecoder } = globalThis;
const Utf8Encoder = new TextEncoder();
// @ts-expect-error
const Utf8Decoder = new TextDecoder();

@@ -18,0 +11,0 @@ export function encodeUtf8(input) {

{
"name": "@yume-chan/struct",
"version": "0.0.17",
"version": "0.0.18",
"description": "C-style structure serializer and deserializer.",

@@ -30,12 +30,14 @@ "keywords": [

"dependencies": {
"@yume-chan/dataview-bigint-polyfill": "^0.0.17",
"tslib": "^2.4.0"
"@yume-chan/dataview-bigint-polyfill": "^0.0.18",
"tslib": "^2.4.1"
},
"devDependencies": {
"@jest/globals": "^28.1.2",
"@yume-chan/ts-package-builder": "^1.0.0",
"@jest/globals": "^29.3.1",
"@yume-chan/eslint-config": "^1.0.0",
"@yume-chan/tsconfig": "^1.0.0",
"cross-env": "^7.0.3",
"jest": "^28.1.2",
"ts-jest": "^28.0.5",
"typescript": "^4.7.4"
"eslint": "^8.31.0",
"jest": "^29.3.1",
"ts-jest": "^29.0.4",
"typescript": "^4.9.4"
},

@@ -45,4 +47,5 @@ "scripts": {

"build:watch": "tsc -b tsconfig.build.json",
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage"
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage",
"lint": "eslint src/**/*.ts --fix"
}
}

@@ -1,5 +0,8 @@

import type { StructAsyncDeserializeStream, StructDeserializeStream } from "./stream.js";
import type { StructFieldValue } from "./field-value.js";
import type { StructValue } from "./struct-value.js";
import type { StructOptions } from "./options.js";
import { type StructFieldValue } from "./field-value.js";
import { type StructOptions } from "./options.js";
import {
type StructAsyncDeserializeStream,
type StructDeserializeStream,
} from "./stream.js";
import { type StructValue } from "./struct-value.js";

@@ -16,4 +19,4 @@ /**

TValue = unknown,
TOmitInitKey extends PropertyKey = never,
> {
TOmitInitKey extends PropertyKey = never
> {
/**

@@ -50,3 +53,3 @@ * When `T` is a type initiated `StructFieldDefinition`,

structValue: StructValue,
value: TValue,
value: TValue
): StructFieldValue<this>;

@@ -63,3 +66,3 @@

stream: StructDeserializeStream,
structValue: StructValue,
structValue: StructValue
): StructFieldValue<this>;

@@ -69,4 +72,4 @@ public abstract deserialize(

stream: StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): Promise<StructFieldValue<this>>;
}

@@ -1,4 +0,4 @@

import type { StructFieldDefinition } from "./definition.js";
import type { StructOptions } from "./options.js";
import type { StructValue } from "./struct-value.js";
import { type StructFieldDefinition } from "./definition.js";
import { type StructOptions } from "./options.js";
import { type StructValue } from "./struct-value.js";

@@ -12,4 +12,8 @@ /**

export abstract class StructFieldValue<
TDefinition extends StructFieldDefinition<any, any, any> = StructFieldDefinition<any, any, any>
> {
TDefinition extends StructFieldDefinition<
any,
any,
any
> = StructFieldDefinition<any, any, any>
> {
/** Gets the definition associated with this runtime value */

@@ -25,7 +29,9 @@ public readonly definition: TDefinition;

public get hasCustomAccessors(): boolean {
return this.get !== StructFieldValue.prototype.get ||
this.set !== StructFieldValue.prototype.set;
return (
this.get !== StructFieldValue.prototype.get ||
this.set !== StructFieldValue.prototype.set
);
}
protected value: TDefinition['TValue'];
protected value: TDefinition["TValue"];

@@ -36,3 +42,3 @@ public constructor(

struct: StructValue,
value: TDefinition['TValue'],
value: TDefinition["TValue"]
) {

@@ -57,3 +63,3 @@ this.definition = definition;

*/
public get(): TDefinition['TValue'] {
public get(): TDefinition["TValue"] {
return this.value;

@@ -65,3 +71,3 @@ }

*/
public set(value: TDefinition['TValue']): void {
public set(value: TDefinition["TValue"]): void {
this.value = value;

@@ -73,6 +79,3 @@ }

*/
public abstract serialize(
dataView: DataView,
offset: number,
): void;
public abstract serialize(dataView: DataView, offset: number): void;
}

@@ -1,2 +0,2 @@

import type { ValueOrPromise } from "../utils.js";
import { type ValueOrPromise } from "../utils.js";

@@ -3,0 +3,0 @@ // TODO: allow over reading (returning a `Uint8Array`, an `offset` and a `length`) to avoid copying

@@ -1,2 +0,2 @@

import type { StructFieldValue } from "./field-value.js";
import { type StructFieldValue } from "./field-value.js";

@@ -9,3 +9,6 @@ export const STRUCT_VALUE_SYMBOL = Symbol("struct-value");

export class StructValue {
/** @internal */ readonly fieldValues: Record<PropertyKey, StructFieldValue> = {};
/** @internal */ readonly fieldValues: Record<
PropertyKey,
StructFieldValue
> = {};

@@ -17,14 +20,13 @@ /**

public constructor(prototype: any) {
public constructor(prototype: object) {
// PERF: `Object.create(extra)` is 50% faster
// than `Object.defineProperties(this.value, extra)`
this.value = Object.create(prototype);
this.value = Object.create(prototype) as Record<PropertyKey, unknown>;
// PERF: `Object.defineProperty` is slow
// but we need it to be non-enumerable
Object.defineProperty(
this.value,
STRUCT_VALUE_SYMBOL,
{ enumerable: false, value: this }
);
Object.defineProperty(this.value, STRUCT_VALUE_SYMBOL, {
enumerable: false,
value: this,
});
}

@@ -47,4 +49,8 @@

enumerable: true,
get() { return fieldValue.get(); },
set(v) { fieldValue.set(v); },
get() {
return fieldValue.get();
},
set(v) {
fieldValue.set(v);
},
});

@@ -51,0 +57,0 @@ } else {

@@ -1,8 +0,37 @@

import { StructAsyncDeserializeStream, StructDefaultOptions, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions, StructValue, STRUCT_VALUE_SYMBOL } from './basic/index.js';
import {
STRUCT_VALUE_SYMBOL,
StructDefaultOptions,
StructValue,
type StructAsyncDeserializeStream,
type StructDeserializeStream,
type StructFieldDefinition,
type StructFieldValue,
type StructOptions,
} from "./basic/index.js";
import { SyncPromise } from "./sync-promise.js";
import { BigIntFieldDefinition, BigIntFieldType, BufferFieldSubType, FixedLengthBufferLikeFieldDefinition, NumberFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, type FixedLengthBufferLikeFieldOptions, type LengthField, type VariableLengthBufferLikeFieldOptions } from './types/index.js';
import type { Evaluate, Identity, Overwrite, ValueOrPromise } from "./utils.js";
import {
BigIntFieldDefinition,
BigIntFieldType,
FixedLengthBufferLikeFieldDefinition,
NumberFieldDefinition,
NumberFieldType,
StringBufferFieldSubType,
Uint8ArrayBufferFieldSubType,
VariableLengthBufferLikeFieldDefinition,
type BufferFieldSubType,
type FixedLengthBufferLikeFieldOptions,
type LengthField,
type VariableLengthBufferLikeFieldOptions,
} from "./types/index.js";
import {
type Evaluate,
type Identity,
type Overwrite,
type ValueOrPromise,
} from "./utils.js";
export interface StructLike<TValue> {
deserialize(stream: StructDeserializeStream | StructAsyncDeserializeStream): Promise<TValue>;
deserialize(
stream: StructDeserializeStream | StructAsyncDeserializeStream
): Promise<TValue>;
}

@@ -13,4 +42,5 @@

*/
export type StructValueType<T extends StructLike<any>> =
Awaited<ReturnType<T['deserialize']>>;
export type StructValueType<T extends StructLike<unknown>> = Awaited<
ReturnType<T["deserialize"]>
>;

@@ -27,12 +57,13 @@ /**

TDefinition extends StructFieldDefinition<any, any, any>
> =
Identity<Struct<
> = Identity<
Struct<
// Merge two types
// Evaluate immediately to optimize editor hover tooltip
Evaluate<TFields & Record<TFieldName, TDefinition['TValue']>>,
Evaluate<TFields & Record<TFieldName, TDefinition["TValue"]>>,
// Merge two `TOmitInitKey`s
TOmitInitKey | TDefinition['TOmitInitKey'],
TOmitInitKey | TDefinition["TOmitInitKey"],
TExtra,
TPostDeserialized
>>;
>
>;

@@ -47,3 +78,3 @@ /**

TPostDeserialized
> {
> {
/**

@@ -61,8 +92,8 @@ * Append a fixed-length array buffer like field to the `Struct`

TType extends BufferFieldSubType<any, any>,
TTypeScriptType = TType['TTypeScriptType'],
>(
TTypeScriptType = TType["TTypeScriptType"]
>(
name: TName,
type: TType,
options: FixedLengthBufferLikeFieldOptions,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
): AddFieldDescriptor<

@@ -87,8 +118,8 @@ TFields,

TOptions extends VariableLengthBufferLikeFieldOptions<TFields>,
TTypeScriptType = TType['TTypeScriptType'],
>(
TTypeScriptType = TType["TTypeScriptType"]
>(
name: TName,
type: TType,
options: TOptions,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
): AddFieldDescriptor<

@@ -100,6 +131,3 @@ TFields,

TName,
VariableLengthBufferLikeFieldDefinition<
TType,
TOptions
>
VariableLengthBufferLikeFieldDefinition<TType, TOptions>
>;

@@ -117,10 +145,7 @@ }

TType extends BufferFieldSubType<any, any>
> {
<
TName extends PropertyKey,
TTypeScriptType = TType['TTypeScriptType'],
>(
> {
<TName extends PropertyKey, TTypeScriptType = TType["TTypeScriptType"]>(
name: TName,
options: FixedLengthBufferLikeFieldOptions,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
): AddFieldDescriptor<

@@ -142,8 +167,11 @@ TFields,

TLengthField extends LengthField<TFields>,
TOptions extends VariableLengthBufferLikeFieldOptions<TFields, TLengthField>,
TTypeScriptType = TType['TTypeScriptType'],
>(
TOptions extends VariableLengthBufferLikeFieldOptions<
TFields,
TLengthField
>,
TTypeScriptType = TType["TTypeScriptType"]
>(
name: TName,
options: TOptions,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
): AddFieldDescriptor<

@@ -163,14 +191,25 @@ TFields,

export type StructPostDeserialized<TFields, TPostDeserialized> =
(this: TFields, object: TFields) => TPostDeserialized;
export type StructPostDeserialized<TFields, TPostDeserialized> = (
this: TFields,
object: TFields
) => TPostDeserialized;
export type StructDeserializedResult<TFields extends object, TExtra extends object, TPostDeserialized> =
TPostDeserialized extends undefined ? Overwrite<TExtra, TFields> : TPostDeserialized;
export type StructDeserializedResult<
TFields extends object,
TExtra extends object,
TPostDeserialized
> = TPostDeserialized extends undefined
? Overwrite<TExtra, TFields>
: TPostDeserialized;
export class Struct<
TFields extends object = {},
TFields extends object = Record<never, never>,
TOmitInitKey extends PropertyKey = never,
TExtra extends object = {},
TPostDeserialized = undefined,
> implements StructLike<StructDeserializedResult<TFields, TExtra, TPostDeserialized>>{
TExtra extends object = Record<never, never>,
TPostDeserialized = undefined
> implements
StructLike<
StructDeserializedResult<TFields, TExtra, TPostDeserialized>
>
{
public readonly TFields!: TFields;

@@ -184,3 +223,7 @@

public readonly TDeserializeResult!: StructDeserializedResult<TFields, TExtra, TPostDeserialized>;
public readonly TDeserializeResult!: StructDeserializedResult<
TFields,
TExtra,
TPostDeserialized
>;

@@ -193,5 +236,10 @@ public readonly options: Readonly<StructOptions>;

*/
public get size() { return this._size; }
public get size() {
return this._size;
}
private _fields: [name: PropertyKey, definition: StructFieldDefinition<any, any, any>][] = [];
private _fields: [
name: PropertyKey,
definition: StructFieldDefinition<any, any, any>
][] = [];

@@ -214,3 +262,3 @@ private _extra: Record<PropertyKey, unknown> = {};

name: TName,
definition: TDefinition,
definition: TDefinition
): AddFieldDescriptor<

@@ -226,3 +274,7 @@ TFields,

if (field[0] === name) {
throw new Error(`This struct already have a field with name '${String(name)}'`);
throw new Error(
`This struct already have a field with name '${String(
name
)}'`
);
}

@@ -246,5 +298,5 @@ }

): Struct<
TFields & TOther['TFields'],
TOmitInitKey | TOther['TOmitInitKey'],
TExtra & TOther['TExtra'],
TFields & TOther["TFields"],
TOmitInitKey | TOther["TOmitInitKey"],
TExtra & TOther["TExtra"],
TPostDeserialized

@@ -256,3 +308,6 @@ > {

this._size += other._size;
Object.defineProperties(this._extra, Object.getOwnPropertyDescriptors(other._extra));
Object.defineProperties(
this._extra,
Object.getOwnPropertyDescriptors(other._extra)
);
return this as any;

@@ -264,11 +319,7 @@ }

TType extends NumberFieldType = NumberFieldType,
TTypeScriptType = TType['TTypeScriptType']
>(
name: TName,
type: TType,
typeScriptType?: TTypeScriptType,
) {
TTypeScriptType = number
>(name: TName, type: TType, typeScriptType?: TTypeScriptType) {
return this.field(
name,
new NumberFieldDefinition(type, typeScriptType),
new NumberFieldDefinition(type, typeScriptType)
);

@@ -280,14 +331,7 @@ }

*/
public int8<
TName extends PropertyKey,
TTypeScriptType = (typeof NumberFieldType)['Uint8']['TTypeScriptType']
>(
public int8<TName extends PropertyKey, TTypeScriptType = number>(
name: TName,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
) {
return this.number(
name,
NumberFieldType.Int8,
typeScriptType
);
return this.number(name, NumberFieldType.Int8, typeScriptType);
}

@@ -298,14 +342,7 @@

*/
public uint8<
TName extends PropertyKey,
TTypeScriptType = (typeof NumberFieldType)['Uint8']['TTypeScriptType']
>(
public uint8<TName extends PropertyKey, TTypeScriptType = number>(
name: TName,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
) {
return this.number(
name,
NumberFieldType.Uint8,
typeScriptType
);
return this.number(name, NumberFieldType.Uint8, typeScriptType);
}

@@ -316,14 +353,7 @@

*/
public int16<
TName extends PropertyKey,
TTypeScriptType = (typeof NumberFieldType)['Uint16']['TTypeScriptType']
>(
public int16<TName extends PropertyKey, TTypeScriptType = number>(
name: TName,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
) {
return this.number(
name,
NumberFieldType.Int16,
typeScriptType
);
return this.number(name, NumberFieldType.Int16, typeScriptType);
}

@@ -334,14 +364,7 @@

*/
public uint16<
TName extends PropertyKey,
TTypeScriptType = (typeof NumberFieldType)['Uint16']['TTypeScriptType']
>(
public uint16<TName extends PropertyKey, TTypeScriptType = number>(
name: TName,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
) {
return this.number(
name,
NumberFieldType.Uint16,
typeScriptType
);
return this.number(name, NumberFieldType.Uint16, typeScriptType);
}

@@ -352,14 +375,7 @@

*/
public int32<
TName extends PropertyKey,
TTypeScriptType = (typeof NumberFieldType)['Int32']['TTypeScriptType']
>(
public int32<TName extends PropertyKey, TTypeScriptType = number>(
name: TName,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
) {
return this.number(
name,
NumberFieldType.Int32,
typeScriptType
);
return this.number(name, NumberFieldType.Int32, typeScriptType);
}

@@ -370,14 +386,7 @@

*/
public uint32<
TName extends PropertyKey,
TTypeScriptType = (typeof NumberFieldType)['Uint32']['TTypeScriptType']
>(
public uint32<TName extends PropertyKey, TTypeScriptType = number>(
name: TName,
typeScriptType?: TTypeScriptType,
typeScriptType?: TTypeScriptType
) {
return this.number(
name,
NumberFieldType.Uint32,
typeScriptType
);
return this.number(name, NumberFieldType.Uint32, typeScriptType);
}

@@ -388,11 +397,7 @@

TType extends BigIntFieldType = BigIntFieldType,
TTypeScriptType = TType['TTypeScriptType']
>(
name: TName,
type: TType,
typeScriptType?: TTypeScriptType,
) {
TTypeScriptType = TType["TTypeScriptType"]
>(name: TName, type: TType, typeScriptType?: TTypeScriptType) {
return this.field(
name,
new BigIntFieldDefinition(type, typeScriptType),
new BigIntFieldDefinition(type, typeScriptType)
);

@@ -408,12 +413,5 @@ }

TName extends PropertyKey,
TTypeScriptType = BigIntFieldType['TTypeScriptType']
>(
name: TName,
typeScriptType?: TTypeScriptType,
) {
return this.bigint(
name,
BigIntFieldType.Int64,
typeScriptType
);
TTypeScriptType = BigIntFieldType["TTypeScriptType"]
>(name: TName, typeScriptType?: TTypeScriptType) {
return this.bigint(name, BigIntFieldType.Int64, typeScriptType);
}

@@ -428,12 +426,5 @@

TName extends PropertyKey,
TTypeScriptType = BigIntFieldType['TTypeScriptType']
>(
name: TName,
typeScriptType?: TTypeScriptType,
) {
return this.bigint(
name,
BigIntFieldType.Uint64,
typeScriptType
);
TTypeScriptType = BigIntFieldType["TTypeScriptType"]
>(name: TName, typeScriptType?: TTypeScriptType) {
return this.bigint(name, BigIntFieldType.Uint64, typeScriptType);
}

@@ -449,16 +440,18 @@

type: BufferFieldSubType,
options: FixedLengthBufferLikeFieldOptions | VariableLengthBufferLikeFieldOptions
options:
| FixedLengthBufferLikeFieldOptions
| VariableLengthBufferLikeFieldOptions
): any => {
if ('length' in options) {
return this.field(
name,
new FixedLengthBufferLikeFieldDefinition(type, options),
);
} else {
return this.field(
name,
new VariableLengthBufferLikeFieldDefinition(type, options),
);
}
};
if ("length" in options) {
return this.field(
name,
new FixedLengthBufferLikeFieldDefinition(type, options)
);
} else {
return this.field(
name,
new VariableLengthBufferLikeFieldDefinition(type, options)
);
}
};

@@ -471,9 +464,10 @@ public uint8Array: BoundArrayBufferLikeFieldDefinitionCreator<

Uint8ArrayBufferFieldSubType
> = (
name: PropertyKey,
options: any,
typeScriptType: any,
): any => {
return this.arrayBufferLike(name, Uint8ArrayBufferFieldSubType.Instance, options, typeScriptType);
};
> = (name: PropertyKey, options: any, typeScriptType: any): any => {
return this.arrayBufferLike(
name,
Uint8ArrayBufferFieldSubType.Instance,
options,
typeScriptType
);
};

@@ -486,9 +480,10 @@ public string: BoundArrayBufferLikeFieldDefinitionCreator<

StringBufferFieldSubType
> = (
name: PropertyKey,
options: any,
typeScriptType: any,
): any => {
return this.arrayBufferLike(name, StringBufferFieldSubType.Instance, options, typeScriptType);
};
> = (name: PropertyKey, options: any, typeScriptType: any): any => {
return this.arrayBufferLike(
name,
StringBufferFieldSubType.Instance,
options,
typeScriptType
);
};

@@ -505,17 +500,11 @@ /**

*/
public extra<T extends Record<
// This trick disallows any keys that are already in `TValue`
Exclude<
keyof T,
Exclude<keyof T, keyof TFields>
>,
never
>>(
public extra<
T extends Record<
// This trick disallows any keys that are already in `TValue`
Exclude<keyof T, Exclude<keyof T, keyof TFields>>,
never
>
>(
value: T & ThisType<Overwrite<Overwrite<TExtra, T>, TFields>>
): Struct<
TFields,
TOmitInitKey,
Overwrite<TExtra, T>,
TPostDeserialized
> {
): Struct<TFields, TOmitInitKey, Overwrite<TExtra, T>, TPostDeserialized> {
Object.defineProperties(

@@ -555,5 +544,3 @@ this._extra,

): Struct<TFields, TOmitInitKey, TExtra, TPostSerialize>;
public postDeserialize(
callback?: StructPostDeserialized<TFields, any>
) {
public postDeserialize(callback?: StructPostDeserialized<TFields, any>) {
this._postDeserialized = callback;

@@ -567,10 +554,12 @@ return this as any;

public deserialize(
stream: StructDeserializeStream,
stream: StructDeserializeStream
): StructDeserializedResult<TFields, TExtra, TPostDeserialized>;
public deserialize(
stream: StructAsyncDeserializeStream,
stream: StructAsyncDeserializeStream
): Promise<StructDeserializedResult<TFields, TExtra, TPostDeserialized>>;
public deserialize(
stream: StructDeserializeStream | StructAsyncDeserializeStream,
): ValueOrPromise<StructDeserializedResult<TFields, TExtra, TPostDeserialized>> {
stream: StructDeserializeStream | StructAsyncDeserializeStream
): ValueOrPromise<
StructDeserializedResult<TFields, TExtra, TPostDeserialized>
> {
const structValue = new StructValue(this._extra);

@@ -583,5 +572,9 @@

.then(() =>
definition.deserialize(this.options, stream as any, structValue)
definition.deserialize(
this.options,
stream as any,
structValue
)
)
.then(fieldValue => {
.then((fieldValue) => {
structValue.set(name, fieldValue);

@@ -597,3 +590,6 @@ });

if (this._postDeserialized) {
const override = this._postDeserialized.call(object, object);
const override = this._postDeserialized.call(
object,
object
);
// If it returns a new value, use that as result

@@ -612,4 +608,10 @@ // Otherwise it only inspects/mutates the object in place.

public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>): Uint8Array;
public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>, output: Uint8Array): number;
public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>, output?: Uint8Array): Uint8Array | number {
public serialize(
init: Evaluate<Omit<TFields, TOmitInitKey>>,
output: Uint8Array
): number;
public serialize(
init: Evaluate<Omit<TFields, TOmitInitKey>>,
output?: Uint8Array
): Uint8Array | number {
let structValue: StructValue;

@@ -637,3 +639,3 @@ if (STRUCT_VALUE_SYMBOL in init) {

let structSize = 0;
const fieldsInfo: { fieldValue: StructFieldValue, size: number; }[] = [];
const fieldsInfo: { fieldValue: StructFieldValue; size: number }[] = [];

@@ -647,9 +649,13 @@ for (const [name] of this._fields) {

let outputType = 'number';
let outputType = "number";
if (!output) {
output = new Uint8Array(structSize);
outputType = 'Uint8Array';
outputType = "Uint8Array";
}
const dataView = new DataView(output.buffer, output.byteOffset, output.byteLength);
const dataView = new DataView(
output.buffer,
output.byteOffset,
output.byteLength
);
let offset = 0;

@@ -661,3 +667,3 @@ for (const { fieldValue, size } of fieldsInfo) {

if (outputType === 'number') {
if (outputType === "number") {
return structSize;

@@ -664,0 +670,0 @@ } else {

export interface SyncPromise<T> {
then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
onfulfilled?:
| ((value: T) => TResult1 | PromiseLike<TResult1>)
| null
| undefined,
onrejected?:
| ((reason: any) => TResult2 | PromiseLike<TResult2>)
| null
| undefined
): SyncPromise<TResult1 | TResult2>;

@@ -25,5 +31,5 @@

if (
typeof value === 'object' &&
typeof value === "object" &&
value !== null &&
typeof (value as PromiseLike<T>).then === 'function'
typeof (value as PromiseLike<T>).then === "function"
) {

@@ -49,3 +55,3 @@ if (

}
}
},
};

@@ -61,4 +67,10 @@

public then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
onfulfilled?:
| ((value: T) => TResult1 | PromiseLike<TResult1>)
| null
| undefined,
onrejected?:
| ((reason: any) => TResult2 | PromiseLike<TResult2>)
| null
| undefined
) {

@@ -82,5 +94,7 @@ return new PendingSyncPromise<TResult1 | TResult2>(

public then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
public then<TResult1 = T>(
onfulfilled?:
| ((value: T) => TResult1 | PromiseLike<TResult1>)
| null
| undefined
) {

@@ -106,4 +120,10 @@ if (!onfulfilled) {

public then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
onfulfilled?:
| ((value: T) => TResult1 | PromiseLike<TResult1>)
| null
| undefined,
onrejected?:
| ((reason: any) => TResult2 | PromiseLike<TResult2>)
| null
| undefined
) {

@@ -110,0 +130,0 @@ if (!onrejected) {

@@ -1,9 +0,31 @@

import { getBigInt64, getBigUint64, setBigInt64, setBigUint64 } from '@yume-chan/dataview-bigint-polyfill/esm/fallback.js';
import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from "../basic/index.js";
import {
getBigInt64,
getBigUint64,
setBigInt64,
setBigUint64,
} from "@yume-chan/dataview-bigint-polyfill/esm/fallback.js";
import {
StructFieldDefinition,
StructFieldValue,
type StructAsyncDeserializeStream,
type StructDeserializeStream,
type StructOptions,
type StructValue,
} from "../basic/index.js";
import { SyncPromise } from "../sync-promise.js";
import type { ValueOrPromise } from "../utils.js";
import { type ValueOrPromise } from "../utils.js";
type DataViewBigInt64Getter = (dataView: DataView, byteOffset: number, littleEndian: boolean | undefined) => bigint;
type DataViewBigInt64Getter = (
dataView: DataView,
byteOffset: number,
littleEndian: boolean | undefined
) => bigint;
type DataViewBigInt64Setter = (dataView: DataView, byteOffset: number, value: bigint, littleEndian: boolean | undefined) => void;
type DataViewBigInt64Setter = (
dataView: DataView,
byteOffset: number,
value: bigint,
littleEndian: boolean | undefined
) => void;

@@ -22,3 +44,3 @@ export class BigIntFieldType {

getter: DataViewBigInt64Getter,
setter: DataViewBigInt64Setter,
setter: DataViewBigInt64Setter
) {

@@ -30,5 +52,13 @@ this.size = size;

public static readonly Int64 = new BigIntFieldType(8, getBigInt64, setBigInt64);
public static readonly Int64 = new BigIntFieldType(
8,
getBigInt64,
setBigInt64
);
public static readonly Uint64 = new BigIntFieldType(8, getBigUint64, setBigUint64);
public static readonly Uint64 = new BigIntFieldType(
8,
getBigUint64,
setBigUint64
);
}

@@ -38,10 +68,8 @@

TType extends BigIntFieldType = BigIntFieldType,
TTypeScriptType = TType["TTypeScriptType"],
> extends StructFieldDefinition<
void,
TTypeScriptType
> {
TTypeScriptType = TType["TTypeScriptType"]
> extends StructFieldDefinition<void, TTypeScriptType> {
public readonly type: TType;
public constructor(type: TType, _typescriptType?: TTypeScriptType) {
public constructor(type: TType, typescriptType?: TTypeScriptType) {
void typescriptType;
super();

@@ -58,3 +86,3 @@ this.type = type;

struct: StructValue,
value: TTypeScriptType,
value: TTypeScriptType
): BigIntFieldValue<this> {

@@ -67,3 +95,3 @@ return new BigIntFieldValue(this, options, struct, value);

stream: StructDeserializeStream,
struct: StructValue,
struct: StructValue
): BigIntFieldValue<this>;

@@ -73,3 +101,3 @@ public override deserialize(

stream: StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): Promise<BigIntFieldValue<this>>;

@@ -79,15 +107,14 @@ public override deserialize(

stream: StructDeserializeStream | StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): ValueOrPromise<BigIntFieldValue<this>> {
return SyncPromise
.try(() => {
return stream.read(this.getSize());
})
.then(array => {
const view = new DataView(array.buffer, array.byteOffset, array.byteLength);
const value = this.type.getter(
view,
0,
options.littleEndian
return SyncPromise.try(() => {
return stream.read(this.getSize());
})
.then((array) => {
const view = new DataView(
array.buffer,
array.byteOffset,
array.byteLength
);
const value = this.type.getter(view, 0, options.littleEndian);
return this.create(options, struct, value as any);

@@ -100,4 +127,4 @@ })

export class BigIntFieldValue<
TDefinition extends BigIntFieldDefinition<BigIntFieldType, any>,
> extends StructFieldValue<TDefinition> {
TDefinition extends BigIntFieldDefinition<BigIntFieldType, any>
> extends StructFieldValue<TDefinition> {
public serialize(dataView: DataView, offset: number): void {

@@ -107,3 +134,3 @@ this.definition.type.setter(

offset,
this.value!,
this.value,
this.options.littleEndian

@@ -110,0 +137,0 @@ );

@@ -1,2 +0,9 @@

import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from '../../basic/index.js';
import {
StructFieldDefinition,
StructFieldValue,
type StructAsyncDeserializeStream,
type StructDeserializeStream,
type StructOptions,
type StructValue,
} from "../../basic/index.js";
import { SyncPromise } from "../../sync-promise.js";

@@ -14,3 +21,6 @@ import { decodeUtf8, encodeUtf8, type ValueOrPromise } from "../../utils.js";

*/
export abstract class BufferFieldSubType<TValue = unknown, TTypeScriptType = TValue> {
export abstract class BufferFieldSubType<
TValue = unknown,
TTypeScriptType = TValue
> {
public readonly TTypeScriptType!: TTypeScriptType;

@@ -40,4 +50,5 @@

/** An `BufferFieldSubType` that's actually an `Uint8Array` */
export class Uint8ArrayBufferFieldSubType<TTypeScriptType = Uint8Array>
extends BufferFieldSubType<Uint8Array, TTypeScriptType> {
export class Uint8ArrayBufferFieldSubType<
TTypeScriptType = Uint8Array
> extends BufferFieldSubType<Uint8Array, TTypeScriptType> {
public static readonly Instance = new Uint8ArrayBufferFieldSubType();

@@ -63,4 +74,5 @@

/** An `BufferFieldSubType` that converts between `Uint8Array` and `string` */
export class StringBufferFieldSubType<TTypeScriptType = string>
extends BufferFieldSubType<string, TTypeScriptType> {
export class StringBufferFieldSubType<
TTypeScriptType = string
> extends BufferFieldSubType<string, TTypeScriptType> {
public static readonly Instance = new StringBufferFieldSubType();

@@ -87,11 +99,10 @@

export abstract class BufferLikeFieldDefinition<
TType extends BufferFieldSubType<any, any> = BufferFieldSubType<unknown, unknown>,
TType extends BufferFieldSubType<any, any> = BufferFieldSubType<
unknown,
unknown
>,
TOptions = void,
TOmitInitKey extends PropertyKey = never,
TTypeScriptType = TType["TTypeScriptType"],
> extends StructFieldDefinition<
TOptions,
TTypeScriptType,
TOmitInitKey
>{
TTypeScriptType = TType["TTypeScriptType"]
> extends StructFieldDefinition<TOptions, TTypeScriptType, TOmitInitKey> {
public readonly type: TType;

@@ -105,2 +116,3 @@

protected getDeserializeSize(struct: StructValue): number {
void struct;
return this.getSize();

@@ -115,4 +127,4 @@ }

struct: StructValue,
value: TType['TTypeScriptType'],
array?: Uint8Array,
value: TType["TTypeScriptType"],
array?: Uint8Array
): BufferLikeFieldValue<this> {

@@ -125,3 +137,3 @@ return new BufferLikeFieldValue(this, options, struct, value, array);

stream: StructDeserializeStream,
struct: StructValue,
struct: StructValue
): BufferLikeFieldValue<this>;

@@ -131,3 +143,3 @@ public override deserialize(

stream: StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): Promise<BufferLikeFieldValue<this>>;

@@ -137,14 +149,13 @@ public override deserialize(

stream: StructDeserializeStream | StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): ValueOrPromise<BufferLikeFieldValue<this>> {
return SyncPromise
.try(() => {
const size = this.getDeserializeSize(struct);
if (size === 0) {
return EMPTY_UINT8_ARRAY;
} else {
return stream.read(size);
}
})
.then(array => {
return SyncPromise.try(() => {
const size = this.getDeserializeSize(struct);
if (size === 0) {
return EMPTY_UINT8_ARRAY;
} else {
return stream.read(size);
}
})
.then((array) => {
const value = this.type.toValue(array);

@@ -158,4 +169,8 @@ return this.create(options, struct, value, array);

export class BufferLikeFieldValue<
TDefinition extends BufferLikeFieldDefinition<BufferFieldSubType<unknown, unknown>, any, any>,
> extends StructFieldValue<TDefinition> {
TDefinition extends BufferLikeFieldDefinition<
BufferFieldSubType<unknown, unknown>,
any,
any
>
> extends StructFieldValue<TDefinition> {
protected array: Uint8Array | undefined;

@@ -167,4 +182,4 @@

struct: StructValue,
value: TDefinition['TValue'],
array?: Uint8Array,
value: TDefinition["TValue"],
array?: Uint8Array
) {

@@ -175,3 +190,3 @@ super(definition, options, struct, value);

public override set(value: TDefinition['TValue']): void {
public override set(value: TDefinition["TValue"]): void {
super.set(value);

@@ -188,5 +203,8 @@ // When value changes, clear the cached `array`

new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength)
.set(this.array, offset);
new Uint8Array(
dataView.buffer,
dataView.byteOffset,
dataView.byteLength
).set(this.array, offset);
}
}

@@ -10,12 +10,7 @@ import { BufferLikeFieldDefinition, type BufferFieldSubType } from "./base.js";

TOptions extends FixedLengthBufferLikeFieldOptions = FixedLengthBufferLikeFieldOptions,
TTypeScriptType = TType["TTypeScriptType"],
> extends BufferLikeFieldDefinition<
TType,
TOptions,
never,
TTypeScriptType
> {
TTypeScriptType = TType["TTypeScriptType"]
> extends BufferLikeFieldDefinition<TType, TOptions, never, TTypeScriptType> {
public getSize(): number {
return this.options.length;
}
};
}

@@ -1,5 +0,15 @@

import { StructFieldValue, type StructFieldDefinition, type StructOptions, type StructValue } from '../../basic/index.js';
import type { KeysOfType } from '../../utils.js';
import { BufferLikeFieldDefinition, BufferLikeFieldValue, type BufferFieldSubType } from './base.js';
import {
StructFieldValue,
type StructFieldDefinition,
type StructOptions,
type StructValue,
} from "../../basic/index.js";
import { type KeysOfType } from "../../utils.js";
import {
BufferLikeFieldDefinition,
BufferLikeFieldValue,
type BufferFieldSubType,
} from "./base.js";
export type LengthField<TFields> = KeysOfType<TFields, number | string>;

@@ -9,4 +19,4 @@

TFields = object,
TLengthField extends LengthField<TFields> = any,
> {
TLengthField extends LengthField<TFields> = any
> {
/**

@@ -31,9 +41,9 @@ * The name of the field that contains the length of the buffer.

TOptions extends VariableLengthBufferLikeFieldOptions = VariableLengthBufferLikeFieldOptions,
TTypeScriptType = TType["TTypeScriptType"],
> extends BufferLikeFieldDefinition<
TTypeScriptType = TType["TTypeScriptType"]
> extends BufferLikeFieldDefinition<
TType,
TOptions,
TOptions['lengthField'],
TOptions["lengthField"],
TTypeScriptType
> {
> {
public getSize(): number {

@@ -45,3 +55,3 @@ return 0;

let value = struct.value[this.options.lengthField] as number | string;
if (typeof value === 'string') {
if (typeof value === "string") {
value = Number.parseInt(value, this.options.lengthFieldRadix ?? 10);

@@ -63,3 +73,3 @@ }

value,
array,
array
);

@@ -70,4 +80,4 @@ }

export class VariableLengthBufferLikeStructFieldValue<
TDefinition extends VariableLengthBufferLikeFieldDefinition = VariableLengthBufferLikeFieldDefinition,
> extends BufferLikeFieldValue<TDefinition> {
TDefinition extends VariableLengthBufferLikeFieldDefinition = VariableLengthBufferLikeFieldDefinition
> extends BufferLikeFieldValue<TDefinition> {
protected length: number | undefined;

@@ -81,4 +91,4 @@

struct: StructValue,
value: TDefinition['TValue'],
array?: Uint8Array,
value: TDefinition["TValue"],
array?: Uint8Array
) {

@@ -97,3 +107,3 @@ super(definition, options, struct, value, array);

originalValue,
this,
this
);

@@ -123,7 +133,7 @@ struct.set(lengthField, this.lengthFieldValue);

// Not using `VariableLengthBufferLikeStructFieldValue` directly makes writing tests much easier...
type VariableLengthBufferLikeFieldValueLike =
StructFieldValue<StructFieldDefinition<VariableLengthBufferLikeFieldOptions, any, any>>;
type VariableLengthBufferLikeFieldValueLike = StructFieldValue<
StructFieldDefinition<VariableLengthBufferLikeFieldOptions, any, any>
>;
export class VariableLengthBufferLikeFieldLengthValue
extends StructFieldValue {
export class VariableLengthBufferLikeFieldLengthValue extends StructFieldValue {
protected originalField: StructFieldValue;

@@ -135,5 +145,10 @@

originalField: StructFieldValue,
arrayBufferField: VariableLengthBufferLikeFieldValueLike,
arrayBufferField: VariableLengthBufferLikeFieldValueLike
) {
super(originalField.definition, originalField.options, originalField.struct, 0);
super(
originalField.definition,
originalField.options,
originalField.struct,
0
);
this.originalField = originalField;

@@ -151,4 +166,6 @@ this.bufferField = arrayBufferField;

const originalValue = this.originalField.get();
if (typeof originalValue === 'string') {
value = value.toString(this.bufferField.definition.options.lengthFieldRadix ?? 10);
if (typeof originalValue === "string") {
value = value.toString(
this.bufferField.definition.options.lengthFieldRadix ?? 10
);
}

@@ -155,0 +172,0 @@

@@ -1,57 +0,113 @@

import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from '../basic/index.js';
import {
StructFieldDefinition,
StructFieldValue,
type StructAsyncDeserializeStream,
type StructDeserializeStream,
type StructOptions,
type StructValue,
} from "../basic/index.js";
import { SyncPromise } from "../sync-promise.js";
import type { ValueOrPromise } from "../utils.js";
import { type ValueOrPromise } from "../utils.js";
type NumberTypeDeserializer = (array: Uint8Array, littleEndian: boolean) => number;
export interface NumberFieldType {
signed: boolean;
size: number;
deserialize(array: Uint8Array, littleEndian: boolean): number;
serialize(
dataView: DataView,
offset: number,
value: number,
littleEndian: boolean
): void;
}
const DESERIALIZERS: Record<number, NumberTypeDeserializer> = {
1: (array, littleEndian) =>
array[0]!,
2: (array, littleEndian) =>
((array[1]! << 8) | array[0]!) * (littleEndian as any) |
((array[0]! << 8) | array[1]!) * (!littleEndian as any),
4: (array, littleEndian) =>
((array[3]! << 24) | (array[2]! << 16) | (array[1]! << 8) | array[0]!) * (littleEndian as any) |
((array[0]! << 24) | (array[1]! << 16) | (array[2]! << 8) | array[3]!) * (!littleEndian as any),
};
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace NumberFieldType {
export const Uint8: NumberFieldType = {
signed: false,
size: 1,
deserialize(array) {
return array[0]!;
},
serialize(dataView, offset, value) {
dataView.setUint8(offset, value);
},
};
export type DataViewSetters =
{ [TKey in keyof DataView]: TKey extends `set${string}` ? TKey : never }[keyof DataView];
export const Int8: NumberFieldType = {
signed: true,
size: 1,
deserialize(array) {
const value = Uint8.deserialize(array, false);
return (value << 24) >> 24;
},
serialize(dataView, offset, value) {
dataView.setInt8(offset, value);
},
};
export class NumberFieldType {
public readonly TTypeScriptType!: number;
export const Uint16: NumberFieldType = {
signed: false,
size: 2,
deserialize(array, littleEndian) {
// PERF: Chrome's `DataView#getUint16` uses inefficient operations,
// including branching, bit extending and 32-bit bit swapping.
// The best way should use 16-bit bit rotation and conditional move,
// like LLVM does for code similar to the below one.
// This code is much faster on V8, but the actual generated assembly is unknown.
return (
(((array[1]! << 8) | array[0]!) * (littleEndian as any)) |
(((array[0]! << 8) | array[1]!) * (!littleEndian as any))
);
},
serialize(dataView, offset, value, littleEndian) {
dataView.setUint16(offset, value, littleEndian);
},
};
public readonly signed: boolean;
export const Int16: NumberFieldType = {
signed: true,
size: 2,
deserialize(array, littleEndian) {
const value = Uint16.deserialize(array, littleEndian);
return (value << 16) >> 16;
},
serialize(dataView, offset, value, littleEndian) {
dataView.setInt16(offset, value, littleEndian);
},
};
public readonly size: number;
export const Uint32: NumberFieldType = {
signed: false,
size: 4,
deserialize(array, littleEndian) {
const value = Int32.deserialize(array, littleEndian);
return value >>> 0;
},
serialize(dataView, offset, value, littleEndian) {
dataView.setUint32(offset, value, littleEndian);
},
};
public readonly deserializer: NumberTypeDeserializer;
public readonly convertSign: (value: number) => number;
public readonly dataViewSetter: DataViewSetters;
public constructor(
size: number,
signed: boolean,
convertSign: (value: number) => number,
dataViewSetter: DataViewSetters
) {
this.size = size;
this.signed = signed;
this.deserializer = DESERIALIZERS[size]!;
this.convertSign = convertSign;
this.dataViewSetter = dataViewSetter;
}
public static readonly Int8 = new NumberFieldType(1, true, value => value << 24 >> 24, 'setInt8');
public static readonly Uint8 = new NumberFieldType(1, false, value => value, 'setUint8');
public static readonly Int16 = new NumberFieldType(2, true, value => value << 16 >> 16, 'setInt16');
public static readonly Uint16 = new NumberFieldType(2, false, value => value, 'setUint16');
public static readonly Int32 = new NumberFieldType(4, true, value => value, 'setInt32');
public static readonly Uint32 = new NumberFieldType(4, false, value => value >>> 0, 'setUint32');
export const Int32: NumberFieldType = {
signed: true,
size: 4,
deserialize(array, littleEndian) {
return (
(((array[3]! << 24) |
(array[2]! << 16) |
(array[1]! << 8) |
array[0]!) *
(littleEndian as any)) |
(((array[0]! << 24) |
(array[1]! << 16) |
(array[2]! << 8) |
array[3]!) *
(!littleEndian as any))
);
},
serialize(dataView, offset, value, littleEndian) {
dataView.setInt32(offset, value, littleEndian);
},
};
}

@@ -61,10 +117,8 @@

TType extends NumberFieldType = NumberFieldType,
TTypeScriptType = TType["TTypeScriptType"],
> extends StructFieldDefinition<
void,
TTypeScriptType
> {
TTypeScriptType = number
> extends StructFieldDefinition<void, TTypeScriptType> {
public readonly type: TType;
public constructor(type: TType, _typescriptType?: TTypeScriptType) {
public constructor(type: TType, typescriptType?: TTypeScriptType) {
void typescriptType;
super();

@@ -81,3 +135,3 @@ this.type = type;

struct: StructValue,
value: TTypeScriptType,
value: TTypeScriptType
): NumberFieldValue<this> {

@@ -90,3 +144,3 @@ return new NumberFieldValue(this, options, struct, value);

stream: StructDeserializeStream,
struct: StructValue,
struct: StructValue
): NumberFieldValue<this>;

@@ -96,3 +150,3 @@ public override deserialize(

stream: StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): Promise<NumberFieldValue<this>>;

@@ -102,12 +156,12 @@ public override deserialize(

stream: StructDeserializeStream | StructAsyncDeserializeStream,
struct: StructValue,
struct: StructValue
): ValueOrPromise<NumberFieldValue<this>> {
return SyncPromise
.try(() => {
return stream.read(this.getSize());
})
.then(array => {
let value: number;
value = this.type.deserializer(array, options.littleEndian);
value = this.type.convertSign(value);
return SyncPromise.try(() => {
return stream.read(this.getSize());
})
.then((array) => {
const value = this.type.deserialize(
array,
options.littleEndian
);
return this.create(options, struct, value as any);

@@ -120,11 +174,9 @@ })

export class NumberFieldValue<
TDefinition extends NumberFieldDefinition<NumberFieldType, any>,
> extends StructFieldValue<TDefinition> {
TDefinition extends NumberFieldDefinition<NumberFieldType, any>
> extends StructFieldValue<TDefinition> {
public serialize(dataView: DataView, offset: number): void {
// `setBigInt64` requires a `bigint` while others require `number`
// So `dataView[DataViewSetters]` requires `bigint & number`
// and that is, `never`
(dataView[this.definition.type.dataViewSetter] as any)(
this.definition.type.serialize(
dataView,
offset,
this.value!,
this.value,
this.options.littleEndian

@@ -131,0 +183,0 @@ );

@@ -28,4 +28,5 @@ /**

*/
export type Overwrite<TBase extends object, TNew extends object> =
Evaluate<Omit<TBase, keyof TNew> & TNew>;
export type Overwrite<TBase extends object, TNew extends object> = Evaluate<
Omit<TBase, keyof TNew> & TNew
>;

@@ -35,3 +36,6 @@ /**

*/
export type OmitNever<T> = Pick<T, { [K in keyof T]: [T[K]] extends [never] ? never : K }[keyof T]>;
export type OmitNever<T> = Pick<
T,
{ [K in keyof T]: [T[K]] extends [never] ? never : K }[keyof T]
>;

@@ -41,4 +45,5 @@ /**

*/
export type KeysOfType<T, TValue> =
{ [TKey in keyof T]: T[TKey] extends TValue ? TKey : never }[keyof T];
export type KeysOfType<T, TValue> = {
[TKey in keyof T]: T[TKey] extends TValue ? TKey : never;
}[keyof T];

@@ -56,3 +61,3 @@ export type ValueOrPromise<T> = T | PromiseLike<T>;

// because they will pollute the global scope
// So `TextEncoder` and `TextDecoder` are not available
// So `TextEncoder` and `TextDecoder` types are not available

@@ -63,5 +68,22 @@ // Node.js 8.3 ships `TextEncoder` and `TextDecoder` in `util` module.

// @ts-expect-error
declare class TextEncoderType {
constructor();
encode(input: string): Uint8Array;
}
declare class TextDecoderType {
constructor();
decode(buffer: ArrayBufferView | ArrayBuffer): string;
}
interface GlobalExtension {
TextEncoder: typeof TextEncoderType;
TextDecoder: typeof TextDecoderType;
}
const { TextEncoder, TextDecoder } = globalThis as unknown as GlobalExtension;
const Utf8Encoder = new TextEncoder();
// @ts-expect-error
const Utf8Decoder = new TextDecoder();

@@ -68,0 +90,0 @@

{
"extends": "./node_modules/@yume-chan/ts-package-builder/tsconfig.base.json"
"extends": "./node_modules/@yume-chan/tsconfig/tsconfig.base.json"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc