{"id":19504025,"url":"https://github.com/mysticatea/bre","last_synced_at":"2025-04-26T00:33:25.621Z","repository":{"id":65974369,"uuid":"63289604","full_name":"mysticatea/bre","owner":"mysticatea","description":"A Binary-Object Mapper for JavaScript","archived":false,"fork":false,"pushed_at":"2018-05-24T07:29:05.000Z","size":625,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-21T21:04:26.219Z","etag":null,"topics":["arraybuffer","binary-data","buffer","ecmascript","javascript","npm-module","npm-package","objects","structs","wrapper"],"latest_commit_sha":null,"homepage":"https://mysticatea.github.io/bre/","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/mysticatea.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":"2016-07-14T00:49:25.000Z","updated_at":"2019-02-19T22:15:32.000Z","dependencies_parsed_at":"2023-02-19T17:45:18.331Z","dependency_job_id":null,"html_url":"https://github.com/mysticatea/bre","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysticatea%2Fbre","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysticatea%2Fbre/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysticatea%2Fbre/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mysticatea%2Fbre/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mysticatea","download_url":"https://codeload.github.com/mysticatea/bre/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250917284,"owners_count":21507561,"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":["arraybuffer","binary-data","buffer","ecmascript","javascript","npm-module","npm-package","objects","structs","wrapper"],"created_at":"2024-11-10T22:24:00.801Z","updated_at":"2025-04-26T00:33:25.376Z","avatar_url":"https://github.com/mysticatea.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bre\n\n[![npm version](https://img.shields.io/npm/v/bre.svg)](https://www.npmjs.com/package/bre)\n[![Downloads/month](https://img.shields.io/npm/dm/bre.svg)](http://www.npmtrends.com/bre)\n[![Build Status](https://travis-ci.org/mysticatea/bre.svg?branch=master)](https://travis-ci.org/mysticatea/bre)\n[![codecov](https://codecov.io/gh/mysticatea/bre/branch/master/graph/badge.svg)](https://codecov.io/gh/mysticatea/bre)\n[![Dependency Status](https://david-dm.org/mysticatea/bre.svg)](https://david-dm.org/mysticatea/bre)\n\nA Object-Binary Mapper for JavaScript/TypeScript.\n\nThis is similar to C `struct` with a memory block.\n\n```ts\nimport { defineObjectRecord } from \"bre\"\n\n// Define a Record Type.\nconst TcpHeader = defineObjectRecord(\"TcpHeader\", {\n    srcPort: \"uint16\",\n    dstPort: \"uint16\",\n    seqNo: \"uint32\",\n    ackNo: \"uint32\",\n    dataOffset: \"bit4\",\n    _reserved0: \"bit6\", // padding\n    urgCode: \"bit1\",\n    ackCode: \"bit1\",\n    pshCode: \"bit1\",\n    rstCode: \"bit1\",\n    synCode: \"bit1\",\n    finCode: \"bit1\",\n    windowSize: \"uint16\",\n    checksum: \"uint16\",\n    urgentPonter: \"uint16\",\n})\n\n// Connect to a Buffer (E.g., a buffer came from stream...)\nconst header = TcpHeader.view(a_buffer, 0)\n\n// Read and Write the Buffer\nconsole.log(header.srcPort, \"→\", header.dstPort, \"🚀\")\nheader.seqNo += 1\nheader.ackNo += 1\nheader.ackCode = 1\n```\n\n`bre`'s record object is just a wrapper of [ArrayBuffer] objects.\n\n- The read of properties reads the connected buffer directly.\n- The write of properties writes the connected buffer directly.\n\nSo the above `TcpHeader` example defines the class like the following automatically: \u003cdetails\u003e\u003csummary\u003eOpen the defined class\u003c/summary\u003e\n\n```js\nclass TcpHeader extends ObjectRecord {\n    constructor(buffer, byteOffset) {\n        super(buffer, byteOffset, 20)\n    }\n\n    static view(buffer, byteOffset = 0) {\n        return Object.freeze(new TcpHeader(buffer, byteOffset))\n    }\n\n    static get bitLength() {\n        return 160\n    }\n\n    static get byteLength() {\n        return 20\n    }\n\n    static keys(record) {\n        return [\n            \"srcPort\",\n            \"dstPort\",\n            \"seqNo\",\n            \"ackNo\",\n            \"dataOffset\",\n            \"urgCode\",\n            \"ackCode\",\n            \"pshCode\",\n            \"rstCode\",\n            \"synCode\",\n            \"finCode\",\n            \"windowSize\",\n            \"checksum\",\n            \"urgentPonter\",\n        ]\n    }\n\n    static values(record) {\n        return [\n            record.srcPort,\n            record.dstPort,\n            record.seqNo,\n            record.ackNo,\n            record.dataOffset,\n            record.urgCode,\n            record.ackCode,\n            record.pshCode,\n            record.rstCode,\n            record.synCode,\n            record.finCode,\n            record.windowSize,\n            record.checksum,\n            record.urgentPonter,\n        ]\n    }\n\n    static entries(record) {\n        return [\n            [\"srcPort\", record.srcPort],\n            [\"dstPort\", record.dstPort],\n            [\"seqNo\", record.seqNo],\n            [\"ackNo\", record.ackNo],\n            [\"dataOffset\", record.dataOffset],\n            [\"urgCode\", record.urgCode],\n            [\"ackCode\", record.ackCode],\n            [\"pshCode\", record.pshCode],\n            [\"rstCode\", record.rstCode],\n            [\"synCode\", record.synCode],\n            [\"finCode\", record.finCode],\n            [\"windowSize\", record.windowSize],\n            [\"checksum\", record.checksum],\n            [\"urgentPonter\", record.urgentPonter],\n        ]\n    }\n\n    get srcPort() {\n        return this[sBuffer].getUint16(0)\n    }\n    set srcPort(value) {\n        assert.integer(value, \"srcPort\")\n        assert.range(value, 0, 65535, \"srcPort\")\n        this[sBuffer].setUint16(0, value)\n    }\n    get dstPort() {\n        return this[sBuffer].getUint16(2)\n    }\n    set dstPort(value) {\n        assert.integer(value, \"dstPort\")\n        assert.range(value, 0, 65535, \"dstPort\")\n        this[sBuffer].setUint16(2, value)\n    }\n    get seqNo() {\n        return this[sBuffer].getUint32(4)\n    }\n    set seqNo(value) {\n        assert.integer(value, \"seqNo\")\n        assert.range(value, 0, 4294967295, \"seqNo\")\n        this[sBuffer].setUint32(4, value)\n    }\n    get ackNo() {\n        return this[sBuffer].getUint32(8)\n    }\n    set ackNo(value) {\n        assert.integer(value, \"ackNo\")\n        assert.range(value, 0, 4294967295, \"ackNo\")\n        this[sBuffer].setUint32(8, value)\n    }\n    get dataOffset() {\n        const data = this[sBuffer].getUint8(12)\n        return (data \u0026 240) \u003e\u003e 4\n    }\n    set dataOffset(value) {\n        assert.integer(value, \"dataOffset\")\n        assert.range(value, 0, 15, \"dataOffset\")\n\n        const data = this[sBuffer].getUint8(12)\n        this[sBuffer].setUint8(12, ((value \u003c\u003c 4) \u0026 240) | (data \u0026 ~240))\n    }\n    get urgCode() {\n        const data = this[sBuffer].getUint8(13)\n        return (data \u0026 32) \u003e\u003e 5\n    }\n    set urgCode(value) {\n        assert.integer(value, \"urgCode\")\n        assert.range(value, 0, 1, \"urgCode\")\n\n        const data = this[sBuffer].getUint8(13)\n        this[sBuffer].setUint8(13, ((value \u003c\u003c 5) \u0026 32) | (data \u0026 ~32))\n    }\n    get ackCode() {\n        const data = this[sBuffer].getUint8(13)\n        return (data \u0026 16) \u003e\u003e 4\n    }\n    set ackCode(value) {\n        assert.integer(value, \"ackCode\")\n        assert.range(value, 0, 1, \"ackCode\")\n\n        const data = this[sBuffer].getUint8(13)\n        this[sBuffer].setUint8(13, ((value \u003c\u003c 4) \u0026 16) | (data \u0026 ~16))\n    }\n    get pshCode() {\n        const data = this[sBuffer].getUint8(13)\n        return (data \u0026 8) \u003e\u003e 3\n    }\n    set pshCode(value) {\n        assert.integer(value, \"pshCode\")\n        assert.range(value, 0, 1, \"pshCode\")\n\n        const data = this[sBuffer].getUint8(13)\n        this[sBuffer].setUint8(13, ((value \u003c\u003c 3) \u0026 8) | (data \u0026 ~8))\n    }\n    get rstCode() {\n        const data = this[sBuffer].getUint8(13)\n        return (data \u0026 4) \u003e\u003e 2\n    }\n    set rstCode(value) {\n        assert.integer(value, \"rstCode\")\n        assert.range(value, 0, 1, \"rstCode\")\n\n        const data = this[sBuffer].getUint8(13)\n        this[sBuffer].setUint8(13, ((value \u003c\u003c 2) \u0026 4) | (data \u0026 ~4))\n    }\n    get synCode() {\n        const data = this[sBuffer].getUint8(13)\n        return (data \u0026 2) \u003e\u003e 1\n    }\n    set synCode(value) {\n        assert.integer(value, \"synCode\")\n        assert.range(value, 0, 1, \"synCode\")\n\n        const data = this[sBuffer].getUint8(13)\n        this[sBuffer].setUint8(13, ((value \u003c\u003c 1) \u0026 2) | (data \u0026 ~2))\n    }\n    get finCode() {\n        const data = this[sBuffer].getUint8(13)\n        return (data \u0026 1) \u003e\u003e 0\n    }\n    set finCode(value) {\n        assert.integer(value, \"finCode\")\n        assert.range(value, 0, 1, \"finCode\")\n\n        const data = this[sBuffer].getUint8(13)\n        this[sBuffer].setUint8(13, ((value \u003c\u003c 0) \u0026 1) | (data \u0026 ~1))\n    }\n    get windowSize() {\n        return this[sBuffer].getUint16(14)\n    }\n    set windowSize(value) {\n        assert.integer(value, \"windowSize\")\n        assert.range(value, 0, 65535, \"windowSize\")\n        this[sBuffer].setUint16(14, value)\n    }\n    get checksum() {\n        return this[sBuffer].getUint16(16)\n    }\n    set checksum(value) {\n        assert.integer(value, \"checksum\")\n        assert.range(value, 0, 65535, \"checksum\")\n        this[sBuffer].setUint16(16, value)\n    }\n    get urgentPonter() {\n        return this[sBuffer].getUint16(18)\n    }\n    set urgentPonter(value) {\n        assert.integer(value, \"urgentPonter\")\n        assert.range(value, 0, 65535, \"urgentPonter\")\n        this[sBuffer].setUint16(18, value)\n    }\n}\n```\n\n\u003c/details\u003e\u003cbr\u003e\n\nPlus, this package provides the perfect type definition for the classes that `defineObjectRecord`/`defineArrayRecord` defined.\n\n[ArrayBuffer]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer\n\n## 💿 Installation\n\n```bash\n$ npm install --save bre\n```\n\n- Requires Node.js `\u003e=6.0.0`\n\n## 📖 Usage\n\nTBD.\n\n## 📰 Changelog\n\n- https://github.com/mysticatea/bre/releases\n\n## ❤️ Contributing\n\nThank you for contributing!\n\nUse Issues/PRs on GitHub.\n\n### Development tools\n\n- `npm test` ... Runs all tests.\n- `npm run build` ... Compiles JavaScript code from TypeScript source code.\n- `npm run clean` ... Removes compiled files, temporary files, and coverage data.\n- `npm run coverage` ... Opens the code coverage of the last `npm test`.\n- `npm run lint` ... Applies ESLint to the source code.\n- `npm run watch` ... Runs all tests on every file changes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmysticatea%2Fbre","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmysticatea%2Fbre","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmysticatea%2Fbre/lists"}