@phughesmcr/partitionedbuffer@0.2.8Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Built and signed on GitHub Actions
A high-performance PartitionedBuffer implementation backed by Uint32Array for efficient memory usage and fast bitwise operations.
This package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers




JSR Score
100%
Published
3 months ago (0.2.8)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110/** * @module Partition * @description A partition is a component storage interface. * @copyright 2024 the PartitionedBuffer authors. All rights reserved. * @license MIT */ import { getSchemaSize, isSchema, type Schema, type SchemaSpec, type SchemaStorage } from "./Schema.ts"; import { isValidName } from "./utils.ts"; /** * Partition metadata */ export type PartitionMeta<T extends SchemaSpec<T> | null> = { /** * The maximum number of entities able to equip this component per world. * * __Warning__: use this only where memory use is a concern, performance will be worse. */ maxOwners?: number | null; /** The component's label */ name: string; }; /** * Partition schema * If T is null, the partition is a tag and no schema is defined or required. * If T is a SchemaSpec, the partition is a component and a schema value is required. */ export type PartitionSchema<T extends SchemaSpec<T> | null> = T extends SchemaSpec<infer U> ? { schema: Schema<U>; } : { schema?: null; }; /** * Partition specification * * The partition creation instructions. Consisting of a PartitionMeta and a PartitionSchema object. * * @example ``` * // A schema: * type Vec2 = { x: number, y: number }; * const partition: PartitionSpec<Vec2> = { name: "position", schema: { x: Float32Array, y: Float32Array } }; * ``` * * @example ``` * // A tag: * const partition: PartitionSpec<null> = { name: "isAlive" }; * ``` * * @example ``` * // A tag with a maximum number of owners: * const partition: PartitionSpec<null> = { name: "isSpecial", maxOwners: 100 }; * ``` */ export type PartitionSpec<T extends SchemaSpec<T> | null = null> = PartitionSchema<T> & PartitionMeta<T>; /** * Internal partition data storage */ export type PartitionStorage<T extends SchemaSpec<T> | null> = T extends SchemaSpec<infer U> ? SchemaStorage<U> : null; /** * Typeguard for a partition specification * @param spec the partition specification * @returns `true` if the specification is valid */ export function isValidPartitionSpec<T extends SchemaSpec<T> | null>(spec: unknown): spec is PartitionSpec<T> { const { name, schema = null, maxOwners = null } = spec as PartitionSpec<T>; if (!isValidName(name)) return false; if (maxOwners !== null && (!Number.isSafeInteger(maxOwners) || maxOwners <= 0)) { throw new Error("maxOwners must be a positive integer"); } if (schema && !isSchema(schema)) return false; return true; } /** Partition Class */ export class Partition<T extends SchemaSpec<T> | null = null> { /** The partition's label */ readonly name: string; /** The partition's storage schema */ readonly schema: T extends SchemaSpec<infer U> ? Schema<U> : null; /** The maximum number of entities able to equip this component per instance. */ readonly maxOwners: number | null; /** The storage requirements of the schema in bytes for a single entity */ readonly size: number; /** `true` if the partition is a tag */ readonly isTag: T extends null ? true : false; /** * Create a new partition * @param spec the partition specification * @throws {SyntaxError} if the specification is invalid */ constructor(spec: PartitionSpec<T>) { if (!isValidPartitionSpec(spec)) { throw new SyntaxError("Invalid partition specification."); } const { name, schema = null, maxOwners = null } = spec; this.name = name; this.schema = schema as T extends SchemaSpec<infer U> ? Schema<U> : null; this.maxOwners = maxOwners ?? null; this.size = schema ? getSchemaSize(schema) : 0; this.isTag = (schema === null) as T extends null ? true : false; } }