as-borsh
v1.0.0
Published
Borsh serializer code generator for AssemblyScript
Maintainers
Readme
as-borsh
Borsh serializer code generator for AssemblyScript.
as-borsh generates fast, type-safe serializers and deserializers directly into AssemblyScript source code. Generated serializers are compatible with the Borsh binary format for all supported types and can be used for blockchain, networking, persistence, and binary protocol applications.
Features
- Struct serialization
- Nested schemas
- Enum serialization
- Primitive types
- Arrays
- Fixed-size arrays
- Maps
- Sets
- Optional values
- Custom type casting
- Borsh-compatible binary layout
- AssemblyScript-native generated code
- Zero runtime reflection
- Compile-time schema validation
Installation
npm install --save-dev as-borshor
yarn add --dev as-borshInitialize Configuration
Generate a default configuration file:
npx as-borsh initThis creates:
as-borsh.config.jsoncExample:
{
// Root AssemblyScript source directory.
"sourceDir": "assembly",
// Directory containing schema definitions.
"schemaDir": "assembly/schemas",
// Output directory for generated serializers.
"outDir": "assembly/serde",
// Schema file suffix.
"schemaFilter": ".schema.ts",
// Runtime import strategy.
// "package" - import from installed npm package.
// "./path" - import from local templates.
"runtimeImport": "package",
// Sort Set<T> by serialized value bytes.
"sortSet": false,
// Sort Map<K,V> by serialized key bytes.
"sortMap": false
}Generate serializers:
npx as-borsh generateCustom config:
npx as-borsh generate --config my-config.jsoncProject Structure
Example:
assembly/
├── schemas/
│ ├── point.schema.ts
│ ├── circle.schema.ts
│ └── shape.enum.ts
│
└── serde/
├── point.serde.ts
├── circle.serde.ts
├── shape.serde.ts
└── index.tsStruct Schemas
Simple Schema
import { defineSchema, Primitives } from "as-borsh/schema";
export default defineSchema({
name: "Point",
props: {
x: Primitives.F32,
y: Primitives.F32,
},
});Generated:
export class PointSchema extends SerdeSchema {
x: f32;
y: f32;
serialize(): ArrayBuffer;
static deserialize(buffer: ArrayBuffer): PointSchema;
}Nested Schemas
import {
defineSchema,
Schema,
Primitives,
} from "as-borsh/schema";
export default defineSchema({
name: "Circle",
props: {
center: Schema("Point"),
radius: Primitives.F32,
},
});Primitive Types
Supported primitive types:
Primitives.Bool
Primitives.U8
Primitives.U16
Primitives.U32
Primitives.U64
Primitives.I8
Primitives.I16
Primitives.I32
Primitives.I64
Primitives.F32
Primitives.F64
Primitives.StringExample:
export default defineSchema({
name: "User",
props: {
id: Primitives.U32,
score: Primitives.F64,
name: Primitives.String,
active: Primitives.Bool,
},
});Arrays
Dynamic arrays serialize as:
u32 length
items...Example:
import {
defineSchema,
ArrayOf,
Primitives,
} from "as-borsh/schema";
export default defineSchema({
name: "Path",
props: {
points: ArrayOf(Primitives.F32),
},
});Nested arrays:
matrix: ArrayOf(ArrayOf(Primitives.F64))Fixed Arrays
Fixed arrays serialize exactly N items.
No length prefix is written.
import {
defineSchema,
FixedArrayOf,
Primitives,
} from "as-borsh/schema";
export default defineSchema({
name: "Color",
props: {
rgb: FixedArrayOf(
Primitives.U8,
3,
),
},
});Primitive Fixed Arrays
If length is larger than expected:
Array is truncated.If length is smaller:
Missing values are padded.Padding values:
| Type | Padding | | ------- | ------- | | Integer | 0 | | Float | 0 | | Bool | false | | String | "" |
Object Fixed Arrays
Object arrays must contain exactly N elements.
Otherwise serialization throws.
Optional Values
Borsh layout:
u8 present
payloadExample:
import {
defineSchema,
Optional,
Primitives,
} from "as-borsh/schema";
export default defineSchema({
name: "Profile",
props: {
bio: Optional(
Primitives.String,
),
},
});Sets
import {
defineSchema,
SetOf,
Primitives,
} from "as-borsh/schema";
export default defineSchema({
name: "Tags",
props: {
values: SetOf(
Primitives.String,
),
},
});When:
{
"sortSet": true
}items are sorted by serialized bytes before serialization.
Maps
import {
defineSchema,
MapOf,
Primitives,
} from "as-borsh/schema";
export default defineSchema({
name: "Scores",
props: {
values: MapOf(
Primitives.String,
Primitives.U32,
),
},
});When:
{
"sortMap": true
}entries are sorted by serialized key bytes before serialization.
This is recommended for canonical Borsh output.
Enums
Enums serialize as:
u8 variant
payloadExample:
import {
defineEnum,
Schema,
ArrayOf,
} from "as-borsh/schema";
export default defineEnum({
name: "Shape",
variants: {
Dot: null,
Point: Schema("Point"),
Circle: Schema("Circle"),
Curve: ArrayOf(
Schema("Point"),
),
},
});Generated:
export enum ShapeVariant {
Dot,
Point,
Circle,
Curve,
}Usage:
const point = new PointSchema(
10.0,
20.0,
);
const shape =
ShapeSchema.point(point);Deserialize:
const shape =
ShapeSchema.deserialize(bytes);
switch (shape.variant) {
case ShapeVariant.Point: {
const point =
shape.payload<PointSchema>();
break;
}
}CastAs
CastAs allows serializing one type as another compatible type.
Example:
CastAs(
Schema("Point"),
"Vec2",
"../types/vec2.ts"
)Generated code treats the field as Vec2 while serializing it as Point.
Useful for:
- Domain models
- Engine types
- External library types
Usage
Serialize:
const point =
new PointSchema(
10.0,
20.0,
);
const bytes =
point.serialize();Deserialize:
const point =
PointSchema.deserialize(
bytes,
);Borsh Compatibility
Supported:
- Structs
- Nested structs
- Enums
- Bool
- Integers
- Floats
- Strings
- Arrays
- Fixed arrays
- Optionals
- Maps
- Sets
Not supported:
- u128
- i128
because AssemblyScript does not provide native support for these types.
License
MIT License
Copyright (c) Grigorii Zhitnii
