UNPKG

@ckb-ccc/core

Version:

Core of CCC - CKBer's Codebase

132 lines (131 loc) 4.47 kB
import { bytesEq } from "../bytes/index.js"; import { hashCkb } from "../hasher/index.js"; /** * The base class of CCC to create a serializable instance. This should be used with the {@link codec} decorator. * @public */ export class Entity { /** * Generate a base class of CCC to create a serializable instance. * This should be used with the {@link codec} decorator. * @public */ static Base() { class Impl { /** * Encode the entity into bytes * @public * @static * @param _ - The entity to encode * @returns The encoded bytes * @throws Will throw an error if the entity is not serializable */ static encode(_) { throw new Error("encode not implemented, use @ccc.mol.codec to decorate your type"); } /** * Decode the entity from bytes * @public * @static * @param _ - The bytes to decode * @returns The decoded entity * @throws Will throw an error if the entity is not serializable */ static decode(_) { throw new Error("decode not implemented, use @ccc.mol.codec to decorate your type"); } /** * Create an entity from bytes * @public * @static * @param _ - The bytes to create the entity from * @returns The created entity * @throws Will throw an error if the entity is not serializable */ static fromBytes(_bytes) { throw new Error("fromBytes not implemented, use @ccc.mol.codec to decorate your type"); } /** * Create an entity from a serializable object * @public * @static * @param _ - The serializable object to create the entity from * @returns The created entity * @throws Will throw an error if the entity is not serializable */ static from(_) { throw new Error("from not implemented"); } /** * Convert the entity to bytes * @public * @returns The bytes representation of the entity */ toBytes() { return this.constructor.encode(this); } /** * Create a clone of the entity * @public * @returns A clone of the entity */ clone() { return this.constructor.fromBytes(this.toBytes()); } /** * Check if the entity is equal to another entity * @public * @param other - The other entity to compare with * @returns True if the entities are equal, false otherwise */ eq(other) { if (this === other) { return true; } return bytesEq(this.toBytes(), /* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */ (this.constructor?.from(other) ?? other).toBytes()); } /** * Calculate the hash of the entity * @public * @returns The hash of the entity */ hash() { return hashCkb(this.toBytes()); } } return Impl; } } /** * A class decorator to add methods implementation on the {@link Entity.Base} class * @example * ```typescript * @mol.codec( * mol.table({ * codeHash: mol.Byte32, * hashType: HashTypeCodec, * args: mol.Bytes, * }), * ) * export class Script extends mol.Entity.Base<ScriptLike, Script>() { * from(scriptLike: ScriptLike): Script {} * } * ``` */ export function codec(codec) { return function (Constructor) { Constructor.byteLength = codec.byteLength; Constructor.encode = function (encodable) { return codec.encode(encodable); }; Constructor.decode = function (bytesLike) { return Constructor.from(codec.decode(bytesLike)); }; Constructor.fromBytes = function (bytes) { return Constructor.from(codec.decode(bytes)); }; return Constructor; }; }