@haneullabs/bcs 0.1.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +37 -9
  2. package/dist/bcs-type.d.mts +138 -0
  3. package/dist/bcs-type.d.mts.map +1 -0
  4. package/dist/bcs-type.mjs +269 -0
  5. package/dist/bcs-type.mjs.map +1 -0
  6. package/dist/bcs.d.mts +184 -0
  7. package/dist/bcs.d.mts.map +1 -0
  8. package/dist/bcs.mjs +250 -0
  9. package/dist/bcs.mjs.map +1 -0
  10. package/dist/index.d.mts +8 -0
  11. package/dist/index.mjs +8 -0
  12. package/dist/reader.d.mts +96 -0
  13. package/dist/reader.d.mts.map +1 -0
  14. package/dist/reader.mjs +142 -0
  15. package/dist/reader.mjs.map +1 -0
  16. package/dist/types.d.mts +21 -0
  17. package/dist/types.d.mts.map +1 -0
  18. package/dist/types.mjs +1 -0
  19. package/dist/uleb.d.mts +9 -0
  20. package/dist/uleb.d.mts.map +1 -0
  21. package/dist/uleb.mjs +36 -0
  22. package/dist/uleb.mjs.map +1 -0
  23. package/dist/utils.d.mts +24 -0
  24. package/dist/utils.d.mts.map +1 -0
  25. package/dist/utils.mjs +56 -0
  26. package/dist/utils.mjs.map +1 -0
  27. package/dist/writer.d.mts +126 -0
  28. package/dist/writer.d.mts.map +1 -0
  29. package/dist/writer.mjs +179 -0
  30. package/dist/writer.mjs.map +1 -0
  31. package/package.json +19 -25
  32. package/src/bcs.ts +32 -7
  33. package/src/index.ts +21 -34
  34. package/src/uleb.ts +0 -1
  35. package/dist/cjs/bcs-type.d.ts +0 -127
  36. package/dist/cjs/bcs-type.js +0 -386
  37. package/dist/cjs/bcs-type.js.map +0 -7
  38. package/dist/cjs/bcs.d.ts +0 -175
  39. package/dist/cjs/bcs.js +0 -406
  40. package/dist/cjs/bcs.js.map +0 -7
  41. package/dist/cjs/index.d.ts +0 -22
  42. package/dist/cjs/index.js +0 -59
  43. package/dist/cjs/index.js.map +0 -7
  44. package/dist/cjs/package.json +0 -5
  45. package/dist/cjs/reader.d.ts +0 -92
  46. package/dist/cjs/reader.js +0 -136
  47. package/dist/cjs/reader.js.map +0 -7
  48. package/dist/cjs/types.d.ts +0 -28
  49. package/dist/cjs/types.js +0 -17
  50. package/dist/cjs/types.js.map +0 -7
  51. package/dist/cjs/uleb.d.ts +0 -5
  52. package/dist/cjs/uleb.js +0 -66
  53. package/dist/cjs/uleb.js.map +0 -7
  54. package/dist/cjs/utils.d.ts +0 -18
  55. package/dist/cjs/utils.js +0 -74
  56. package/dist/cjs/utils.js.map +0 -7
  57. package/dist/cjs/writer.d.ts +0 -117
  58. package/dist/cjs/writer.js +0 -196
  59. package/dist/cjs/writer.js.map +0 -7
  60. package/dist/esm/bcs-type.d.ts +0 -127
  61. package/dist/esm/bcs-type.js +0 -366
  62. package/dist/esm/bcs-type.js.map +0 -7
  63. package/dist/esm/bcs.d.ts +0 -175
  64. package/dist/esm/bcs.js +0 -397
  65. package/dist/esm/bcs.js.map +0 -7
  66. package/dist/esm/index.d.ts +0 -22
  67. package/dist/esm/index.js +0 -46
  68. package/dist/esm/index.js.map +0 -7
  69. package/dist/esm/package.json +0 -5
  70. package/dist/esm/reader.d.ts +0 -92
  71. package/dist/esm/reader.js +0 -116
  72. package/dist/esm/reader.js.map +0 -7
  73. package/dist/esm/types.d.ts +0 -28
  74. package/dist/esm/types.js +0 -1
  75. package/dist/esm/types.js.map +0 -7
  76. package/dist/esm/uleb.d.ts +0 -5
  77. package/dist/esm/uleb.js +0 -46
  78. package/dist/esm/uleb.js.map +0 -7
  79. package/dist/esm/utils.d.ts +0 -18
  80. package/dist/esm/utils.js +0 -54
  81. package/dist/esm/utils.js.map +0 -7
  82. package/dist/esm/writer.d.ts +0 -117
  83. package/dist/esm/writer.js +0 -176
  84. package/dist/esm/writer.js.map +0 -7
  85. package/dist/tsconfig.esm.tsbuildinfo +0 -1
  86. package/dist/tsconfig.tsbuildinfo +0 -1
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@haneullabs/bcs",
3
- "version": "0.1.0",
3
+ "version": "2.0.2",
4
4
  "description": "BCS - Canonical Binary Serialization implementation for JavaScript",
5
5
  "license": "Apache-2.0",
6
- "author": "Haneul Labs <build@haneullabs.com>",
6
+ "author": "Haneul Labs <build@haneul-labs.com>",
7
7
  "sideEffects": false,
8
- "type": "commonjs",
9
- "main": "./dist/cjs/index.js",
10
- "module": "./dist/esm/index.js",
11
- "types": "./dist/cjs/index.d.ts",
8
+ "type": "module",
9
+ "main": "./dist/index.mjs",
10
+ "types": "./dist/index.d.mts",
12
11
  "exports": {
13
12
  ".": {
14
- "import": "./dist/esm/index.js",
15
- "require": "./dist/cjs/index.js"
13
+ "types": "./dist/index.d.mts",
14
+ "import": "./dist/index.mjs",
15
+ "default": "./dist/index.mjs"
16
16
  }
17
17
  },
18
18
  "files": [
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://github.com/GeunhwaJeong/haneul-ts-sdks.git"
25
+ "url": "git+https://github.com/GeunhwaJeong/ts-sdks.git"
26
26
  },
27
27
  "keywords": [
28
28
  "bcs",
@@ -33,41 +33,35 @@
33
33
  "serde"
34
34
  ],
35
35
  "bugs": {
36
- "url": "https://github.com/GeunhwaJeong/haneul-ts-sdks/issues"
36
+ "url": "https://github.com/GeunhwaJeong/ts-sdks/issues"
37
37
  },
38
38
  "size-limit": [
39
- {
40
- "path": "dist/index.js",
41
- "limit": "10 kB"
42
- },
43
39
  {
44
40
  "path": "dist/index.mjs",
45
41
  "limit": "10 kB"
46
42
  }
47
43
  ],
48
- "homepage": "https://sdk.haneullabs.com/bcs",
44
+ "homepage": "https://sdk.haneul-labs.com/bcs",
49
45
  "devDependencies": {
50
46
  "@size-limit/preset-small-lib": "^12.0.0",
51
47
  "size-limit": "^12.0.0",
52
48
  "typescript": "^5.9.3",
53
- "vitest": "^4.0.15",
54
- "@haneullabs/build-scripts": "0.1.0"
49
+ "vitest": "^4.0.17"
55
50
  },
56
51
  "dependencies": {
57
- "@scure/base": "^1.2.6",
58
- "@haneullabs/utils": "0.1.0"
52
+ "@scure/base": "^2.0.0",
53
+ "@haneullabs/utils": "^0.3.1"
59
54
  },
60
55
  "scripts": {
61
56
  "clean": "rm -rf tsconfig.tsbuildinfo ./dist",
62
- "dev": "pnpm build --watch",
63
- "build": "build-package",
57
+ "build": "rm -rf dist && tsc --noEmit && tsdown",
64
58
  "test": "vitest run --typecheck",
65
59
  "test:watch": "vitest --typecheck",
66
60
  "prettier:check": "prettier -c --ignore-unknown .",
67
61
  "prettier:fix": "prettier -w --ignore-unknown .",
68
- "eslint:check": "eslint --max-warnings=0 .",
69
- "eslint:fix": "pnpm run eslint:check --fix",
70
- "lint": "pnpm run eslint:check && pnpm run prettier:check",
71
- "lint:fix": "pnpm run eslint:fix && pnpm run prettier:fix"
62
+ "oxlint:check": "oxlint .",
63
+ "oxlint:fix": "oxlint --fix",
64
+ "lint": "pnpm run oxlint:check && pnpm run prettier:check",
65
+ "lint:fix": "pnpm run oxlint:fix && pnpm run prettier:fix"
72
66
  }
73
67
  }
package/src/bcs.ts CHANGED
@@ -151,6 +151,21 @@ function vector<T extends BcsType<any>, Name extends string = `vector<${T['name'
151
151
  });
152
152
  }
153
153
 
154
+ /**
155
+ * Compares two byte arrays using lexicographic ordering.
156
+ * This matches Rust's Ord implementation for Vec<u8>/[u8] which is used for BTreeMap key ordering.
157
+ * Comparison is done byte-by-byte first, then by length if all compared bytes are equal.
158
+ */
159
+ export function compareBcsBytes(a: Uint8Array, b: Uint8Array): number {
160
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
161
+ if (a[i] !== b[i]) {
162
+ return a[i] - b[i];
163
+ }
164
+ }
165
+
166
+ return a.length - b.length;
167
+ }
168
+
154
169
  function map<K extends BcsType<any>, V extends BcsType<any>>(
155
170
  keyType: K,
156
171
  valueType: V,
@@ -171,18 +186,28 @@ function map<K extends BcsType<any>, V extends BcsType<any>>(
171
186
  Map<InferBcsInput<K>, InferBcsInput<V>>,
172
187
  `Map<${K['name']}, ${V['name']}>`
173
188
  > {
174
- return bcs.vector(bcs.tuple([keyType, valueType])).transform({
189
+ return new BcsType({
175
190
  name: `Map<${keyType.name}, ${valueType.name}>`,
176
- input: (value: Map<InferBcsInput<K>, InferBcsInput<V>>) => {
177
- return [...value.entries()];
178
- },
179
- output: (value) => {
191
+ read: (reader) => {
192
+ const length = reader.readULEB();
180
193
  const result = new Map<InferBcsType<K>, InferBcsType<V>>();
181
- for (const [key, val] of value) {
182
- result.set(key, val);
194
+ for (let i = 0; i < length; i++) {
195
+ result.set(keyType.read(reader), valueType.read(reader));
183
196
  }
184
197
  return result;
185
198
  },
199
+ write: (value, writer) => {
200
+ const entries = [...value.entries()].map(
201
+ ([key, val]) => [keyType.serialize(key).toBytes(), val] as const,
202
+ );
203
+ entries.sort(([a], [b]) => compareBcsBytes(a, b));
204
+
205
+ writer.writeULEB(entries.length);
206
+ for (const [keyBytes, val] of entries) {
207
+ writer.writeBytes(keyBytes);
208
+ valueType.write(val, writer);
209
+ }
210
+ },
186
211
  });
187
212
  }
188
213
 
package/src/index.ts CHANGED
@@ -21,14 +21,16 @@ import {
21
21
  isSerializedBcs,
22
22
  SerializedBcs,
23
23
  } from './bcs-type.js';
24
- import { bcs } from './bcs.js';
24
+ import { bcs, compareBcsBytes } from './bcs.js';
25
25
  import { BcsReader } from './reader.js';
26
26
  import type {
27
+ Encoding,
27
28
  EnumInputShape,
28
29
  EnumOutputShape,
29
30
  EnumOutputShapeWithKeys,
30
31
  InferBcsInput,
31
32
  InferBcsType,
33
+ JoinString,
32
34
  } from './types.js';
33
35
  import { decodeStr, encodeStr, splitGenericParameters } from './utils.js';
34
36
  import type { BcsWriterOptions } from './writer.js';
@@ -37,46 +39,31 @@ import { BcsWriter } from './writer.js';
37
39
  // Re-export all encoding dependencies.
38
40
  export {
39
41
  bcs,
40
- BcsType,
41
- BcsStruct,
42
42
  BcsEnum,
43
+ BcsReader,
44
+ BcsStruct,
43
45
  BcsTuple,
44
- type BcsTypeOptions,
45
- SerializedBcs,
46
- isSerializedBcs,
47
- toBase58,
46
+ BcsType,
47
+ BcsWriter,
48
+ compareBcsBytes,
49
+ decodeStr,
50
+ encodeStr,
48
51
  fromBase58,
49
- toBase64,
50
52
  fromBase64,
51
- toHex,
52
53
  fromHex,
53
- encodeStr,
54
- decodeStr,
54
+ isSerializedBcs,
55
+ SerializedBcs,
55
56
  splitGenericParameters,
56
- BcsReader,
57
- BcsWriter,
57
+ toBase58,
58
+ toBase64,
59
+ toHex,
60
+ type BcsTypeOptions,
58
61
  type BcsWriterOptions,
59
- type InferBcsInput,
60
- type InferBcsType,
61
- type EnumOutputShape,
62
+ type Encoding,
62
63
  type EnumInputShape,
64
+ type EnumOutputShape,
63
65
  type EnumOutputShapeWithKeys,
66
+ type InferBcsInput,
67
+ type InferBcsType,
68
+ type JoinString,
64
69
  };
65
-
66
- /** @deprecated use toBase58 instead */
67
- export const toB58 = toBase58;
68
-
69
- /** @deprecated use fromBase58 instead */
70
- export const fromB58 = fromBase58;
71
-
72
- /** @deprecated use toBase64 instead */
73
- export const toB64 = toBase64;
74
-
75
- /** @deprecated use fromBase64 instead */
76
- export const fromB64 = fromBase64;
77
-
78
- /** @deprecated use toHex instead */
79
- export const toHEX = toHex;
80
-
81
- /** @deprecated use fromHex instead */
82
- export const fromHEX = fromHex;
package/src/uleb.ts CHANGED
@@ -34,7 +34,6 @@ export function ulebDecode(arr: number[] | Uint8Array): {
34
34
  let shift = 0n;
35
35
  let len = 0;
36
36
 
37
- // eslint-disable-next-line no-constant-condition
38
37
  while (true) {
39
38
  if (len >= arr.length) {
40
39
  throw new Error('ULEB decode error: buffer overflow');
@@ -1,127 +0,0 @@
1
- import { BcsReader } from './reader.js';
2
- import type { BcsWriterOptions } from './writer.js';
3
- import { BcsWriter } from './writer.js';
4
- import type { EnumInputShape, EnumOutputShape, JoinString } from './types.js';
5
- export interface BcsTypeOptions<T, Input = T, Name extends string = string> {
6
- name?: Name;
7
- validate?: (value: Input) => void;
8
- }
9
- export declare class BcsType<T, Input = T, const Name extends string = string> {
10
- #private;
11
- $inferType: T;
12
- $inferInput: Input;
13
- name: Name;
14
- read: (reader: BcsReader) => T;
15
- serializedSize: (value: Input, options?: BcsWriterOptions) => number | null;
16
- validate: (value: Input) => void;
17
- constructor(options: {
18
- name: Name;
19
- read: (reader: BcsReader) => T;
20
- write: (value: Input, writer: BcsWriter) => void;
21
- serialize?: (value: Input, options?: BcsWriterOptions) => Uint8Array<ArrayBuffer>;
22
- serializedSize?: (value: Input) => number | null;
23
- validate?: (value: Input) => void;
24
- } & BcsTypeOptions<T, Input, Name>);
25
- write(value: Input, writer: BcsWriter): void;
26
- serialize(value: Input, options?: BcsWriterOptions): SerializedBcs<T, Input>;
27
- parse(bytes: Uint8Array): T;
28
- fromHex(hex: string): T;
29
- fromBase58(b64: string): T;
30
- fromBase64(b64: string): T;
31
- transform<T2 = T, Input2 = Input, NewName extends string = Name>({ name, input, output, validate, }: {
32
- input?: (val: Input2) => Input;
33
- output?: (value: T) => T2;
34
- } & BcsTypeOptions<T2, Input2, NewName>): BcsType<T2, Input2, NewName>;
35
- }
36
- declare const SERIALIZED_BCS_BRAND: never;
37
- export declare function isSerializedBcs(obj: unknown): obj is SerializedBcs<unknown>;
38
- export declare class SerializedBcs<T, Input = T> {
39
- #private;
40
- [SERIALIZED_BCS_BRAND]: boolean;
41
- constructor(schema: BcsType<T, Input>, bytes: Uint8Array<ArrayBuffer>);
42
- toBytes(): Uint8Array<ArrayBuffer>;
43
- toHex(): string;
44
- toBase64(): string;
45
- toBase58(): string;
46
- parse(): T;
47
- }
48
- export declare function fixedSizeBcsType<T, Input = T, const Name extends string = string>({ size, ...options }: {
49
- name: Name;
50
- size: number;
51
- read: (reader: BcsReader) => T;
52
- write: (value: Input, writer: BcsWriter) => void;
53
- } & BcsTypeOptions<T, Input, Name>): BcsType<T, Input, Name>;
54
- export declare function uIntBcsType<const Name extends string = string>({ readMethod, writeMethod, ...options }: {
55
- name: Name;
56
- size: number;
57
- readMethod: `read${8 | 16 | 32}`;
58
- writeMethod: `write${8 | 16 | 32}`;
59
- maxValue: number;
60
- } & BcsTypeOptions<number, number, Name>): BcsType<number, number, Name>;
61
- export declare function bigUIntBcsType<const Name extends string = string>({ readMethod, writeMethod, ...options }: {
62
- name: Name;
63
- size: number;
64
- readMethod: `read${64 | 128 | 256}`;
65
- writeMethod: `write${64 | 128 | 256}`;
66
- maxValue: bigint;
67
- } & BcsTypeOptions<string, string | number | bigint>): BcsType<string, string | number | bigint, Name>;
68
- export declare function dynamicSizeBcsType<T, Input = T, const Name extends string = string>({ serialize, ...options }: {
69
- name: Name;
70
- read: (reader: BcsReader) => T;
71
- serialize: (value: Input, options?: BcsWriterOptions) => Uint8Array<ArrayBuffer>;
72
- } & BcsTypeOptions<T, Input>): BcsType<T, Input, string>;
73
- export declare function stringLikeBcsType<const Name extends string = string>({ toBytes, fromBytes, ...options }: {
74
- name: Name;
75
- toBytes: (value: string) => Uint8Array;
76
- fromBytes: (bytes: Uint8Array) => string;
77
- serializedSize?: (value: string) => number | null;
78
- } & BcsTypeOptions<string, string, Name>): BcsType<string, string, Name>;
79
- export declare function lazyBcsType<T, Input>(cb: () => BcsType<T, Input>): BcsType<T, Input, string>;
80
- export interface BcsStructOptions<T extends Record<string, BcsType<any>>, Name extends string = string> extends Omit<BcsTypeOptions<{
81
- [K in keyof T]: T[K] extends BcsType<infer U, any> ? U : never;
82
- }, {
83
- [K in keyof T]: T[K] extends BcsType<any, infer U> ? U : never;
84
- }, Name>, 'name'> {
85
- name: Name;
86
- fields: T;
87
- }
88
- export declare class BcsStruct<T extends Record<string, BcsType<any>>, const Name extends string = string> extends BcsType<{
89
- [K in keyof T]: T[K] extends BcsType<infer U, any> ? U : never;
90
- }, {
91
- [K in keyof T]: T[K] extends BcsType<any, infer U> ? U : never;
92
- }, Name> {
93
- constructor({ name, fields, ...options }: BcsStructOptions<T, Name>);
94
- }
95
- export interface BcsEnumOptions<T extends Record<string, BcsType<any> | null>, Name extends string = string> extends Omit<BcsTypeOptions<EnumOutputShape<{
96
- [K in keyof T]: T[K] extends BcsType<infer U, any, any> ? U : true;
97
- }>, EnumInputShape<{
98
- [K in keyof T]: T[K] extends BcsType<any, infer U, any> ? U : boolean | object | null;
99
- }>, Name>, 'name'> {
100
- name: Name;
101
- fields: T;
102
- }
103
- export declare class BcsEnum<T extends Record<string, BcsType<any> | null>, const Name extends string = string> extends BcsType<EnumOutputShape<{
104
- [K in keyof T]: T[K] extends BcsType<infer U, any> ? U : true;
105
- }>, EnumInputShape<{
106
- [K in keyof T]: T[K] extends BcsType<any, infer U, any> ? U : boolean | object | null;
107
- }>, Name> {
108
- constructor({ fields, ...options }: BcsEnumOptions<T, Name>);
109
- }
110
- export interface BcsTupleOptions<T extends readonly BcsType<any>[], Name extends string> extends Omit<BcsTypeOptions<{
111
- -readonly [K in keyof T]: T[K] extends BcsType<infer T, any> ? T : never;
112
- }, {
113
- [K in keyof T]: T[K] extends BcsType<any, infer T> ? T : never;
114
- }, Name>, 'name'> {
115
- name?: Name;
116
- fields: T;
117
- }
118
- export declare class BcsTuple<const T extends readonly BcsType<any>[], const Name extends string = `(${JoinString<{
119
- [K in keyof T]: T[K] extends BcsType<any, any, infer T> ? T : never;
120
- }, ', '>})`> extends BcsType<{
121
- -readonly [K in keyof T]: T[K] extends BcsType<infer T, any> ? T : never;
122
- }, {
123
- [K in keyof T]: T[K] extends BcsType<any, infer T> ? T : never;
124
- }, Name> {
125
- constructor({ fields, name, ...options }: BcsTupleOptions<T, Name>);
126
- }
127
- export {};