{"id":13534377,"url":"https://github.com/moomoolive/struct-vec","last_synced_at":"2025-04-01T22:31:35.824Z","repository":{"id":42199695,"uuid":"477879409","full_name":"moomoolive/struct-vec","owner":"moomoolive","description":"🧰 Javascript array-like containers for multithreading","archived":false,"fork":false,"pushed_at":"2022-04-10T23:40:18.000Z","size":429,"stargazers_count":24,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-25T16:02:47.705Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moomoolive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-04T21:28:19.000Z","updated_at":"2024-03-26T06:02:32.000Z","dependencies_parsed_at":"2022-08-12T09:10:56.883Z","dependency_job_id":null,"html_url":"https://github.com/moomoolive/struct-vec","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moomoolive%2Fstruct-vec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moomoolive%2Fstruct-vec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moomoolive%2Fstruct-vec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moomoolive%2Fstruct-vec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moomoolive","download_url":"https://codeload.github.com/moomoolive/struct-vec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222779885,"owners_count":17036542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T07:01:31.712Z","updated_at":"2024-11-02T21:31:21.009Z","avatar_url":"https://github.com/moomoolive.png","language":"TypeScript","readme":"## بسم الله الرحمن الرحيم\n\n![CI Workflow](https://github.com/moomoolive/struct-vec/actions/workflows/node.js.yml/badge.svg)\n[![Dependencies](https://img.shields.io/badge/%F0%9F%93%A6-0%20dependencies-green.svg)](https://shields.io/)\n[![Bundle Size](https://img.shields.io/github/size/moomoolive/struct-vec/buildInfo/index.js.br)](https://shields.io/) \n\n# Struct Vec\n\n### 🧰 Javascript array-like containers for multithreading\n\nEfficiently communicating between js workers is a pain because you are forced either to pass data by [structured cloning](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) or represent your data as raw buffers. Structured cloning isn't ideal for performance because it requires de-serialization/serialization every time you pass a message, and raw buffers aren't ideal for productivity because they are esoteric and hard to work with.\n\nThis package attempts to solve this problem by allowing you to define data structures called `Vecs`. `Vecs` provide an API is similar to javascript `Arrays`, but are completely backed by `SharedArrayBuffers` - thus can be passed between workers at zero-cost, while still being intuitive to work with with.\n\nThis package was inspired by [Google's FlatBuffers](https://google.github.io/flatbuffers/), [Rust's std::Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html), and [@bnaya/objectbuffer](https://github.com/Bnaya/objectbuffer) package.\n\n## Table of Contents\n\n- [Examples](#examples)\n  - [Quick Start](#quick-start)\n  - [Initializing a Vec](#initializing-a-vec)\n  - [Indexing](#indexing)\n  - [Adding Elements](#adding-elements)\n  - [Iterating](#iterating)\n  - [Removing Elements](#removing-elements)\n  - [Swapping Elements](#swapping-elements)\n  - [Type Casting](#casting)\n  - [Multithreading](#multithreading)\n- [Requirements](#requirements)\n- [Struct Definitions](#struct-definitions)\n  - [Creating a Struct Definition](#creating-a-struct-definition)\n  - [Default Struct Fields](#default-struct-fields)\n  - [Supported Data Types](#data-types)\n    - [f32](#f32)\n    - [i32](#i32)\n    - [bool](#bool)\n    - [char](#char)\n  - [Disallowed Field Names](#disallowed-field-names)\n- [Compilers](#compilers)\n  - [Runtime Compiler](#runtime-compiler)\n  - [Build-time Compiler](#build-time-compiler)\n- [Caveats](#caveats)\n  - [Indexing does not Return Element](#indexing-does-not-return-element)\n  - [Indexing out of Bounds](#indexing-out-of-bounds)\n  - [Do Not Mutate Vec Length or Capacity during Multithreading](#do-not-mutate-vec-length-or-capacity-during-multithreading)\n- [Performance Tips](#performance-tips)\n  - [Adding Many Elements](#adding-many-elements)\n  - [Removing Many Elements](#removing-many-elements)\n  - [Avoid ES6 Iterators and Indexing](#avoid-es6-iterators-and-indexing)\n  - [Avoid Using the \"e\" Field Except for Setting an Element](#avoid-using-the-e-field-except-for-setting-an-element)\n- [Benchmarks](#benchmarks)\n  - [Benchmarks Summary](#benchmarks-summary)\n  - [Imperative Loop](#imperative-loop)\n  - [ForEach Loop](#foreach-loop)\n  - [ES6 Iterator Loop](#es6-iterator-loop)\n  - [Parallel Loop](#parallel-loop)\n  - [Pushing Elements](#pushing-elements)\n- [API Reference](#api-reference)\n  - [Vec](#module_vec-struct..Vec)\n  - [validateStructDef](#module_vec-struct..validateStructDef)\n  - [vec](#module_vec-struct..vec_gen)\n  - [vecCompile](#module_vec-struct..vec_gencompile)\n\n## Examples\n\n### Quick Start\n\n```bash\nnpm i struct-vec\n```\n\n```js\nimport {vec} from \"struct-vec\"\n\n// define the typing of elements in\n// vec. Returns a class\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\n// initialize a vec\nconst positions = new PositionV()\n\n// add some elements\nfor (let i = 0; i \u003c 200; i++) {\n  positions.push({x: 1, y: 2, z: 3})\n}\n\nconsole.log(positions.length) // output: 200\n\n// loop over vec\nfor (let i = 0; i \u003c positions.length; i++) {\n  // get element with \".index\" method\n  const element = positions.index(i)\n  console.log(element.x) // output: 1\n  console.log(element.y) // output: 2\n  console.log(element.z) // output: 3\n}\n\npositions.forEach(pos =\u003e {\n    // use the \".e\" method to get\n    // the object representation\n    // of your element\n    console.log(pos.e) // output: {x: 1, y: 1, z: 1}\n})\n\n// get a reference to an index\nconst firstElement = positions.index(0).ref\n\n// remove elements\nconst allElements = positions.length\nfor (let i = 0; i \u003c allElements; i++) {\n  positions.pop()\n}\n\nconsole.log(positions.length) // output: 0\n```\n\n### Initializing a Vec\n\n```js\nimport {vec} from \"struct-vec\"\n\n// define what an element should look like \n// definitions are called \"struct defs\" \nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\n// you can initialize your vecs without any arguments\nconst noArg = new PositionV()\n\n// Or you can specify how much capacity it initially has\n// (check the api reference for more info on capacity)\nconst withCapacity = new PositionV(15_000)\nconsole.log(withCapacity.capacity) // output: 15_000\n\n// Or you can construct a vec from another vec's memory\nconst fromMemory = PositionV.fromMemory(withCapacity.memory)\nconsole.log(fromMemory.capacity) // output: 15_000\n```\n\n### Indexing\n\nWhenever you wish to operate on an element in a vec (get the value or set it), reference a specific field of the element [NOT the entire element](#indexing-does-not-return-element).\n\n#### Getting Values at an Index\n\nIf you want the value of an element, refer to one of it's fields (`yourElement.x` for example), the `e` field to get the entire element [by value](#default_struct_field_e), or the `ref` field to get a [reference](#default_struct_field_ref) ([The `e` and `ref` fields are auto-generated](#default-struct-fields) for all struct defs).\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\npositions.push({x: 1, y: 2, z: 3})\n\n// 🛑 \"wrongValue\" doesn't equal {x: 1, y: 2, z: 3}\nconst wrongValue = positions.index(0)\n\n// ✅ refer to one the fields\nconst {x, y, z} = positions.index(0)\nconsole.log(x, y, z) // output: 1 2 3\n\n// ✅ get entire element by value\nconst correctValue = positions.index(0).e\nconsole.log(correctValue) // output: {x: 1, y: 2, z: 3}\n\n// ✅ get a reference to index\nconst first = positions.index(0).ref\nconsole.log(first.x, first.y, first.z) // output: 1 2 3\n\n// ✅ array destructuring is allowed as well\nconst [element] = positions\nconsole.log(element) // output: {x: 1, y: 2, z: 3}\n```\n\n#### Setting Values at an Index\n\nIf you want to set the value of an element, refer to one of it's fields (`yourElement.x = 2` for example) or reference the [`e` field](#default_struct_field_e) to set the entire element ([The `e` field is auto-generated](#default-struct-fields) for all struct defs). Both these methods work for [references](#default_struct_field_ref) as well.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst Cats = vec({\n     cuteness: \"i32\",\n     isDangerous: \"bool\", \n     emoji: \"char\"\n})\nconst cats = new Cats()\n\ncats.push({\n     cuteness: 10_000, \n     isDangerous: false, \n     emoji: \"😸\"\n})\n\n// 🛑 does not work - throws error\ncats.index(0) = {\n     cuteness: 2_876, \n     isDangerous: true, \n     emoji: \"🐆\"\n}\n\n// ✅ refer to one the fields\ncats.index(0).cuteness = 2_876\ncats.index(0).isDangerous = true\ncats.index(0).emoji = \"🐆\"\nconst {cuteness, emoji, isDangerous} = cats.index(0)\nconsole.log(cuteness, emoji, isDangerous) // output: 2876 true 🐆\n\n// ✅ set entire element at once\ncats.index(0).e = {\n     cuteness: 2_876, \n     isDangerous: true, \n     emoji: \"🐆\"\n}\nconsole.log(cats.index(0).e) // output: {cuteness: 2_876, isDangerous: true, emoji: \"🐆\"}\n\n// ✅ works for references as well\nconst first = cats.index(0).ref\n\nfirst.cuteness = 2_876\nfirst.isDangerous = true\nfirst.emoji = \"🐆\"\nconsole.log(first.cuteness, first.emoji, first.isDangerous) // output: 2876 true 🐆\n\nfirst.e = {\n     cuteness: 2_876, \n     isDangerous: true, \n     emoji: \"🐆\"\n}\nconsole.log(first.e) // output: {cuteness: 2_876, isDangerous: true, emoji: \"🐆\"}\n```\n\n### Adding Elements\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\nfor (let i = 0; i \u003c 100_000; i++) {\n  // add elements\n  positions.push({x: 1, y: 1, z: 1})\n}\n\nconsole.log(positions.index(0).e) // output: {x: 1, y: 1, z: 1}\nconsole.log(positions.index(2_500).e) // output: {x: 1, y: 1, z: 1}\nconsole.log(positions.length) // output: 100_000\n```\n\n### Iterating\n\n#### Imperatively\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\nconst positions = new PositionV(5_560).fill({x: 4, y: 3, z: 2})\n\nfor (let i = 0; i \u003c positions.length; i++) {\n  const element = positions.index(i)\n  element.x = 20\n  element.y = 5\n  element.z = element.x + element.y\n}\n\n```\n\n#### Iterators\n\nVecs support the majority of iterators that are found on javascript arrays. Check the [API Reference](#api-reference) for a full list of available iterators.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\nconst positions = new PositionV(5_560).fill({x: 4, y: 3, z: 2})\n\npositions.forEach((element, i, v) =\u003e {\n  element.x = 20\n  element.y = 5\n  element.z = element.x + element.y\n})\n\nconst bigPositions = positions.filter((element) =\u003e element.x \u003e 10)\n\n// note: vec es6 iterators are slow!!! but work nonetheless\nfor (const element of positions) {\n  element.x = 20\n  element.y = 5\n  element.z = element.x + element.y\n}\n```\n\n#### Nested Loops\n\nDue to some limitations, vecs usually [can only point to one element at a time](#indexing-does-not-return-element). To overcome a [`detachedCursor`](#indexing-does-not-return-element) or [`ref`](#default_struct_field_ref) can be used.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV(5).fill({x: 1, y: 1, z: 1})\n\n// create a cursor initially pointing at index 0\nconst innnerCursor = positions.detachedCursor(0)\nfor (let i = 0; i \u003c positions.length; i++) {\n     const outerEl = positions.index(i)\n     for (let x = 0; x \u003c vec.length; x++) {\n          const innerEl = extraCursor.index(x)\n          \n          if (innerEl.x === outerEl.x) {\n               console.log(\"same x\")\n          } else if (innerEl.y === outerEl.y) {\n               console.log(\"same y\")\n          } else if (innerEl.z === outerEl.z) {\n               console.log(\"same z\")\n          }\n     }\n}\n```\n\n### Removing Elements\n\n#### End of Vec\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\npositions.push({x: 1, y: 1, z: 1})\nconst removed = positions.pop()\nconsole.log(removed) // output: {x: 1, y: 1, z: 1}\nconsole.log(positions.length) // output: 0\n```\n\n#### Start of Vec\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\npositions.push({x: 1, y: 1, z: 1})\npositions.push({x: 2, y: 2, z: 2})\nconst removed = positions.shift()\nconsole.log(removed) // output: {x: 1, y: 1, z: 1}\nconsole.log(positions.length) // output: 1\n```\n\n#### Middle of Vec\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\npositions.push({x: 1, y: 1, z: 1})\npositions.push({x: 3, y: 3, z: 3})\npositions.push({x: 2, y: 2, z: 2})\nconst [removed] = positions.splice(1, 1)\nconsole.log(removed) // output: {x: 3, y: 3, z: 3}\nconsole.log(positions.length) // output: 2\n```\n\n### Swapping Elements\n\nDue to how [vecs work internally](#indexing-does-not-return-element), swapping can feel awkward. Luckily, there is a `swap` method that lets you forget about the details.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\npositions.push({x: 1, y: 1, z: 1})\npositions.push({x: 3, y: 3, z: 3})\n\n// 🛑 incorrect swap\nconst tmp = positions.index(0)\npositions.index(0) = positions.index(1) // throws Error\npositions.index(1) = tmp // throws Error\n\n// ✅ Correct swap\npositions.swap(0, 1)\n// ✅ This also works, but looks a little\n// awkward\nconst correctTmp = positions.index(0).e\npositions.index(0).e = positions.index(1).e\npositions.index(1).e = correctTmp\n```\n\n### Casting\n\n#### Array\n\n*Note: [Vecs use 32-bit floats](#f32), so there will be a loss of precision for decimal numbers when converting an array to a vec.\n\n```js\nimport {vec, Vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(15).fill({x: 1, y: 2, z: 3})\n\n// cast to array\nconst pArray = [...p]\nconsole.log(pArray.length) // output: 15\nconsole.log(pArray[0]) // output: {x: 1, y: 2, z: 3}\nconsole.log(Array.isArray(pArray)) // output: true\n\n// create from array\n// note: array elements and vec elements must be\n// of same type\nconst pFromArray = PositionsV.fromArray(pArray)\nconsole.log(pFromArray.length) // output: 15\nconsole.log(pFromArray.index(0).e) // output: {x: 1, y: 2, z: 3}\nconsole.log(Vec.isVec(pFromArray)) // output: true\nconsole.log(pFromArray !== p) // output: true\n```\n\n#### String\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20).fill({x: 1, y: 1, z: 1})\n\n// cast to string\nconst vecString = p.toJSON()\n// can be casted to string like so as well\nconst vecString1 = JSON.stringify(p)\nconsole.log(typeof vecString) // output: \"string\"\nconsole.log(vecString1 === vecString) // output: true\n// create vec from string\nconst jsonVec = PositionV.fromString(vecString)\n\nconsole.log(jsonVec.length) // output: 20\njsonVec.forEach(pos =\u003e {\n     console.log(pos.e) // output: {x: 1, y: 1, z: 1}\n})\n```\n\n### Multithreading\n\nVecs are backed by SharedArrayBuffers and can therefore be sent between workers at zero-cost ([check out the benchmarks](#parallel-loop)), irrespective of how many elements are in the vec.\n\nMultithreading with vecs is as easy as this:\n\n*index.mjs*\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst Position = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new Position(10_000).fill(\n    {x: 1, y: 1, z: 1}\n)\n\nconst worker = new Worker(\"worker.mjs\", {type: \"module\"})\n// pass by reference, no copying\nworker.postMessage(positions.memory)\n```\n\n*worker.mjs*\n\n```js\nimport {vec} from \"struct-vec\" \n\nconst Position = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\nself.onmessage = ({data}) =\u003e {\n   Position.fromMemory(data).forEach(p =\u003e {\n      p.x += 1\n      p.y += 2\n      p.z += 3\n   })\n   self.postMessage(\"finished\")\n}\n```\n\nSAFETY-NOTES: \n- do not attempt to use [length-changing methods while multithreading](#do-not-mutate-vec-length-or-capacity-during-multithreading)\n- because vecs are shared across multiple contexts, you can run into real threading issues like data races. Vecs do not come with any type of protections against threading-related bugs, so you'll have to devise your own (mutexes, scheduling, etc.).\n\n## Requirements\n\nThis package requires javascript environments that support ES6 and `SharedArrayBuffers` (eg. Node, Deno, [supported browsers](https://caniuse.com/sharedarraybuffer), etc.).\n\nIn order to allow enable `SharedArrayBuffers` in supported browsers you probably need to fulfill these [security requirements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements).\n\nAlso be aware that the runtime compiler (the [`vec`](#runtime-compiler) function) uses the unsafe [Function constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) behind the scenes to generate vec classes at runtime. This will render `vec` useless in javascript environments that disallow the use of unsafe constructors such as `Function`, `eval`, etc. If it is the case that your environment disallows unsafe constructors, then consider using the build-time compiler (the [`vecCompile`](#buildtime-compiler) function) instead.\n\n### Typescript\n\nTypescript bindings requires version 3.3.3+.\n\n## Struct Definitions\n\nAll elements in a vec are structs, which can be thought of as strictly-typed objects, that only carry data (no methods). Once a vec is given a struct definition (struct def), structs within the vec can only be exactly the type specified in the definition. This is why it is highly recommended to use this package with Typescript, as setting struct fields with incorrect types can lead to odd behaviors.\n\n### Creating a Struct Definition\n\nCreating a struct def is similar to defining a struct def in statically-typed languages (C, Rust, Go, etc.) or an [interface in Typescript](https://www.typescriptlang.org/docs/handbook/2/objects.html). Define a struct def by creating an object and mapping fields ([with a valid name](#disallowed-field-names)) to [supported data types](#data-types). Nesting of struct defs is NOT allowed.\n\n```js\n// should have floats at \"x\", \"y\", and \"z\" fields\nconst positionDef = {x: \"f32\", y: \"f32\", z: \"f32\"}\n\n// should have character type at \"emoji\" field, and\n// integer type at \"cuteness\" field\nconst catDef = {emoji: \"char\", cuteness: \"i32\"}\n\n// should have boolean type at \"isScary\" and\n// integer type at \"power\" field\nconst monsterDef = {isScary: \"bool\", power: \"i32\"}\n```\n\n### Default Struct Fields\n\nEvery struct, regardless of definition has some auto-generated fields. Auto-generated fields are:\n\n\u003ca name=\"default_struct_field_e\"\u003e\u003c/a\u003e\n\n`e` : allows you to get and set an entire element.\n- calling `.e` on an element returns the element by value not by reference. [See `ref`](#default_struct_field_e) to get element by reference.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst Cats = vec({\n     cuteness: \"i32\",\n     isDangerous: \"bool\", \n     emoji: \"char\"\n})\nconst cats = new Cats()\n\ncats.push({\n     cuteness: 10_000, \n     isDangerous: false, \n     emoji: \"😸\"\n})\n// get entire element\nconsole.log(cats.index(0).e) // output: {cuteness: 10_000, isDangerous: false, emoji: \"😸\"}\n\n// set entire element\ncats.index(0).e = {\n     cuteness: 2_876, \n     isDangerous: true, \n     emoji: \"🐈‍⬛\"\n}\nconsole.log(cats.index(0).e) // output: {cuteness: 2_876, isDangerous: true, emoji: \"🐈‍⬛\"}\n```\n\n\u003ca name=\"default_struct_field_ref\"\u003e\u003c/a\u003e\n\n`ref`: returns a reference to an index in a vec.\n- these references refer to an index in a vec NOT the element at the index. Meaning that if the underlying element is moved, the reference will no longer point to it and potentially [dangle](https://practice.geeksforgeeks.org/problems/what-is-dangling-reference).\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst Enemy = vec({power: \"i32\", isDead: \"bool\"})\nconst orcs = new Enemy()\norcs.push(\n     {power: 55, isDead: false},\n     {power: 13, isDead: false},\n     {power: 72, isDead: false},\n)\n// get a reference to index 0\nconst firstElement = orcs.index(0).ref\nconsole.log(orcs.index(2).e) // output: {power: 72, isDead: false},\nconsole.log(firstElement.e) // output: {power: 55, isDead: false}\n\n// if underlying element of a ref moves \n// it does not move with it\norcs.swap(0, 1)\nconsole.log(firstElement.e) // output: {power: 13, isDead: false}\n\n// ✅ references can create other references\nconst firstElementRef = firstElement.ref\n```\n\n### Data types\n#### f32\n\n[Single-precision floating point number](https://en.wikipedia.org/wiki/Single-precision_floating-point_format), takes 4 bytes (32 bits) of memory. Similar to javascript's `Number` type, but with less precision. Also similar to to C's [`float` type](https://www.learnc.net/c-tutorial/c-float/).\n\nTo define a `f32` field:\n```js\nimport {vec} from \"struct-vec\"\n\n// \"num\" should be a float type\nconst NumVec = vec({num: \"f32\"})\nconst v = new NumVec()\n\nv.push({num: 1.1})\nconsole.log(v.index(0).num) // output: 1.100000023841858\nv.index(0).num = 2.1\n// notice the loss of precision\nconsole.log(v.index(0).num) // output: 2.0999999046325684\n```\n\n[![access-speed-num](https://img.shields.io/badge/%F0%9F%9A%80%20Access%20Speed-Great-brightgreen)](https://shields.io/)\n\nThis data type very fast in terms of access speed as it maps exactly to a native javascript type.  \n\n[![type-safety-num](https://img.shields.io/badge/%F0%9F%AA%B2%20Type%20Saftey-info-blue)](https://shields.io/) \n\nIf one sets a `f32` field with an incorrect type (`String` type for example), the field will be set to `NaN`. There a couple of exceptions to this rule, such as if the incorrect type is `null`, an `Array`, a `BigInt`, a `Symbol`, or a `Boolean` which will either throw a runtime error, set the field to 0 or 1, depending on the type and javascript engine.\n\n#### i32\n\nA [32-bit signed integer](https://www.ibm.com/docs/en/aix/7.2?topic=types-signed-unsigned-integers), takes 4 bytes (32 bits) of memory. Similar to javascript's `Number` type, but without the ability to carry decimals. Also similar to C's [`int` type](https://www.learnc.net/c-tutorial/c-integer/).\n\nTo define a `i32` field:\n```js\nimport {vec} from \"struct-vec\"\n\n// \"num\" should be a integer type\nconst NumVec = vec({num: \"i32\"})\nconst v = new NumVec()\n\nv.push({num: 1})\nconsole.log(v.index(0).num) // output: 1\nv.index(0).num = 2\nconsole.log(v.index(0).num) // output: 2\nv.index(0).num = 2.2\n// notice that i32s cannot hold decimals\nconsole.log(v.index(0).num) // output: 2\n```\n\n[![access-speed-num](https://img.shields.io/badge/%F0%9F%9A%80%20Access%20Speed-Great-brightgreen)](https://shields.io/)\n\n[same as f32](#f32) \n\n[![type-safety-num](https://img.shields.io/badge/%F0%9F%AA%B2%20Type%20Saftey-info-blue)](https://shields.io/) \n\n[same as f32](#f32) \n\n\n#### bool\n\nA boolean value that can be either true or false, takes 1/8 of a byte of memory (1 bit). Same as javascript's `Boolean` type.\n\nTo define a `bool` field:\n```js\nimport {vec} from \"struct-vec\"\n\n// \"bool\" should be boolean type\nconst BoolVec = vec({bool: \"bool\"})\nconst v = new BoolVec()\n\nv.push({bool: true})\nconsole.log(v.index(0).bool) // output: true\nv.index(0).bool = false\nconsole.log(v.index(0).bool) // output: false\n```\n\n[![access-speed-bool](https://img.shields.io/badge/%F0%9F%9A%80%20Access%20Speed-Good-green)](https://shields.io/)\n\nThis data type requires a small conversion when getting and setting it's value.\n\n[![type-safety-bool](https://img.shields.io/badge/%F0%9F%AA%B2%20Type%20Saftey-info-blue)](https://shields.io/)\n\nWhen a `bool` field is set with an incorrect type (`Number` type for example), the field will be set to `true` except if the type is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy), in which case the field will be set to `false`. \n\n#### char\n\nOne valid [unicode 14.0.0](http://www.unicode.org/versions/Unicode14.0.0/) character, takes 4 bytes (32 bits). Same as javascript's `String` type, except that it is restricted to exactly one character.\n\nTo define a `char` field:\n```js\nimport {vec} from \"struct-vec\"\n\n// \"char\" should be character type\nconst CharVec = vec({char: \"char\"})\nconst v = new CharVec()\nv.push({char: \"😀\"})\nconsole.log(v.index(0).char) // output: \"😀\"\nv.index(0).char = \"a\"\nconsole.log(v.index(0).char) // output: \"a\"\n```\n\n[![access-speed-char](https://img.shields.io/badge/%F0%9F%9A%80%20Access%20Speed-Bad-yellow)](https://shields.io/)\n\nThis data type requires a medium level conversion in order to access. Can be up to 100% slower (2x slower) than the [`f32`](#f32) type.\n\n[![type-safety-char](https://img.shields.io/badge/%F0%9F%AA%B2%20Type%20Saftey-info-blue)](https://shields.io/)\n\nWhen a `char` field is set with an incorrect type an error will be thrown. If the inputted type is a string longer than one character, the field will be set to the first character of input. If the inputted type is an empty string, the field will be set to `\" \"` (space character).\n\n### Disallowed Field Names\n\nStruct field names follow the same naming convention as [javascript variables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#variables), excluding unicode characters.\n\nFields also cannot be named `e`, `_viewingIndex`, `ref`,`index`, `self`.\n\n```js\nimport {vec} from \"struct-vec\"\n\n// 🛑 Not allowed\nconst v0 = vec({_viewingIndex: \"char\"})\nconst v1 = vec({self: \"f32\"})\nconst v5 = vec({e: \"f32\"})\nconst v2 = vec({[\"my-field\"]: \"bool\"})\nconst v3 = vec({[\"👍\"]: \"char\"})\nconst v4 = vec({0: \"f32\"})\n\n// ✅ allowed\nconst v11 = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst v6 = vec({$field: \"bool\"})\nconst v7 = vec({_field: \"char\"})\nconst v8 = vec({e0: \"f32\"})\nconst v9 = vec({myCoolField: \"f32\"})\nconst v10 = vec({my$_crazy0_fieldName123: \"bool\"})\n```\n\n## Compilers\n\nThis package provides two ways to define vecs, either through the exported `vec` (runtime compiler) or `vecCompile` (build-time compiler) functions. Both compilers emit the exact same vec classes.\n\nThe key differences between the compilers is that the build-time compiler returns a string containing your vec class which you can write to disk to use in another application, instead of creating a vec class which can be used right away.\n\n### Runtime Compiler\n\nGenerally, the runtime compiler is easier to work with and that's why all the documentation examples use it. Essentially, the runtime compiler takes your [struct def](#struct-definitions) and returns a vec class that can immediately be used.\n\nIn case your were wondering, the runtime compiler is quite fast. Defining a vec like so:\n\n```js\nconst v = vec({x: \"f32\", y: \"f32\", z: \"f32\", w: \"f32\"})\n```\n\ntakes about `0.013` milliseconds in Node. Unless you are planning on defining tens of thousands of vecs, the runtime compiler won't really slow down your application.\n\nThe runtime compiler does however make use of the unsafe [`Function constructor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) internally. If you know that your javascript environment doesn't allow the use of unsafe constructors (like `Function`, `eval`, etc.), then use the build-time compiler.\n\nAlso, if you want a build tool like Webpack, ESBuild, Vite, etc. to apply transforms on your vec classes (such as convert them to ES5 syntax), the build-time compiler might be the right choice for you.\n\n### Build-time Compiler\n\nThe build-time compiler is almost exactly the same as the runtime one. The difference being, after the compiler takes your [struct def](#struct-definitions), it returns a string version of your vec class, instead of a vec class that can be immediately used.\n\nHere's an example:\n\n*build.mjs*\n```js\nimport fs from \"fs\"\nimport {vecCompile} from \"struct-vec\"\n\n// the path to the \"struct-vec\" library.\n// For the web or Deno, you would\n// put the full url to the library.\n// for example: https://deno.land/....\n// or https://unpkg.com/...\nconst LIB_PATH = \"struct-vec\"\n\n// create a struct def, just like with the\n// runtime compiler\nconst def = {x: \"bool\", y: \"f32\", z: \"char\"}\n\nconst MyClass = vecCompile(def, LIB_PATH, {\n     // generate a javascript class, not typescript\n     lang: \"js\",\n     // create class with \"export\" statement\n     exportSyntax: \"named\",\n     className: \"MyClass\"\n})\nconsole.log(typeof MyClass) // output: string\n// write the class to disk to use later\n// or in another application\nfs.writeFileSync(\"MyClass.mjs\", MyClass, {encoding: \"utf-8\"})\n```\n\nnow take a look at the file the class was written to:\n\n*MyClass.mjs*\n```js\n// imported dependencies from LIB_PATH\nimport {Vec} from \"struct-vec\"\n/**\n * @extends {Vec\u003c{\"x\":\"bool\",\"y\":\"f32\",\"z\":\"char\"}\u003e}\n */\n// class was named correctly\n// and it was created as a \"named\" export\nexport class MyClass extends Vec {\n     // some auto generated stuff\n     // that looks like it was written by an ape\n    static Cursor = class Cursor {\n        _viewingIndex = 0\n        constructor(self) { this.self = self }\n        get y() { return this.self._memory[this._viewingIndex] }; set y(newValue) { this.self._memory[this._viewingIndex] = newValue };\n        get z() { return String.fromCodePoint(this.self._memory[this._viewingIndex + 1] || 32) }; set z(newValue) { this.self._memory[this._viewingIndex + 1] = newValue.codePointAt(0) || 32 };\n        get x() { return Boolean(this.self._memory[this._viewingIndex + 2] \u0026 1) }; set x(newValue) { this.self._memory[this._viewingIndex + 2] \u0026= -2;this.self._memory[this._viewingIndex + 2] |= Boolean(newValue)};\n        set e({y, z, x}) { this.y = y;this.z = z;this.x = x; }\n        get e() { return {y: this.y, z: this.z, x: this.x} }        \n    }\n    get elementSize() { return 3 }\n    // here's the inputted struct def\n    get def() { return {\"x\":\"bool\",\"y\":\"f32\",\"z\":\"char\"} }\n    get cursorDef() { return MyClass.Cursor }\n}\n```\nYou can now import `MyClass` into a javascript or typescript file and it will work just like any other vec. Other build options are found in the [API Reference](#api-reference).\n\nUnfortunately the build-time compiler does not come with a command-line tool - so you'll need to figure out how you want to generate and store your vec classes.\n\n## Caveats\n\n### Indexing does NOT Return Element\n\nIndexing into a vec (calling `index`) is similar to calling [`next` on an iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#iterators). Calling `myVec.index(0)` will take you to the first element, allowing you to access it's fields, but does not return the element. \n\nTo get an element by value use the [`e` field](#default_struct_field_e). To get an entire element by reference use the [`ref` field](#default_struct_field_ref).\n\nThe implication of all this, is that a vec can only point to one element at a time. If you want to look at two or more elements at once, you will have to create additional cursors, which can created with the `Vec.detachedCursor` method.\n\nAn example to illustrate this point is a nested for loop:\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\npositions.push({x: 1, y: 1, z: 1})\npositions.push({x: 3, y: 3, z: 3})\npositions.push({x: 2, y: 2, z: 2})\n\n// 🛑 incorrect example\nfor (let i = 0; i \u003c positions.length; i++) {\n     // move vec to index 0\n     const el = positions.index(i)\n     // move vec from index 0 through 2\n     for (let x = 0; x \u003c vec.length; x++) {\n          const innerEl = positions.index(x)\n     }\n     // ❌ vec was moved to index 2 (vec.length) at the \n     // end of the inner loop and is no longer \n     // pointing to index i\n     console.log(el.e) // output: {x: 2, y: 2, z: 2}\n}\n\n// ✅ Use a detached cursor\n// create a cursor initially pointing\n// at index 0\nconst extraCursor = positions.detachedCursor(0)\nfor (let i = 0; i \u003c positions.length; i++) {\n     const el = positions.index(i)\n     // move extra cursor from index 0 through 2\n     for (let x = 0; x \u003c vec.length; x++) {\n          // detached cursors can be move via the \"index\"\n          // method, just like vecs but don't\n          // influence were the vec is pointing\n          const innerEl = extraCursor.index(x)\n     }\n     console.log(el.e) // output: what ever is at index i\n}\n\n// ✅ Use a reference, also works\n// but less efficent\nfor (let i = 0; i \u003c positions.length; i++) {\n     // refs are just a special\n     // type of \"detachedCursor\" under the hood\n     const el = positions.index(i).ref\n     // move vec from index 0 through 2\n     for (let x = 0; x \u003c vec.length; x++) {\n          const innerEl = positions.index(x)\n     }\n     console.log(el.e) // output: what ever is at index i\n}\n```\n\n### Indexing Out of Bounds\n\nIndexing out of bounds negatively (`i \u003c 0`) will return `undefined` just like an `Array`. Indexing out of bounds past the length (`i \u003e vec.length - 1`) may or may not return `undefined`. Sometimes a vec will keep garbage memory at the end to avoid resizing and this is the expected behavior.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV(5)\n\npositions.push({x: 1, y: 1, z: 1})\npositions.push({x: 2, y: 2, z: 2})\npositions.pop()\n// current length\nconsole.log(positions.length) // output: 1\n\n// ✅ indexing out of bounds negatively (i \u003c 0) \n// always returns undefined\nconsole.log(positions.index(-1).x) // output: undefined\n\n// ⚠️ indexing out of bounds positively (i \u003e vec.length - 1)\n// may or may not return undefined\nconsole.log(positions.index(1).x) // output: 2\nconsole.log(positions.index(2).x) // output: 0\nconsole.log(positions.index(10_000).x) // output: undefined\n```\n\n### Do Not Mutate Vec Length or Capacity during Multithreading\n\nDo not use any methods that may potentially change the `length` (or `capacity`) of a vec during multi-threading. Doing so will lead to unpredictable bugs.\n\nLength-changing methods include: `pop`, `truncate`, `splice`, `shift`, `push`, `fill`, `unshift`\n\nCapacity-changing methods include: `shrinkTo`, `reserve`\n\n## Performance Tips\n\n### Adding Many Elements\n\nGenerally speaking vecs manage their own memory, so you never have to think about resizing or shrinking a vec. However, vecs also provide the ability to expand their memory (or shrink it) on-demand, which is useful when you know ahead of time that you will be adding many elements at once.\n\nBefore pushing many elements at once you can use the `reserve` method to resize the vec's memory as to avoid resizing multiple times and [increase performance](#pushing-elements).\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\n// make sure there is enough memory for an additional\n// 10,00 elements\npositions.reserve(10_000)\n\nfor (let i = 0; i \u003c 10_000; i++) {\n  positions.push({x: 1, z: 1, y: 1})\n}\n```\n\n### Removing Many Elements\n\nSimilar to when adding many elements, vecs provide a couple of mass removal methods that are more performant.\n\nIf you want to remove the last n elements use the `truncate` method\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV(10_000).fill({x: 1, y: 1, z: 1})\n\nconsole.log(positions.length) // output: 10_000\n\n// remove last 5_000 elements at once\npositions.truncate(5_000)\n\nconsole.log(positions.length) // output: 5_000\n```\n\n### Avoid ES6 Iterators and Indexing\n\nES6 array destructuring operator (`const [element] = vec`), spread operator (`...vec`), and for...of loops (`for (const el of vec)`) should be avoided except if you want to [cast a vec to an array](#casting) or something similar. \n\nThese operators force vecs to deserialize their internal binary representation of structs to objects - [which is costly](#es6-iterator-loop) and can cause some unexpected side-effects due to fact that they return elements by [value](#default_struct_field_e), NOT by reference.\n\nNOTE: the `values`, `entries`, `keys` methods are also es6 iterators.\n\n### Avoid Using the e Field Except for Setting an Element\n\nUsing the `e` field to view the value of an element is costly as it forces the vec to deserialize it's internal binary representation into object format ([similar to es6 methods](#avoid-es6-iterators-and-indexing)). Getting the value of individual fields is far more performant than using the `e` field. Fortunately, this bottleneck doesn't seem to exist when setting with `e`.\n\n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV()\n\npositions.push({x: 1, z: 1, y: 1})\n\n// ✅ performant\nconst {x, y, z} = positions.index(0)\n// ✅ also performant\nconst xVal = positions.index(0).x\nconst yVal = positions.index(0).y\nconst zVal = positions.index(0).z\n\n// ⚠️ less performant\nconst val = positions.index(0).e\n\n// ✅ setting with \"e\" field is also performant \n// unlike viewing\npositions.index(0).e = {x: 2, y: 5, z: 7}\n```\n\n## Benchmarks\n\nAll test were done over 100 samples, with 4 warmup runs\nbefore recording. [The multithreaded benchmarks](#parallel-loop) are the only exception to this.\n\nTest machine was a Windows 11/WSL-Ubuntu 20.04 (x64), with a Intel i7-9750H CPU (12 core), and 16 GB RAM.\n\n### Iteration\n#### Imperative loop\n\nIterate over 10 million elements in an imperative manner, adding 10 to one of the element fields.\n\nThe raw buffer fields here are `Float32Array`s.\n\nTaken on ```March 31, 2022```\n\n`Node 16.13.1 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer | 15.28 ms ±0.96 |\n| Array | 49.82 ms ±2.35 |\n| Vec | 21.69 ms ±0.74 |\n\n`Deno 1.20.2 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer | 14.79 ms ±0.89 |\n| Array | 32.01 ms ±1.15 |\n| Vec | 20.63 ms ±0.76 |\n\n`Chrome 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer | 18.80 ms ±2.42 |\n| Array | 38.19 ms ±2.64 |\n| Vec | 21.54 ms ±1.66 |\n\n`Firefox 98 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer | 23.97 ms ±0.93 |\n| Array | 64.30 ms ±3.13 |\n| Vec | 54.68 ms ±1.54 |\n\n`Edge 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer | 17.19 ms ±1.87 |\n| Array | 37.82 ms ±2.10 |\n| Vec | 21.36 ms ±1.28 |\n\n#### ForEach loop\n\nIterate over 10 million elements with `ForEach` iterator, adding 10 to one of the element fields.\n\nTaken on ```March 24, 2022```\n\n`Node 16.13.1 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Array | 116.84 ms ±3.53 |\n| Vec | 47.84 ms ±0.77 |\n\n`Deno 1.20.2 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Array | 103.82 ms ±2.98 |\n| Vec | 45.57 ms ±1.14 |\n\n`Chrome 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Array | 126.19 ms ±5.72 |\n| Vec | 48.67 ms ±4.08 |\n\n`Firefox 98 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Array | 102.04 ms ±4.00 |\n| Vec | 149.01 ms ±10.09 |\n\n`Edge 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Array | 124.70 ms ±4.44 |\n| Vec | 48.71 ms ±2.59 |\n\n#### ES6 Iterator loop\n\nIterate over 10 million elements with ES6's for...of loop and add 10 to one of the element fields.\n\nTaken on ```March 24, 2022```\n\n`Node 16.13.1 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer (imperative) | 30.59 ms ±1.56 |\n| Array | 53.12 ms ±1.96 |\n| Vec | 196.70 ms ±6.47 |\n\n`Deno 1.20.2 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer (imperative) | 30.45 ms ±1.54 |\n| Array | 34.95 ms ±1.19 |\n| Vec | 194.63 ms ±4.82 |\n\n`Chrome 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer (imperative) | 32.13 ms ±2.15 |\n| Array | 34.97 ms ±1.57 |\n| Vec | 200.56 ms ±7.61 |\n\n`Firefox 98 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer (imperative) | 29.21 ms ±3.35 |\n| Array | 106.89 ms ±4.14 |\n| Vec | 346.72 ms ±13.57 |\n\n`Edge 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Raw Buffer (imperative) | 31.20 ms ±1.66 |\n| Array | 34.46 ms ±0.83 |\n| Vec | 200.35 ms ±6.35 |\n\n#### Parallel Loop\n\nIterate over 8 million elements in a parallel (4 cores) and perform a significant computation. Average of 10 runs, with 4 warmups runs before recording.\n\nTaken on ```March 31, 2022```\n\n`Node 16.13.1 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Single-thread Array | 6,415.10 ms ±469.00 |\n| Multithreaded Array |  18,833.40 ms ±246.66 |\n| Single-thread Vec | 4,856.90 ms ±120.40 |\n| Multithreaded Vec | 1,411.40 ms ±98.34 |\n\n`Deno 1.20.2 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Single-thread Array | 6,541.40 ms ±167.11 |\n| Multithreaded Array | 18,204.20 ms ±172.01 |\n| Single-thread Vec | 5,487.70 ms ±43.90 |\n| Multithreaded Vec | 1,411.40 ms ±98.34 |\n\n`Chrome 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Single-thread Array | 5,746.00 ms ±76.65 |\n| Multithreaded Array | 17,989.40 ms ±751.12 |\n| Single-thread Vec | 5,350.60 ms ±162.57 |\n| Multithreaded Vec | 1,580.80 ms ±39.07 |\n\n`Firefox 98 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Single-thread Array | 6387.00 ms ±26.23 |\n| Multithreaded Array | Crashed with no error code |\n| Single-thread Vec | 6293.40 ms ±179.05 |\n| Multithreaded Vec | 1847.10 ms ±74.04 |\n\n`Edge 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Single-thread Array | 6,388.00 ms ±233.65 |\n| Multithreaded Array | Crashed with code STATUS_BREAKPOINT |\n| Single-thread Vec | 5,338.30 ms ±127.40 |\n| Multithreaded Vec | 1,569.20 ms ±73.29 |\n\n#### Pushing Elements\n\nPushing 10 million elements in a row.\n\n\"with reserve\" label means that vec/array preallocated enough space for all 10 million elements before attempting to push elements.\n\nPreallocation with arrays looks like this:\n```js\nconst arr = new Array(10_000_000)\n// start pushing elements\n```\n\nFor vecs:\n```js\nconst vec = new PositionV()\nvec.reserve(10_000_000)\n// start pushing elements \n```\n\nTaken on ```March 31, 2022```\n\n`Node 16.13.1 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Vec | 138.99 ms ±15.51 | \n| Array | 690.30 ms ±227.53 |\n| Vec with reserve | 76.92 ms ±4.69 |\n| Array with reserve | 2305.48 ms ±85.52 |\n\n`Deno 1.20.2 (Ubuntu 20.04)`\n| Candidate | Result |\n| ---- | ------ |\n| Vec |  143.74 ms ±12.57 |\n| Array | 1459.62 ms ±170.93 |\n| Vec with reserve | 101.21 ms ±5.23 |\n| Array with reserve | 1602.00 ms ±27.78 |\n\n`Chrome 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Vec |  228.77 ms ±14.33 |\n| Array | 1373.45 ms ±262.41 |\n| Vec with reserve | 129.86 ms ±62.47 |\n| Array with reserve | 1459.22 ms ±35.14 |\n\n`Firefox 98 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Vec |  630.28 ms ±9.57 |\n| Array | 612.50 ms ±10.76 |\n| Vec with reserve | 446.65 ms ±22.07 |\n| Array with reserve | 2348.31 ms ±198.37 |\n\n`Edge 99 (Windows 11)`\n| Candidate | Result |\n| ---- | ------ |\n| Vec |  243.50 ms ±11.83 |\n| Array | 1370.32 ms ±259.06 |\n| Vec with reserve | 132.42 ms ±10.41 |\n| Array with reserve | 1457.89 ms ±58.15 |\n\n## API Reference\n\u003ca name=\"module_vec-struct\"\u003e\u003c/a\u003e\n\n* [vec-struct](#module_vec-struct)\n    * [~Vec](#module_vec-struct..Vec)\n        * [new Vec([initialCapacity])](#new_module_vec-struct..Vec_new)\n        * _instance_\n            * [.elementSize](#module_vec-struct..Vec+elementSize) : \u003ccode\u003enumber\u003c/code\u003e\n            * [.def](#module_vec-struct..Vec+def) : \u003ccode\u003eStructDef\u003c/code\u003e\n            * [.length](#module_vec-struct..Vec+length) : \u003ccode\u003enumber\u003c/code\u003e\n            * [.capacity](#module_vec-struct..Vec+capacity) : \u003ccode\u003enumber\u003c/code\u003e\n            * [.memory](#module_vec-struct..Vec+memory) : \u003ccode\u003eReadonlyInt32Array\u003c/code\u003e\n            * [.index(index)](#module_vec-struct..Vec+index) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.at(index)](#module_vec-struct..Vec+at) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.forEach(callback)](#module_vec-struct..Vec+forEach) ⇒ \u003ccode\u003evoid\u003c/code\u003e\n            * [.map(callback)](#module_vec-struct..Vec+map) ⇒ \u003ccode\u003eArray.\u0026lt;YourCallbackReturnType\u0026gt;\u003c/code\u003e\n            * [.mapv(callback)](#module_vec-struct..Vec+mapv) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.filter(callback)](#module_vec-struct..Vec+filter) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.find(callback)](#module_vec-struct..Vec+find) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e\n            * [.findIndex(callback)](#module_vec-struct..Vec+findIndex) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n            * [.lastIndexOf(callback)](#module_vec-struct..Vec+lastIndexOf) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n            * [.reduce(callback, initialValue)](#module_vec-struct..Vec+reduce) ⇒ \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e\n            * [.reduceRight(callback, initialValue)](#module_vec-struct..Vec+reduceRight) ⇒ \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e\n            * [.every(callback)](#module_vec-struct..Vec+every) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n            * [.some(callback)](#module_vec-struct..Vec+some) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n            * [.entries()](#module_vec-struct..Vec+entries) ⇒ \u003ccode\u003eIterator.\u0026lt;Array.\u0026lt;number, Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\n            * [.keys()](#module_vec-struct..Vec+keys) ⇒ \u003ccode\u003eIterator.\u0026lt;number\u0026gt;\u003c/code\u003e\n            * [.values()](#module_vec-struct..Vec+values) ⇒ \u003ccode\u003eIterator.\u0026lt;Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u003c/code\u003e\n            * [.slice([start], [end])](#module_vec-struct..Vec+slice) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.copyWithin(target, [start], [end])](#module_vec-struct..Vec+copyWithin) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.reserve(additional)](#module_vec-struct..Vec+reserve) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.reverse()](#module_vec-struct..Vec+reverse) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.concat(...vecs)](#module_vec-struct..Vec+concat) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.pop()](#module_vec-struct..Vec+pop) ⇒ \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e\n            * [.truncate(count)](#module_vec-struct..Vec+truncate) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n            * [.fill(value, [start], [end])](#module_vec-struct..Vec+fill) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.push(...structs)](#module_vec-struct..Vec+push) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n            * [.splice(start, [deleteCount], ...items)](#module_vec-struct..Vec+splice) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.shift()](#module_vec-struct..Vec+shift) ⇒ \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.unshift(...structs)](#module_vec-struct..Vec+unshift) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n            * [.shrinkTo([minCapacity])](#module_vec-struct..Vec+shrinkTo) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.sort(compareFn)](#module_vec-struct..Vec+sort) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.swap(aIndex, bIndex)](#module_vec-struct..Vec+swap) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.toJSON()](#module_vec-struct..Vec+toJSON) ⇒ \u003ccode\u003estring\u003c/code\u003e\n            * [.detachedCursor(index)](#module_vec-struct..Vec+detachedCursor) ⇒ \u003ccode\u003eDetachedVecCursor\u003c/code\u003e\n        * _static_\n            * [.def](#module_vec-struct..Vec.def) : \u003ccode\u003eReadonly.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.elementSize](#module_vec-struct..Vec.elementSize) : \u003ccode\u003eReadonly.\u0026lt;number\u0026gt;\u003c/code\u003e\n            * [.isVec(candidate)](#module_vec-struct..Vec.isVec) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n            * [.fromMemory(memory)](#module_vec-struct..Vec.fromMemory) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.fromArray(structArray)](#module_vec-struct..Vec.fromArray) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n            * [.fromString(vecString)](#module_vec-struct..Vec.fromString) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n    * [~validateStructDef(def)](#module_vec-struct..validateStructDef) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n    * [~vec(structDef, [options])](#module_vec-struct..vec_gen) ⇒ \u003ccode\u003eVecClass.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n    * [~vecCompile(structDef, pathToLib, [options])](#module_vec-struct..vec_genCompile) ⇒ \u003ccode\u003estring\u003c/code\u003e\n\n\u003ca name=\"module_vec-struct..Vec\"\u003e\u003c/a\u003e\n\n### vec-struct~Vec\nThe base class that all generated vec\nclasses inherit from.\n\nThis class isn't intended to be manually\ninherited from, as the ```vec``` and `vecCompile` functions\nwill automatically inherit this class and\ngenerate the necessary override methods\nbased on your struct definition. The class\nis still made available however as it has\nsome useful static methods, such as:\n\n```isVec``` : can be used\nto check if a particular type\nis a vec at runtime, similar to the ```Array.isArray```\nmethod.\n\nThe class is generic over ```T``` which extends\nthe ```StructDef``` type. In other words, the Vec class\nis type ```Vec\u003cT extends StructDef\u003e```\n\n**Kind**: inner class of [\u003ccode\u003evec-struct\u003c/code\u003e](#module_vec-struct)  \n\n* [~Vec](#module_vec-struct..Vec)\n    * [new Vec([initialCapacity])](#new_module_vec-struct..Vec_new)\n    * _instance_\n        * [.elementSize](#module_vec-struct..Vec+elementSize) : \u003ccode\u003enumber\u003c/code\u003e\n        * [.def](#module_vec-struct..Vec+def) : \u003ccode\u003eStructDef\u003c/code\u003e\n        * [.length](#module_vec-struct..Vec+length) : \u003ccode\u003enumber\u003c/code\u003e\n        * [.capacity](#module_vec-struct..Vec+capacity) : \u003ccode\u003enumber\u003c/code\u003e\n        * [.memory](#module_vec-struct..Vec+memory) : \u003ccode\u003eReadonlyInt32Array\u003c/code\u003e\n        * [.index(index)](#module_vec-struct..Vec+index) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.at(index)](#module_vec-struct..Vec+at) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.forEach(callback)](#module_vec-struct..Vec+forEach) ⇒ \u003ccode\u003evoid\u003c/code\u003e\n        * [.map(callback)](#module_vec-struct..Vec+map) ⇒ \u003ccode\u003eArray.\u0026lt;YourCallbackReturnType\u0026gt;\u003c/code\u003e\n        * [.mapv(callback)](#module_vec-struct..Vec+mapv) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.filter(callback)](#module_vec-struct..Vec+filter) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.find(callback)](#module_vec-struct..Vec+find) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e\n        * [.findIndex(callback)](#module_vec-struct..Vec+findIndex) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n        * [.lastIndexOf(callback)](#module_vec-struct..Vec+lastIndexOf) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n        * [.reduce(callback, initialValue)](#module_vec-struct..Vec+reduce) ⇒ \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e\n        * [.reduceRight(callback, initialValue)](#module_vec-struct..Vec+reduceRight) ⇒ \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e\n        * [.every(callback)](#module_vec-struct..Vec+every) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n        * [.some(callback)](#module_vec-struct..Vec+some) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n        * [.entries()](#module_vec-struct..Vec+entries) ⇒ \u003ccode\u003eIterator.\u0026lt;Array.\u0026lt;number, Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\n        * [.keys()](#module_vec-struct..Vec+keys) ⇒ \u003ccode\u003eIterator.\u0026lt;number\u0026gt;\u003c/code\u003e\n        * [.values()](#module_vec-struct..Vec+values) ⇒ \u003ccode\u003eIterator.\u0026lt;Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u003c/code\u003e\n        * [.slice([start], [end])](#module_vec-struct..Vec+slice) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.copyWithin(target, [start], [end])](#module_vec-struct..Vec+copyWithin) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.reserve(additional)](#module_vec-struct..Vec+reserve) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.reverse()](#module_vec-struct..Vec+reverse) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.concat(...vecs)](#module_vec-struct..Vec+concat) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.pop()](#module_vec-struct..Vec+pop) ⇒ \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e\n        * [.truncate(count)](#module_vec-struct..Vec+truncate) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n        * [.fill(value, [start], [end])](#module_vec-struct..Vec+fill) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.push(...structs)](#module_vec-struct..Vec+push) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n        * [.splice(start, [deleteCount], ...items)](#module_vec-struct..Vec+splice) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.shift()](#module_vec-struct..Vec+shift) ⇒ \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.unshift(...structs)](#module_vec-struct..Vec+unshift) ⇒ \u003ccode\u003enumber\u003c/code\u003e\n        * [.shrinkTo([minCapacity])](#module_vec-struct..Vec+shrinkTo) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.sort(compareFn)](#module_vec-struct..Vec+sort) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.swap(aIndex, bIndex)](#module_vec-struct..Vec+swap) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.toJSON()](#module_vec-struct..Vec+toJSON) ⇒ \u003ccode\u003estring\u003c/code\u003e\n        * [.detachedCursor(index)](#module_vec-struct..Vec+detachedCursor) ⇒ \u003ccode\u003eDetachedVecCursor\u003c/code\u003e\n    * _static_\n        * [.def](#module_vec-struct..Vec.def) : \u003ccode\u003eReadonly.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.elementSize](#module_vec-struct..Vec.elementSize) : \u003ccode\u003eReadonly.\u0026lt;number\u0026gt;\u003c/code\u003e\n        * [.isVec(candidate)](#module_vec-struct..Vec.isVec) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\n        * [.fromMemory(memory)](#module_vec-struct..Vec.fromMemory) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.fromArray(structArray)](#module_vec-struct..Vec.fromArray) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n        * [.fromString(vecString)](#module_vec-struct..Vec.fromString) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\n\n\u003ca name=\"new_module_vec-struct..Vec_new\"\u003e\u003c/a\u003e\n\n#### new Vec([initialCapacity])\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| [initialCapacity] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e15\u003c/code\u003e | the amount of capacity to initialize vec with. Defaults to 15. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst geoCoordinates = vec({latitude: \"f32\", longitude: \"f32\"})\n\n// both are valid ways to initialize\nconst withCapacity = new geoCoordinates(100)\nconst without = new geoCoordinates()\n```\n\u003ca name=\"module_vec-struct..Vec+elementSize\"\u003e\u003c/a\u003e\n\n#### vec.elementSize : \u003ccode\u003enumber\u003c/code\u003e\nThe amount of raw memory an individual\nstruct (element of a vec) requires for this vec type.\nAn individual block of memory corresponds to\n4 bytes (32-bits).\n\nFor example if ```elementSize``` is 2, each struct\nwill take 8 bytes.\n\n**Kind**: instance property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\u003ca name=\"module_vec-struct..Vec+def\"\u003e\u003c/a\u003e\n\n#### vec.def : \u003ccode\u003eStructDef\u003c/code\u003e\nThe definition of an individual\nstruct (element) in a vec.\n\n**Kind**: instance property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\u003ca name=\"module_vec-struct..Vec+length\"\u003e\u003c/a\u003e\n\n#### vec.length : \u003ccode\u003enumber\u003c/code\u003e\nThe number of elements in vec.\nThe value is between 0 and (2^32) - 1\n(about 2 billion),\nalways numerically greater than the\nhighest index in the array.\n\n**Kind**: instance property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\u003ca name=\"module_vec-struct..Vec+capacity\"\u003e\u003c/a\u003e\n\n#### vec.capacity : \u003ccode\u003enumber\u003c/code\u003e\nThe number of elements a vec can\nhold before needing to resize.\nThe value is between 0 and (2^32) - 1\n(about 2 billion).\n\n**Kind**: instance property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Example** *(Expanding Capacity)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst Cats = vec({isCool: \"f32\", isDangerous: \"f32\"})\n// initialize with a capacity of 15\nconst cats = new Cats(15)\n// currently the \"cats\" array can hold\n// up to 15 elements without resizing\n// but does not have any elements yet\nconsole.log(cats.capacity) // output: 15\nconsole.log(cats.length) // output: 0\n\n// fill entire capacity with elements\ncats.fill({isCool: 1, isDangerous: 1})\n// now the cats array will need to resize\n// if we attempt to add more elements\nconsole.log(cats.capacity) // output: 15\nconsole.log(cats.length) // output: 15\n\nconst capacity = cats.capacity\ncats.push({isCool: 1, isDangerous: 1})\n// vec resized capacity to accommodate\n// for more elements\nconsole.log(capacity \u003c cats.capacity) // output: true\nconsole.log(cats.length) // output: 16\n```\n**Example** *(Shrinking Capacity)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst Cats = vec({isCool: \"f32\", isDangerous: \"f32\"})\n// initialize with a capacity of 15\nconst cats = new Cats(15)\n// currently the \"cats\" array can hold\n// up to 15 elements without resizing\n// but does not have any elements yet\nconsole.log(cats.capacity) // output: 15\nconsole.log(cats.length) // output: 0\nfor (let i = 0; i \u003c 5; i++) {\n     cats.push({isCool: 1, isDangerous: 1})\n}\n\n// vec can hold 3x more elements than we need\n// lets shrink the capacity to be memory efficient\nconsole.log(cats.capacity) // output: 15\nconsole.log(cats.length) // output: 5\n\n// shrink vec memory so that length\n// and capacity are the same\ncats.shrinkTo(0)\nconsole.log(cats.capacity) // output: 5\nconsole.log(cats.length) // output: 5\n```\n\u003ca name=\"module_vec-struct..Vec+memory\"\u003e\u003c/a\u003e\n\n#### vec.memory : \u003ccode\u003eReadonlyInt32Array\u003c/code\u003e\nThe binary representation\nof a vec.\n\nWARNING: It is never recommended\nto manually edit the underlying memory,\ndoing so may lead to memory corruption.\n\n**Kind**: instance property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\u003ca name=\"module_vec-struct..Vec+index\"\u003e\u003c/a\u003e\n\n#### vec.index(index) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nReturns a cursor which allows the viewing of\nthe element at the inputted index.\n\nNOTE: this method does not return the actual\nelement at the index. In order to get the entire\nelement at a given index you must use the\n\".e\" method on the cursor. If you want one\nof the fields of the element just reference\nthe field (for example \".x\")\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A cursor of the target\nindex  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| index | \u003ccode\u003enumber\u003c/code\u003e | the index you want to view |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\nconst pos = new PositionsV()\n\npos.push({x: 1, y: 1, z: 1})\npos.push({x: 1, y: 2, z: 1})\npos.push({x: 1, y: 3, z: 1})\n\n// get entire element at index 0.\n// The \"e\" property comes with all elements\n// automatically\nconsole.log(pos.index(0).e) // output: {x: 1, y: 1, z: 1}\nconsole.log(pos.index(1).e) // output: {x: 1, y: 2, z: 1}\n// get the \"y\" field of the element\n// at index 2\nconsole.log(pos.index(2).y) // output: 3\n```\n\u003ca name=\"module_vec-struct..Vec+at\"\u003e\u003c/a\u003e\n\n#### vec.at(index) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nReturns a cursor which allows the viewing of\nthe element at the inputted index.\n\nThis method is identical to the ```index``` method\nexcept that it accepts negative indices. Negative\nindices are counted from the back of the vec\n(vec.length + index)\n\nPERFORMANCE-TIP: this method is far less efficient\nthan the ```index``` method.\n\nNOTE: this method does not return the actual\nelement at the index. In order to get the entire\nelement at a given index you must use the\n\".e\" method on the cursor. If you want one\nof the fields of the element just reference\nthe field (for example \".x\")\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A cursor of the target\nindex  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| index | \u003ccode\u003enumber\u003c/code\u003e | the index you want to view. Supports negative indices. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\nconst pos = new PositionsV()\n\npos.push({x: 1, y: 1, z: 1})\npos.push({x: 1, y: 2, z: 1})\npos.push({x: 1, y: 3, z: 1})\n\n// get entire element at index 0.\n// The \"e\" property comes with all elements\n// automatically\nconsole.log(pos.index(-1).e) // output: {x: 1, y: 3, z: 1}\nconsole.log(pos.index(-2).e) // output: {x: 1, y: 2, z: 1}\n// get the \"y\" field of the element\n// at index 2\nconsole.log(pos.index(-3).y) // output: 1\n```\n\u003ca name=\"module_vec-struct..Vec+forEach\"\u003e\u003c/a\u003e\n\n#### vec.forEach(callback) ⇒ \u003ccode\u003evoid\u003c/code\u003e\nExecutes a provided function once for each\nvec element.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eForEachCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to execute for each element taking three arguments: - ```element``` The current element being processed in the - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV(15).fill({x: 1, y: 1, z: 1})\n\npos.forEach((p, i, v) =\u003e {\n     console.log(p.e) // output: {x: 1, y: 1, z: 1}\n})\n```\n\u003ca name=\"module_vec-struct..Vec+map\"\u003e\u003c/a\u003e\n\n#### vec.map(callback) ⇒ \u003ccode\u003eArray.\u0026lt;YourCallbackReturnType\u0026gt;\u003c/code\u003e\nCreates a new array populated with the results\nof calling a provided function on every\nelement in the calling vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eArray.\u0026lt;YourCallbackReturnType\u0026gt;\u003c/code\u003e - A new array with each element being\nthe result of the callback function.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eMapCallback.\u0026lt;StructDef, YourCallbackReturnValue\u0026gt;\u003c/code\u003e | Function that is called for every element of vec. Each time callbackFn executes, the returned value is added to new Array. Taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV(15).fill({x: 1, y: 1, z: 1})\nconst xVals = pos.map(p =\u003e p.x)\n\nxVals.forEach((num) =\u003e {\n     console.log(num) // output: 1\n})\n```\n\u003ca name=\"module_vec-struct..Vec+mapv\"\u003e\u003c/a\u003e\n\n#### vec.mapv(callback) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nCreates a new vec populated with the results\nof calling a provided function on every\nelement in the calling vec.\n\nEssentially ```mapv``` is the same as chaining\n```slice``` and ```forEach``` together.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec with each element being the result\nof the callback function.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eMapvCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | Function that is called for every element of vec. Please note that each element is an exact copy of the vec ```mapv``` was called on. Taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV(15).fill({x: 1, y: 1, z: 1})\nconst yAdd = pos.mapv(p =\u003e p.y += 2)\n\nyAdd.forEach((p) =\u003e {\n     console.log(p.e) // output: {x: 1, y: 3, z: 1}\n})\npos.forEach((p) =\u003e {\n     console.log(p.e) // output: {x: 1, y: 1, z: 1}\n})\nconsole.log(pos !== yAdd) // output: true\n```\n\u003ca name=\"module_vec-struct..Vec+filter\"\u003e\u003c/a\u003e\n\n#### vec.filter(callback) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nCreates a new vec with all elements that pass\nthe test implemented by the provided function.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec with the elements that pass the test.\nIf no elements pass the test, an empty vec will be\nreturned.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eTruthyIterCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to test for each element, taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 0})\n}\nconst bigZs = pos.filter(p =\u003e p.z \u003e 5)\n\nconsole.log(bigZs.length) // output: 5\nbigZs.forEach((p) =\u003e {\n     console.log(p.e) // output: {x: 1, y: 2, z: 10}\n})\nconsole.log(pos.length) // output: 10\nconsole.log(pos !== bigZs) // output: true\n```\n\u003ca name=\"module_vec-struct..Vec+find\"\u003e\u003c/a\u003e\n\n#### vec.find(callback) ⇒ \u003ccode\u003eVecCursor.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e\nReturns a vec cursor to the first element in the provided\nvec that satisfies the provided testing\nfunction. If no values satisfy the testing\nfunction, undefined is returned.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eTruthyIterCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to test for each element, taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 0})\n}\n\nconst nonExistent = pos.find(p =\u003e p.z === 100)\nconsole.log(nonExistent) // output: undefined\n\nconst exists = pos.find(p =\u003e p.z === 10)\nconsole.log(exists.e) // output: {x: 1, y: 2, z: 10}\n```\n\u003ca name=\"module_vec-struct..Vec+findIndex\"\u003e\u003c/a\u003e\n\n#### vec.findIndex(callback) ⇒ \u003ccode\u003enumber\u003c/code\u003e\nReturns the index of the first element in the\nvec that satisfies the provided testing function.\nOtherwise, it returns -1, indicating that no\nelement passed the test\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003enumber\u003c/code\u003e - The index of the first element in the vec\nthat passes the test. Otherwise, -1  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eTruthyIterCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to test for each element, taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 0})\n}\n\nconst nonExistent = pos.findIndex(p =\u003e p.z === 100)\nconsole.log(nonExistent) // output: -1\n\nconst exists = pos.findIndex(p =\u003e p.z === 10)\nconsole.log(exists) // output: 0\n```\n\u003ca name=\"module_vec-struct..Vec+lastIndexOf\"\u003e\u003c/a\u003e\n\n#### vec.lastIndexOf(callback) ⇒ \u003ccode\u003enumber\u003c/code\u003e\nReturns the last index at which a given element can\nbe found in the vec, or -1 if it\nis not present. The vec is searched\nbackwards, starting at fromIndex.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003enumber\u003c/code\u003e - The index of the last element in the vec\nthat passes the test. Otherwise, -1  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eTruthyIterCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to test for each element, taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 0})\n}\n\nconst nonExistent = pos.lastIndexOf(p =\u003e p.z === 100)\nconsole.log(nonExistent) // output: -1\n\nconst exists = pos.lastIndexOf(p =\u003e p.z === 10)\nconsole.log(exists) // output: 4\n```\n\u003ca name=\"module_vec-struct..Vec+reduce\"\u003e\u003c/a\u003e\n\n#### vec.reduce(callback, initialValue) ⇒ \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e\nExecutes a user-supplied \"reducer\" callback\nfunction on each element of the vec,\nin order, passing in the return value from the\ncalculation on the preceding element. The\nfinal result of running the reducer across\nall elements of the vec is a single value.\n\nNOTE: this implementation is slightly different\nthan the standard vec \"reduce\" as an initial\nvalue is required\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e - The value that results from\nrunning the \"reducer\" callback function\nto completion over the entire vec.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eReduceCallback.\u0026lt;StructDef, YourCallbackReturnValue\u0026gt;\u003c/code\u003e | A \"reducer\" function that takes four arguments: - ```previousValue``` the value resulting from the previous call to callbackFn. - ```currentValue``` The current element being processed - ```currentIndex``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n| initialValue | \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e | A value to which previousValue is initialized the first time the callback is called. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\nconst value = pos.reduce(p =\u003e {\n     return p.x + p.y + p.z\n}, 0)\nconsole.log(value) // output: 65\n```\n\u003ca name=\"module_vec-struct..Vec+reduceRight\"\u003e\u003c/a\u003e\n\n#### vec.reduceRight(callback, initialValue) ⇒ \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e\nApplies a function against an accumulator\nand each value of the array\n(from right-to-left) to reduce it to a single value.\n\nNOTE: this implementation is slightly different\nthan the standard array \"reduceRight\", as an initial\nvalue is required\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e - The value that results from\nrunning the \"reducer\" callback function\nto completion over the entire vec.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eReduceCallback.\u0026lt;StructDef, YourCallbackReturnValue\u0026gt;\u003c/code\u003e | A \"reducer\" function that takes four arguments: - ```previousValue``` the value resulting from the previous call to callbackFn. - ```currentValue``` The current element being processed - ```currentIndex``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n| initialValue | \u003ccode\u003eYourCallbackReturnValue\u003c/code\u003e | A value to which previousValue is initialized the first time the callback is called. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\nconst value = pos.reduceRight(p =\u003e {\n     return p.x + p.y + p.z\n}, 0)\nconsole.log(value) // output: 65\n```\n\u003ca name=\"module_vec-struct..Vec+every\"\u003e\u003c/a\u003e\n\n#### vec.every(callback) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\nTests whether all elements in the vec pass the\ntest implemented by the provided function.\nIt returns a Boolean value.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eTruthyIterCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to test for each element, taking three arguments: - ```element``` The current element being processed in the - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\n\nconst everyZis100 = pos.every(p =\u003e p.z === 100)\nconsole.log(everyZis100) // output: false\n\nconst everyZis10 = pos.every(p =\u003e p.z === 10)\nconsole.log(everyZis10) // output: 10\n```\n\u003ca name=\"module_vec-struct..Vec+some\"\u003e\u003c/a\u003e\n\n#### vec.some(callback) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\nTests whether at least one element in\nthe vec passes the test implemented\nby the provided function. It returns true\nif, in the vec, it finds an element for\nwhich the provided function returns true;\notherwise it returns false. It does not\nmodify the vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| callback | \u003ccode\u003eTruthyIterCallback.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | A function to test for each element, taking three arguments: - ```element``` The current element being processed - ```index``` (optional) The index of the current element being processed in the vec. - ```vec``` (optional) The vec which method was called upon. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\npos.push({x: 1, y: 5, z: 0})\n\nconst z100Exists = pos.some(p =\u003e p.z === 100)\nconsole.log(z100Exists) // output: false\n\nconst y5Exists = pos.some(p =\u003e p.y === 5)\nconsole.log(y5Exists) // output: true\n```\n\u003ca name=\"module_vec-struct..Vec+entries\"\u003e\u003c/a\u003e\n\n#### vec.entries() ⇒ \u003ccode\u003eIterator.\u0026lt;Array.\u0026lt;number, Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\nReturns a new vec Iterator object that\ncontains the key/value pairs for each\nindex in the vec.\n\nPERFORMANCE-TIP: Vecs are very slow when using\nthe ES6 for...of looping syntax. Imperative iteration\nand higher-order (forEach, map, etc.) iterators are\nfar more efficient.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eIterator.\u0026lt;Array.\u0026lt;number, Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e - A new vec iterator object  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\n\nfor (const [index, element] of pos.entries()) {\n     console.log(typeof index) // output: number\n     console.log(element) // output: {x: 1, y: 2, z: 10}\n}\n```\n\u003ca name=\"module_vec-struct..Vec+keys\"\u003e\u003c/a\u003e\n\n#### vec.keys() ⇒ \u003ccode\u003eIterator.\u0026lt;number\u0026gt;\u003c/code\u003e\nReturns a new Array Iterator object that\ncontains the keys for each index in the array.\n\nPERFORMANCE-TIP: Vecs are very slow when using\nthe ES6 for...of looping syntax. Imperative iteration\nand higher-order (forEach, map, etc.) iterators are\nfar more efficient.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eIterator.\u0026lt;number\u0026gt;\u003c/code\u003e - A new vec iterator object  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\n\nfor (const index of pos.keys()) {\n     console.log(typeof index) // output: number\n}\n```\n\u003ca name=\"module_vec-struct..Vec+values\"\u003e\u003c/a\u003e\n\n#### vec.values() ⇒ \u003ccode\u003eIterator.\u0026lt;Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u003c/code\u003e\nReturns a new array iterator object that\ncontains the values for each index in the array.\n\nPERFORMANCE-TIP: Vecs are very slow when using\nthe ES6 for...of looping syntax. Imperative iteration\nand higher-order (forEach, map, etc.) iterators are\nfar more efficient.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eIterator.\u0026lt;Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u003c/code\u003e - A new vec iterator object  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV()\nfor (let i = 0; i \u003c 5; i++) {\n     pos.push({x: 1, y: 2, z: 10})\n}\n\nfor (const element of pos.values()) {\n     console.log(element) // output: {x: 1, y: 2, z: 10}\n}\n```\n\u003ca name=\"module_vec-struct..Vec+slice\"\u003e\u003c/a\u003e\n\n#### vec.slice([start], [end]) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nReturns a deep copy of a portion\nof an vec into a new vec object selected from\nstart to end (end not included) where start and end\nrepresent the index of items in that vec. The original\nvec will not be modified\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec containing the extracted elements.  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| [start] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | Zero-based index at which to start extraction. A negative index can be used, indicating an offset from the end of the sequence. slice(-2) extracts the last two elements in the sequence. If start is undefined, slice starts from the index 0. If start is greater than the index range of the sequence, an empty vec is returned. |\n| [end] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003evec.length\u003c/code\u003e | Zero-based index at which to start extraction. A negative index can be used, indicating an offset from the end of the sequence. slice(-2) extracts the last two elements in the sequence. If start is undefined, slice starts from the index 0. If start is greater than the index range of the sequence, an empty vec is returned. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst pos = PositionsV(15).fill({x: 1, y: 2, z: 10})\n\nconst posCopy = pos.slice()\nconsole.log(posCopy.length) // output: 15\nposCopy.forEach(p =\u003e {\n     console.log(p.e)// output: {x: 1, y: 2, z: 10}\n})\n\n```\n\u003ca name=\"module_vec-struct..Vec+copyWithin\"\u003e\u003c/a\u003e\n\n#### vec.copyWithin(target, [start], [end]) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nShallow copies part of an vec to another location in the\nsame vec and returns it without modifying its length.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The modified vec.  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| target | \u003ccode\u003enumber\u003c/code\u003e |  | Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. If target is at or greater than vec.length, nothing will be copied. If target is positioned after start, the copied sequence will be trimmed to fit vec.length. |\n| [start] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | Zero-based index at which to start copying elements from. If negative, start will be counted from the end. If start is omitted, copyWithin will copy from index 0. |\n| [end] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003evec.length\u003c/code\u003e | Zero-based index at which to end copying elements from. copyWithin copies up to but not including end. If negative, end will be counted from the end. If end is omitted, copyWithin will copy until the last index (default to vec.length). |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        // copy position to 0 elements 2, 3, 4\n        p.copyWithin(0, 2, p.length)\n\n        console.log(p.index(0).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(1).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(2).e) // output: {x: 122, y: 23, z: 8}\n        console.log(p.index(3).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(4).e) // output: {x: 122, y: 23, z: 8}\n```\n\u003ca name=\"module_vec-struct..Vec+reserve\"\u003e\u003c/a\u003e\n\n#### vec.reserve(additional) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nTries to reserve capacity for at least additional more\nelements to be inserted in the given vec.\nAfter calling reserve, capacity will be greater than or\nequal to vec.length + additional.\nDoes nothing if capacity is already sufficient.\n\nIf runtime will not allocate any more memory, an error is thrown.\n\nPERFORMANCE-TIP: use this method before adding many elements\nto a vec to avoid resizing multiple times.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The expanded vec.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| additional | \u003ccode\u003enumber\u003c/code\u003e | The amount of elements to allocate memory for. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\n// initialize with space for 15 elements\nconst p = new PositionV(15)\nconsole.log(p.capacity) // output: 15\n\n// make space for 100 more elements\np.reserve(100)\nconsole.log(p.capacity) // output: 115\n```\n\u003ca name=\"module_vec-struct..Vec+reverse\"\u003e\u003c/a\u003e\n\n#### vec.reverse() ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nReverses an vec in place. The first vec\nelement becomes the last, and the last vec element\nbecomes the first.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The reversed vec.  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        p.reverse()\n\n        console.log(p.index(0).e) // output: {x: 122, y: 23, z: 8}\n        console.log(p.index(1).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(2).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(3).e) // output: {x: 1, y: 3, z: 0}\n        console.log(p.index(4).e) // output: {x: 2, y: 3, z: 8}\n```\n\u003ca name=\"module_vec-struct..Vec+concat\"\u003e\u003c/a\u003e\n\n#### vec.concat(...vecs) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nMerge two or more vec.\nThis method does not change the existing vec,\nbut instead returns a new vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec instance.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| ...vecs | \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | Vecs to concatenate into a new vec. If all value parameters are omitted, concat returns a deep copy of the existing vec on which it is called. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\nconst pos = new PositionsV(3).fill({x: 1, y: 1, z: 1})\nconst pos1 = new PositionsV(2).fill({x: 2, y: 1, z: 1})\nconst pos2 = new PositionsV(4).fill({x: 3, y: 1, z: 1})\n\nconst pos3 = pos.concat(pos1, pos2)\nconsole.log(pos3.length) // output: 9\n\nconsole.log(pos3 !== pos2) // output: true\nconsole.log(pos3 !== pos1) // output: true\nconsole.log(pos3 !== pos) // output: true\n\nconsole.log(pos3.index(0).e) // output: {x: 1, y: 1, z: 1}\nconsole.log(pos3.index(3).e) // output: {x: 2, y: 1, z: 1}\nconsole.log(pos3.index(5).e) // output: {x: 3, y: 1, z: 1}\n```\n\u003ca name=\"module_vec-struct..Vec+pop\"\u003e\u003c/a\u003e\n\n#### vec.pop() ⇒ \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e\nRemoves the last element from an vec and returns\nthat element. This method changes the length of\nthe vec.\n\nPERFORMANCE-TIP: use the ```truncate``` method\nif you want to efficiently remove many elements from the back,\ninstead of using a loop with the ```pop``` method.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e \\| \u003ccode\u003eundefined\u003c/code\u003e - The removed element from the vec;\nundefined if the vec is empty  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        console.log(p.pop()) // output: {x: 122, y: 23, z: 8}\n        console.log(p.length) // output: 4\n\n        console.log(p.pop()) // output: {x: 233, y: 31, z: 99}\n        console.log(p.length) // output: 3\n\n        // pop rest of elements\n        p.pop(); p.pop(); p.pop();\n        console.log(p.length) // output: 0\n\n        console.log(p.pop()) // output: undefined\n        console.log(p.length) // output: 0\n```\n\u003ca name=\"module_vec-struct..Vec+truncate\"\u003e\u003c/a\u003e\n\n#### vec.truncate(count) ⇒ \u003ccode\u003enumber\u003c/code\u003e\nRemoves the last n elements from an vec and returns\nthe new length of the vec. If no elements are present\nin vec, this is a no-op.\n\nPERFORMANCE-TIP: use the this method\nif you want to efficiently remove many elements from the back,\ninstead the ```pop``` method.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003enumber\u003c/code\u003e - New length of the vec  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| count | \u003ccode\u003enumber\u003c/code\u003e | number of elements to remove |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        const newLen = p.truncate(p.length)\n        console.log(newLen) // output: 0\n        console.log(p.length) // output: 0\n```\n\u003ca name=\"module_vec-struct..Vec+fill\"\u003e\u003c/a\u003e\n\n#### vec.fill(value, [start], [end]) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nChanges all elements in an vec to a static value,\nfrom a start index (default 0) to an\nend index (default vec.capacity).\nIt returns the modified vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The modified vec.  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| value | \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e |  | Value to fill the vec with. Note: all elements in the vec will be a copy of this value. |\n| [start] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | Start index (inclusive), default 0. |\n| [end] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003evec.capacity\u003c/code\u003e | End index (exclusive), default vec.capacity. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(15).fill({x: 1, y: 1, z: 1})\nconsole.log(p.length) // output: 15\n\np.forEach(pos =\u003e {\n     console.log(pos.e) // output: {x: 1, y: 1, z: 1}\n})\n```\n\u003ca name=\"module_vec-struct..Vec+push\"\u003e\u003c/a\u003e\n\n#### vec.push(...structs) ⇒ \u003ccode\u003enumber\u003c/code\u003e\nAdds one or more elements to the end of an Vec\nand returns the new length of the Vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003enumber\u003c/code\u003e - the new length of the vec  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| ...structs | \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | the element(s) to add to the end of a vec. Element(s) must conform to the struct def, available through the \"def\" property. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV()\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10}, {x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        console.log(p.length) // output: 5\n\n        console.log(p.index(0).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(4).e) // output: {x: 122, y: 23, z: 8}\n```\n\u003ca name=\"module_vec-struct..Vec+splice\"\u003e\u003c/a\u003e\n\n#### vec.splice(start, [deleteCount], ...items) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nChanges the contents of an vec by removing or\nreplacing existing elements and/or adding new elements in place.\nTo access part of an vec without modifying it, see slice().\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A vec containing the deleted elements.\n\nIf only one element is removed, an vec of one element is\nreturned.\n\nIf no elements are removed, an empty vec is returned.  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| start |  |  | The index at which to start changing the vec. If greater than the largest index, no operation is be performed and an empty vec is returned. If negative, it will begin that many elements from the end of the vec. (In this case, the origin -1, meaning -n is the index of the nth last element, and is therefore equivalent to the index of vec.length - n.) If start is negative infinity, no operation is be performed and an empty vec is returned. |\n| [deleteCount] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003evec.length\u003c/code\u003e | An integer indicating the number of elements in the vec to remove from start. If deleteCount is omitted, or if its value is equal to or larger than vec.length - start (that is, if it is equal to or greater than the number of elements left in the vec, starting at start), then all the elements from start to the end of the vec will be deleted. However, it must not be omitted if there is any item1 parameter. If deleteCount is 0 or negative, no elements are removed. In this case, you should specify at least one new element (see below). |\n| ...items | \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e |  | The elements to add to the vec, beginning from start. If you do not specify any elements, splice() will only remove elements from the vec. |\n\n**Example** *(Removing Elements)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        p.splice(1, 2)\n        console.log(p.length) // output: 3\n\n        console.log(p.index(0).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(1).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(2).e) // output: {x: 122, y: 23, z: 8}\n```\n**Example** *(Adding Elements)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        p.splice(1, 0, {x: 1, y: 1, z: 1}, {x: 2, y: 2, z: 2})\n        console.log(p.length) // output: 7\n\n        console.log(p.index(0).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(1).e) // output: {x: 1, y: 1, z: 1}\n        console.log(p.index(2).e) // output: {x: 2, y: 2, z: 2}\n        console.log(p.index(3).e) // output: {x: 1, y: 3, z: 0}\n        console.log(p.index(4).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(5).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(6).e) // output: {x: 122, y: 23, z: 8}\n```\n**Example** *(Adding and Removing Elements Simultaneously)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        p.splice(1, 2, {x: 1, y: 1, z: 1}, {x: 2, y: 2, z: 2})\n        console.log(p.length) // output: 5\n\n        console.log(p.index(0).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(1).e) // output: {x: 1, y: 1, z: 1}\n        console.log(p.index(2).e) // output: {x: 2, y: 2, z: 2}\n        console.log(p.index(3).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(4).e) // output: {x: 122, y: 23, z: 8}\n```\n\u003ca name=\"module_vec-struct..Vec+shift\"\u003e\u003c/a\u003e\n\n#### vec.shift() ⇒ \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nRemoves the first element from an vec and returns\nthat removed element. This method changes the length\nof the vec\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The removed element from the vec;\nundefined if the vec is empty  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20)\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        console.log(p.shift()) // output: {x: 2, y: 3, z: 8}\n        console.log(p.length) // output: 4\n\n        console.log(p.shift()) // output: {x: 1, y: 3, z: 0}\n        console.log(p.length) // output: 3\n\n        // shift rest of elements\n        p.shift(); p.shift(); p.shift();\n        console.log(p.length) // output: 0\n\n        console.log(p.shift()) // output: undefined\n        console.log(p.length) // output: 0\n```\n\u003ca name=\"module_vec-struct..Vec+unshift\"\u003e\u003c/a\u003e\n\n#### vec.unshift(...structs) ⇒ \u003ccode\u003enumber\u003c/code\u003e\nAdds one or more elements to the beginning of an\nvec and returns the new length of the vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003enumber\u003c/code\u003e - The new length of the vec.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| ...structs | \u003ccode\u003eStruct.\u0026lt;StructDef\u0026gt;\u003c/code\u003e | The element(s) to add to the front of the vec |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV()\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        p.unshift({x: 2, y: 4, z: 10})\n        p.unshift({x: 2, y: 3, z: 8}, {x: 1, y: 3, z: 0})\n\n        console.log(p.length) // output: 5\n\n        console.log(p.index(0).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(1).e) // output: {x: 1, y: 3, z: 0}\n        console.log(p.index(2).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(3).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(4).e) // output: {x: 122, y: 23, z: 8}\n```\n\u003ca name=\"module_vec-struct..Vec+shrinkTo\"\u003e\u003c/a\u003e\n\n#### vec.shrinkTo([minCapacity]) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nShrinks the capacity of the vec with a lower bound.\n\nThe capacity will remain at least as large as both\nthe length and the supplied value.\n\nIf the current capacity is less than the lower limit,\nthis is a no-op.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The shrunken vec.  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| [minCapacity] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e15\u003c/code\u003e | the maximum amount of elements a vec can hold before needing to resize. If negative, it will default to zero. If omitted, defaults to 15. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\n// initialize with space for 15 elements\nconst p = new PositionV(15)\nconsole.log(p.capacity) // output: 15\n\n// shrink so that vec can only carry 10\n// additional elements\np.shrinkTo(10)\nconsole.log(p.capacity) // output: 10\n```\n\u003ca name=\"module_vec-struct..Vec+sort\"\u003e\u003c/a\u003e\n\n#### vec.sort(compareFn) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nSorts the elements of an array in place and\nreturns the sorted array.\n\nThe underlying algorithm\nused is \"bubble sort\", with a time-space complexity\nbetween O(n^2) and O(n).\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - The sorted vec. Note that the vec\nis sorted in place, and no copy is made.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| compareFn | \u003ccode\u003eSortCompareCallback\u003c/code\u003e | Specifies a function that defines the sort order. Takes two arguments and returns a number: ```a``` The first element for comparison. ```b``` The second element for comparison. If return value is bigger than 0, ```b``` will be sorted before ```a```. If return value is smaller than 0, ```a``` will be sorted before ```b```. Otherwise if return is 0, order of the elements will not change. |\n\n**Example** *(Ascending Order)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV()\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        console.log(p.length) // output: 5\n\n        p.sort((a, b) =\u003e {\n            // if a's \"x\" field is larger than b's\n            // swap the position of a and b\n            if (a.x \u003e b.x) {\n                return 1\n            }\n            // otherwise keep the same order\n            return 0\n        })\n\n        console.log(p.index(0).e) // output: {x: 1, y: 3, z: 0}\n        console.log(p.index(1).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(2).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(3).e) // output: {x: 122, y: 23, z: 8}\n        console.log(p.index(4).e) // output: {x: 233, y: 31, z: 99}\n```\n**Example** *(Descending Order)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV()\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        console.log(p.length) // output: 5\n\n        p.sort((a, b) =\u003e {\n            // if a's \"x\" field is smaller than b's\n            // swap the position of a and b\n            if (a.x \u003c b.x) {\n                return -1\n            }\n            // otherwise keep the same order\n            return 0\n        })\n\n        console.log(p.index(0).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(1).e) // output: {x: 122, y: 23, z: 8}\n        console.log(p.index(2).e) // output: {x: 2, y: 3, z: 8}\n        console.log(p.index(3).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(4).e) // output: {x: 1, y: 3, z: 0}\n```\n\u003ca name=\"module_vec-struct..Vec+swap\"\u003e\u003c/a\u003e\n\n#### vec.swap(aIndex, bIndex) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nSwaps the position of two elements. If inputted index\nis negative it will be counted from the back of the\nvec (vec.length + index)\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - the vec with swapped elements  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| aIndex | \u003ccode\u003enumber\u003c/code\u003e | the index of the first element to swap |\n| bIndex | \u003ccode\u003enumber\u003c/code\u003e | the index of the second element to swap |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV()\n        p.push({x: 2, y: 3, z: 8})\n        p.push({x: 1, y: 3, z: 0})\n        p.push({x: 2, y: 4, z: 10})\n        p.push({x: 233, y: 31, z: 99})\n        p.push({x: 122, y: 23, z: 8})\n\n        p.swap(0, 2)\n        console.log(p.index(0).e) // output: {x: 2, y: 4, z: 10}\n        console.log(p.index(2).e) // output: {x: 2, y: 3, z: 8}\n\n        p.swap(1, 3)\n        console.log(p.index(1).e) // output: {x: 233, y: 31, z: 99}\n        console.log(p.index(3).e) // output: {x: 1, y: 3, z: 0}\n```\n\u003ca name=\"module_vec-struct..Vec+toJSON\"\u003e\u003c/a\u003e\n\n#### vec.toJSON() ⇒ \u003ccode\u003estring\u003c/code\u003e\nReturns a stringified version of the\nvec it's called on.\n\nCan be re-parsed into vec via the ```Vec.fromString```\nstatic method.\n\nNOTE: if any of the underlying memory is set to\n`NaN` (via setting with an incorrect type for example)\nit will be coerced to 0\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003estring\u003c/code\u003e - a string version of a vec  \n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV(20).fill({x: 1, y: 1, z: 1})\n\nconsole.log(p.length) // output: 20\np.forEach(pos =\u003e {\n     console.log(pos.e) // output: {x: 1, y: 1, z: 1}\n})\n\nconst vecString = p.toJSON()\nconsole.log(typeof vecString) // output: \"string\"\n// create vec from string representation\nconst jsonVec = PositionV.fromString(vecString)\n\nconsole.log(jsonVec.length) // output: 20\njsonVec.forEach(pos =\u003e {\n     console.log(pos.e) // output: {x: 1, y: 1, z: 1}\n})\n```\n\u003ca name=\"module_vec-struct..Vec+detachedCursor\"\u003e\u003c/a\u003e\n\n#### vec.detachedCursor(index) ⇒ \u003ccode\u003eDetachedVecCursor\u003c/code\u003e\nCreates an cursor that can be used to inspect/mutate\na vec, independent of the vec. It has\nidentical functionality as the ```Vec.index``` method,\nexpect that you can use it without the vec.\n\n**Kind**: instance method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| index | \u003ccode\u003enumber\u003c/code\u003e | what index should the cursor initially point at |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst p = new PositionV()\np.push(\n     {x: 1, y: 1, z: 1},\n     {x: 2, y: 2, z: 2},\n     {x: 3, y: 3, z: 3},\n)\n\n// create a cursor and point it at index\n// 0\nconst cursorA = p.detachedCursor(0)\n// create a cursor and point it at index\n// 1\nconst cursorB = p.detachedCursor(1)\n\nconsole.log(cursorA.e) // {x: 1, y: 1, z: 1}\nconsole.log(cursorB.e) // {x: 2, y: 2, z: 2}\nconsole.log(p.index(2).e) // {x: 3, y: 3, z: 3}\n\n// works like the \"index\" method of vecs\n// but can be used independantly\ncursorA.index(2).x = 55\nconsole.log(p.index(2).e) // {x: 55, y: 3, z: 3}\nconsole.log(cursorA.e) // {x: 55, y: 3, z: 3}\n```\n\u003ca name=\"module_vec-struct..Vec.def\"\u003e\u003c/a\u003e\n\n#### Vec.def : \u003ccode\u003eReadonly.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nThe definition of an individual\nstruct (element) in a vec class.\n\n**Kind**: static property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\u003ca name=\"module_vec-struct..Vec.elementSize\"\u003e\u003c/a\u003e\n\n#### Vec.elementSize : \u003ccode\u003eReadonly.\u0026lt;number\u0026gt;\u003c/code\u003e\nThe amount of raw memory an individual\nstruct (element of a vec) requires for vecs of this class.\nAn individual block of memory corresponds to\n4 bytes (32-bits).\n\nFor example if ```elementSize``` is 2, each struct\nwill take 8 bytes.\n\n**Kind**: static property of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\u003ca name=\"module_vec-struct..Vec.isVec\"\u003e\u003c/a\u003e\n\n#### Vec.isVec(candidate) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\nChecks if input is a of Vec type.\n\nIf using the static method on generated\nclass, it will check if input is of same\nVec Type of generated class.\n\nIf using the\nstatic method on the `Vec` class exported\nfrom this package, then it will check if\ninput is of type `Vec` (more general).\n\n**Kind**: static method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| candidate | \u003ccode\u003eany\u003c/code\u003e | the value to test |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec, Vec} from \"struct-vec\"\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst CatsV = vec({cuteness: \"f32\", isDangerous: \"bool\"})\n\nconst cats = new CatsV()\nconst positions = new PositionsV()\n\n// base class method checks if\n// input is a vec type\nconsole.log(Vec.isVec(cats)) // output: true\nconsole.log(Vec.isVec(positions)) // output: true\n\n// generated class method checks\n// if input is the same Vec type\n// as generated class\n// equivalent to instanceof operator\nconsole.log(CatsV.isVec(cats)) // output: true\nconsole.log(CatsV.isVec(positions)) // output: false\n\nconsole.log(PositionV.isVec(cats)) // output: false\nconsole.log(PositionV.isVec(positions)) // output: true\n```\n\u003ca name=\"module_vec-struct..Vec.fromMemory\"\u003e\u003c/a\u003e\n\n#### Vec.fromMemory(memory) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nAn alternate constructor for vecs.\nThis constructor creates a vec from\nanother vec's memory.\n\nThis constructor is particularly useful\nwhen multithreading. One can send the memory\n(```memory``` property) of a vec on one thread\nto another, via ```postMessage``` and initialize\nan identical vec on the receiving thread through\nthis constructor.\n\nVec memory is backed by ```SharedArrayBuffer```s,\nso sending it between workers and the main thread is\na zero-copy operation. In other words, vec memory\nis always sent by reference when using the ```postMessage```\nmethod of ```Worker```s.\n\n**Kind**: static method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| memory | \u003ccode\u003eReadonlyInt32Array\u003c/code\u003e | memory of another Vec of the same kind |\n\n**Example** *(Multithreading)*  \n```js\n// ------------ index.mjs ---------------\nimport {vec} from \"struct-vec\"\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst positions = new PositionV(10_000).fill(\n     {x: 1, y: 1, z: 1}\n)\n\nconst worker = new Worker(\"worker.mjs\", {type: \"module\"})\n// pass by reference, no copying\nworker.postMessage(positions.memory)\n\n// ------------ worker.mjs ---------------\nimport {vec} from \"struct-vec\"\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n\nself.onmessage = (message) =\u003e {\n     PositionV.fromMemory(message.data).forEach((pos) =\u003e {\n         pos.x += 1\n         pos.y += 2\n         pos.z += 3\n     })\n}\n```\n\u003ca name=\"module_vec-struct..Vec.fromArray\"\u003e\u003c/a\u003e\n\n#### Vec.fromArray(structArray) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nAn alternate constructor for vecs.\nCreates a vec from inputted\narray, if all elements of array are compliant\nwith struct def of given vec class.\n\n**Kind**: static method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| structArray | \u003ccode\u003eArray.\u0026lt;Struct.\u0026lt;StructDef\u0026gt;\u0026gt;\u003c/code\u003e | array from which to construct the vec. |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec, Vec} from \"struct-vec\"\n\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\nconst arr = new Array(15).fill({x: 1, y: 2, z: 3})\n\nconst positions = PositionsV.fromArray(arr)\nconsole.log(Vec.isVec(positions)) // output: true\n```\n\u003ca name=\"module_vec-struct..Vec.fromString\"\u003e\u003c/a\u003e\n\n#### Vec.fromString(vecString) ⇒ \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nAn alternate constructor for vecs.\nCreates a new vec instance from an inputted\nstring.\n\nString should be a stringified vec. One\ncan stringify any vec instance by calling the\n```toJSON``` method.\n\n**Kind**: static method of [\u003ccode\u003eVec\u003c/code\u003e](#module_vec-struct..Vec)  \n**Returns**: \u003ccode\u003eVec.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A new vec  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| vecString | \u003ccode\u003estring\u003c/code\u003e | a stringified vec |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec, Vec} from \"struct-vec\"\n\nconst geoCoordinates = vec({latitude: \"f32\", longitude: \"f32\"})\n\nconst geo = new geoCoordinates(15).fill({\n            latitude: 20.10,\n            longitude: 76.52\n        })\nconst string = JSON.stringify(geo)\nconst parsed = JSON.parse(string)\n\nconst geoCopy = geoCoordinates.fromString(parsed)\nconsole.log(Vec.isVec(geoCopy)) // output: true\n```\n\u003ca name=\"module_vec-struct..validateStructDef\"\u003e\u003c/a\u003e\n\n### vec-struct~validateStructDef(def) ⇒ \u003ccode\u003eboolean\u003c/code\u003e\nA helper function to validate an inputted struct\ndefinition. If inputted struct def is valid\nthe function true, otherwise it will return\nfalse.\n\n**Kind**: inner method of [\u003ccode\u003evec-struct\u003c/code\u003e](#module_vec-struct)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| def | \u003ccode\u003eany\u003c/code\u003e | the struct definition to be validated |\n\n**Example** *(Basic Usage)*  \n```js\nimport {validateStructDef} from \"vec-struct\"\n\nconsole.log(validateStructDef(null)) // output: false\nconsole.log(validateStructDef(true)) // output: false\nconsole.log(validateStructDef(\"def\")) // output: false\nconsole.log(validateStructDef({x: \"randomType\"})) // output: false\nconsole.log(validateStructDef({x: {y: \"f32\"}})) // output: false\n\nconsole.log(validateStructDef({x: \"f32\"})) // output: true\nconsole.log(validateStructDef({code: \"f32\"})) // output: true\n```\n\u003ca name=\"module_vec-struct..vec_gen\"\u003e\u003c/a\u003e\n\n### vec-struct~vec(structDef, [options]) ⇒ \u003ccode\u003eVecClass.\u0026lt;StructDef\u0026gt;\u003c/code\u003e\nA vec compiler that can be used at runtime.\nCreates class definitions for growable array-like\ndata structure (known as a vector or vec for short) that\nhold fixed-sized objects (known as structs) from\nyour inputted struct definition.\n\nVecs are backed by SharedArrayBuffers and therefore\ncan be passed across threads with zero serialization\ncost.\n\nSAFETY-NOTE: this compiler uses the unsafe `Function`\nconstructor internally. Use`vecCompile` if you\nwish to avoid unsafe code. Do note, that `vecCompile`\ncan only be used at build time.\n\nNOTE: vecs carry fixed-sized, strongly-typed\nelements that cannot be change once the class is\ncreated, unlike normal arrays.\n\n**Kind**: inner method of [\u003ccode\u003evec-struct\u003c/code\u003e](#module_vec-struct)  \n**Returns**: \u003ccode\u003eVecClass.\u0026lt;StructDef\u0026gt;\u003c/code\u003e - A class that creates vecs which conform\nto inputted def  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| structDef | \u003ccode\u003eStructDef\u003c/code\u003e |  | a type definition for the elements to be carried by an instance of the generated vec class |\n| [options] | \u003ccode\u003eObject\u003c/code\u003e |  |  |\n| [options.className] | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e\u0026quot;AnonymousVec\u0026quot;\u003c/code\u003e | the value of the generated class's `name` property. Useful for debugging |\n\n**Example** *(Basic Usage)*  \n```js\nimport {vec} from \"struct-vec\"\n\n// create Vec definition\nconst PositionV = vec({x: \"f32\", y: \"f32\", z: \"f32\"})\n// now initialize like a normal class\nconst p = new PositionV()\n\nconst geoCoordinates = vec({latitude: \"f32\", longitude: \"f32\"})\nconst geo = new geoCoordinates(15).fill({latitude: 1, longitude: 1})\n\n// invalid struct defs throws error\nconst errClass = vec(null) // SyntaxError\nconst errClass2 = vec({x: \"unknownType\"}) // SyntaxError\n```\n\u003ca name=\"module_vec-struct..vec_genCompile\"\u003e\u003c/a\u003e\n\n### vec-struct~vecCompile(structDef, pathToLib, [options]) ⇒ \u003ccode\u003estring\u003c/code\u003e\nA vec compiler that can be used at build time.\nCreates class definitions for growable array-like\ndata structure (known as a vector or vec for short) that\nhold fixed-sized objects (known as structs) from\nyour inputted struct definition.\n\nClass definitions created by this compiler are the exact same\nas the one's created by the runtime compiler.\n\nVecs are backed by SharedArrayBuffers and therefore\ncan be passed across threads with zero serialization\ncost.\n\nNOTE: this compiler does not come will any command line\ntool, so you as the user must decide how to generate\nand store the vec classes emitted by this compiler.\n\nNOTE: vecs carry fixed-sized, strongly-typed\nelements that cannot be change once the class is\ncreated, unlike normal arrays.\n\n**Kind**: inner method of [\u003ccode\u003evec-struct\u003c/code\u003e](#module_vec-struct)  \n**Returns**: \u003ccode\u003estring\u003c/code\u003e - a string rendition of vec class  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| structDef | \u003ccode\u003eStructDef\u003c/code\u003e |  | a type definition for the elements to be carried by an instance of the generated vec class. |\n| pathToLib | \u003ccode\u003estring\u003c/code\u003e |  | where the \"struct-vec\" library is located use the full url if using compiler in web (without build tool) or deno. |\n| [options] | \u003ccode\u003eObject\u003c/code\u003e |  |  |\n| [options.bindings] | \u003ccode\u003e\u0026quot;js\u0026quot;\u003c/code\u003e \\| \u003ccode\u003e\u0026quot;ts\u0026quot;\u003c/code\u003e | \u003ccode\u003e\u0026quot;js\u0026quot;\u003c/code\u003e | what language should vec class be generated in. Choose either \"js\" (javascript) or \"ts\" (typescript). Defaults to \"js\". |\n| [options.exportSyntax] | \u003ccode\u003e\u0026quot;none\u0026quot;\u003c/code\u003e \\| \u003ccode\u003e\u0026quot;named\u0026quot;\u003c/code\u003e \\| \u003ccode\u003e\u0026quot;default\u0026quot;\u003c/code\u003e | \u003ccode\u003e\u0026quot;none\u0026quot;\u003c/code\u003e | what es6 export syntax should class be generated with. Choose either \"none\" (no import statement with class), \"named\" (use the \"export\" syntax), or \"default\" (use \"export default\" syntax). Defaults to \"none\". |\n| [options.className] | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e\u0026quot;AnonymousVec\u0026quot;\u003c/code\u003e | the name of the generated vec class. Defaults to \"AnonymousVec\". |\n\n**Example** *(Basic Usage)*  \n```js\nimport fs from \"fs\"\nimport {vecCompile} from \"struct-vec\"\n\n// the path to the \"struct-vec\" library.\n// For the web or deno, you would\n// put the full url to the library.\nconst LIB_PATH = \"struct-vec\"\n\n// create Vec definition\nconst def = {x: \"f32\", y: \"f32\", z: \"f32\"}\nconst GeneratedClass = vecCompile(def, LIB_PATH, {\n     // create a typescript class\n     lang: \"ts\",\n     // export the class with \"export default\"\n     // syntax\n     exportSyntax: \"default\",\n     className: \"GeneratedClass\"\n})\nconsole.log(typeof GeneratedClass) // output: string\n// write the class to disk to use later\n// // or in another application\nfs.writeFileSync(\"GeneratedClass\", GeneratedClass, {\n     encoding: \"utf-8\"\n})\n```\n","funding_links":[],"categories":["Libraries"],"sub_categories":["JavaScript"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoomoolive%2Fstruct-vec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoomoolive%2Fstruct-vec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoomoolive%2Fstruct-vec/lists"}