Skip to content

Commit edf5923

Browse files
committed
refactor: add DuplexBuffer interface
1 parent 8a922c4 commit edf5923

File tree

8 files changed

+70
-19
lines changed

8 files changed

+70
-19
lines changed

packages/string-store/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
export type * from './lib/buffer/DuplexBuffer';
2+
export * from './lib/buffer/UnalignedUint16Array';
13
export * from './lib/schema/Schema';
24
export * from './lib/schema/SchemaStore';
35
export * from './lib/shared/Pointer';
46
export * from './lib/types';
5-
export * from './lib/UnalignedUint16Array';
67
export * from './lib/utilities';
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { PointerLike } from '../shared/Pointer';
2+
3+
export interface DuplexBuffer {
4+
at(index: number): number | undefined;
5+
6+
get maxLength(): number;
7+
get maxBitLength(): number;
8+
get length(): number;
9+
get bitLength(): number;
10+
11+
writeBit(value: number): void;
12+
writeInt2(value: number): void;
13+
writeInt4(value: number): void;
14+
writeInt8(value: number): void;
15+
writeInt16(value: number): void;
16+
writeInt32(value: number): void;
17+
writeInt64(value: number): void;
18+
writeBigInt32(value: bigint): void;
19+
writeBigInt64(value: bigint): void;
20+
writeFloat32(value: number): void;
21+
writeFloat64(value: number): void;
22+
23+
readBit(offset: PointerLike): 0 | 1;
24+
readInt2(offset: PointerLike): number;
25+
readUint2(offset: PointerLike): number;
26+
readInt4(offset: PointerLike): number;
27+
readUint4(offset: PointerLike): number;
28+
readInt8(offset: PointerLike): number;
29+
readUint8(offset: PointerLike): number;
30+
readInt16(offset: PointerLike): number;
31+
readUint16(offset: PointerLike): number;
32+
readInt32(offset: PointerLike): number;
33+
readUint32(offset: PointerLike): number;
34+
readInt64(offset: PointerLike): number;
35+
readUint64(offset: PointerLike): number;
36+
readBigInt32(offset: PointerLike): bigint;
37+
readBigUint32(offset: PointerLike): bigint;
38+
readBigInt64(offset: PointerLike): bigint;
39+
readBigUint64(offset: PointerLike): bigint;
40+
readFloat32(offset: PointerLike): number;
41+
readFloat64(offset: PointerLike): number;
42+
43+
toString(): string;
44+
toArray(): Uint16Array;
45+
}

packages/string-store/src/lib/UnalignedUint16Array.ts renamed to packages/string-store/src/lib/buffer/UnalignedUint16Array.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Pointer, type PointerLike } from './shared/Pointer';
1+
import { Pointer, type PointerLike } from '../shared/Pointer';
2+
import type { DuplexBuffer } from './DuplexBuffer';
23

34
const ConverterUint8 = new Uint8Array(8);
45
const ConverterUint16 = new Uint16Array(ConverterUint8.buffer);
@@ -11,7 +12,7 @@ const ConverterInt64 = new BigInt64Array(ConverterUint8.buffer);
1112
const ConverterFloat = new Float32Array(ConverterUint8.buffer);
1213
const ConverterDouble = new Float64Array(ConverterUint8.buffer);
1314

14-
export class UnalignedUint16Array {
15+
export class UnalignedUint16Array implements DuplexBuffer {
1516
#buffer: Uint16Array;
1617
#bitLength = 0;
1718
#wordIndex = 0;
@@ -300,8 +301,8 @@ export class UnalignedUint16Array {
300301
this.#wordLength++;
301302
}
302303

303-
public static from(value: string | UnalignedUint16Array): UnalignedUint16Array {
304-
if (value instanceof UnalignedUint16Array) return value;
304+
public static from(value: string | DuplexBuffer): DuplexBuffer {
305+
if (typeof value !== 'string') return value;
305306

306307
const buffer = new UnalignedUint16Array(value.length);
307308
for (let i = 0; i < value.length; i++) {

packages/string-store/src/lib/schema/Schema.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import type { DuplexBuffer } from '../buffer/DuplexBuffer';
2+
import { UnalignedUint16Array } from '../buffer/UnalignedUint16Array';
13
import { Pointer, type PointerLike } from '../shared/Pointer';
24
import { t, type IType } from '../types/index';
3-
import { UnalignedUint16Array } from '../UnalignedUint16Array';
45

56
export class Schema<Id extends number = number, Entries extends object = object> {
67
readonly #id: Id;
@@ -83,7 +84,7 @@ export class Schema<Id extends number = number, Entries extends object = object>
8384
* @param defaultMaximumArrayLength The default maximum array length, if any
8485
* @returns The newly created buffer.
8586
*/
86-
public serializeRaw(value: Readonly<SerializeValueEntries<Entries>>, defaultMaximumArrayLength = 100): UnalignedUint16Array {
87+
public serializeRaw(value: Readonly<SerializeValueEntries<Entries>>, defaultMaximumArrayLength = 100): DuplexBuffer {
8788
const buffer = new UnalignedUint16Array(this.totalBitSize ?? defaultMaximumArrayLength);
8889
this.serializeInto(buffer, value);
8990
return buffer;
@@ -100,7 +101,7 @@ export class Schema<Id extends number = number, Entries extends object = object>
100101
* The schema's ID is written to the buffer first, followed by each property
101102
* in the schema.
102103
*/
103-
public serializeInto(buffer: UnalignedUint16Array, value: Readonly<SerializeValueEntries<Entries>>): void {
104+
public serializeInto(buffer: DuplexBuffer, value: Readonly<SerializeValueEntries<Entries>>): void {
104105
buffer.writeInt16(this.#id);
105106
for (const [name, type] of this) {
106107
(type as IType<any, number | null>).serialize(buffer, (value as any)[name]);
@@ -119,7 +120,7 @@ export class Schema<Id extends number = number, Entries extends object = object>
119120
* Unlike {@link Schema.serializeInto}, this method does not read the schema's ID
120121
* from the buffer, that is reserved for the {@link SchemaStore}.
121122
*/
122-
public deserialize(buffer: UnalignedUint16Array | string, pointer: PointerLike): UnwrapSchemaEntries<Entries> {
123+
public deserialize(buffer: DuplexBuffer | string, pointer: PointerLike): UnwrapSchemaEntries<Entries> {
123124
buffer = UnalignedUint16Array.from(buffer);
124125
pointer = Pointer.from(pointer);
125126
const result = Object.create(null) as UnwrapSchemaEntries<Entries>;

packages/string-store/src/lib/schema/SchemaStore.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import type { DuplexBuffer } from '../buffer/DuplexBuffer';
2+
import { UnalignedUint16Array } from '../buffer/UnalignedUint16Array';
13
import { Pointer } from '../shared/Pointer';
2-
import { UnalignedUint16Array } from '../UnalignedUint16Array';
34
import { Schema, type SerializeValue, type UnwrapSchema } from './Schema';
45

56
export class SchemaStore<Entries extends object = object> {
@@ -72,7 +73,7 @@ export class SchemaStore<Entries extends object = object> {
7273
* @param value The value to serialize
7374
* @returns The serialized buffer
7475
*/
75-
public serializeRaw<const Id extends KeyOfStore<this>>(id: Id, value: SerializeValue<Entries[Id] & object>): UnalignedUint16Array {
76+
public serializeRaw<const Id extends KeyOfStore<this>>(id: Id, value: SerializeValue<Entries[Id] & object>): DuplexBuffer {
7677
const schema = this.get(id) as Schema<Id, object>;
7778
return schema.serializeRaw(value, this.defaultMaximumArrayLength);
7879
}
@@ -83,7 +84,7 @@ export class SchemaStore<Entries extends object = object> {
8384
* @param buffer The buffer to deserialize
8485
* @returns The resolved value, including the id of the schema used for deserialization
8586
*/
86-
public deserialize(buffer: string | UnalignedUint16Array): DeserializationResult<Entries> {
87+
public deserialize(buffer: string | DuplexBuffer): DeserializationResult<Entries> {
8788
buffer = UnalignedUint16Array.from(buffer);
8889
const pointer = new Pointer();
8990
const id = buffer.readInt16(pointer) as KeyOfStore<this>;
@@ -101,7 +102,7 @@ export class SchemaStore<Entries extends object = object> {
101102
*
102103
* If an empty value is passed, a {@linkcode RangeError} will be thrown.
103104
*/
104-
public getIdentifier(buffer: string | UnalignedUint16Array): KeyOfStore<this> {
105+
public getIdentifier(buffer: string | DuplexBuffer): KeyOfStore<this> {
105106
if (buffer.length === 0) {
106107
throw new RangeError('Expected a non-empty value');
107108
}

packages/string-store/src/lib/types/base/IType.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import type { DuplexBuffer } from '../../buffer/DuplexBuffer';
12
import type { Pointer } from '../../shared/Pointer';
2-
import type { UnalignedUint16Array } from '../../UnalignedUint16Array';
33

44
export interface IType<ValueType, BitSize extends number | null, InputValue = ValueType> {
55
/**
@@ -8,15 +8,15 @@ export interface IType<ValueType, BitSize extends number | null, InputValue = Va
88
* @param buffer The buffer to write to
99
* @param value The value to write
1010
*/
11-
serialize(buffer: UnalignedUint16Array, value: InputValue): void;
11+
serialize(buffer: DuplexBuffer, value: InputValue): void;
1212

1313
/**
1414
* Deserialize a value from a buffer.
1515
*
1616
* @param buffer The buffer to read from
1717
* @param pointer The pointer indicating the current position in the buffer
1818
*/
19-
deserialize(buffer: UnalignedUint16Array, pointer: Pointer): ValueType;
19+
deserialize(buffer: DuplexBuffer, pointer: Pointer): ValueType;
2020

2121
/**
2222
* The size of the value in bits, or `null` if the size is variable.

packages/string-store/tests/lib/SchemaStore.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Float64Type, Schema, SchemaStore, UnalignedUint16Array } from '../../src';
1+
import { Float64Type, Schema, SchemaStore, UnalignedUint16Array, type DuplexBuffer } from '../../src';
22

33
describe('SchemaStore', () => {
44
test('GIVEN an empty SchemaStore THEN it should be empty', () => {
@@ -35,7 +35,7 @@ describe('SchemaStore', () => {
3535
expect<2>(store.getIdentifier(buffer)).toBe(2);
3636
expect<2>(store.getIdentifier(buffer.toString())).toBe(2);
3737

38-
expectTypeOf(buffer).toEqualTypeOf<UnalignedUint16Array>();
38+
expectTypeOf(buffer).toEqualTypeOf<DuplexBuffer>();
3939
});
4040

4141
test('GIVEN a schema and a value THEN it serializes and deserializes the binary string correctly', () => {
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
import { createVitestConfig } from '../../scripts/vitest.config';
22

3-
export default createVitestConfig();
3+
export default createVitestConfig({
4+
test: { coverage: { exclude: ['src/lib/buffer/DuplexBuffer.ts', 'src/lib/types/base/IType.ts'] } }
5+
});

0 commit comments

Comments
 (0)