Compare commits

...

37 Commits

Author SHA1 Message Date
1c80a1097b 3.0.5 2025-04-12 16:52:44 +00:00
4344dbd111 fix(documentation): Enhance documentation with extensive usage examples, update project metadata, and remove obsolete CI configuration, fixes 2025-04-12 16:52:44 +00:00
bb89564339 update description 2024-05-29 14:11:56 +02:00
f480be9917 3.0.4 2024-04-25 18:08:50 +02:00
11bf0d9dbb fix(core): update 2024-04-25 18:08:49 +02:00
c58cc2b0df 3.0.3 2024-04-25 18:06:05 +02:00
87273cbbbd fix(core): update 2024-04-25 18:06:04 +02:00
bebc8b0ede 3.0.2 2024-04-17 20:34:18 +02:00
46e5217fc0 fix(core): update 2024-04-17 20:34:17 +02:00
ebb539e824 3.0.1 2024-04-17 20:33:24 +02:00
63e3b492e6 fix(core): update 2024-04-17 20:33:24 +02:00
158614c62c 3.0.0 2024-04-17 20:30:33 +02:00
f11114f6dc BREAKING CHANGE(core): update 2024-04-17 20:30:32 +02:00
f233cb1dcd 2.0.3 2024-04-17 19:49:30 +02:00
866da6f21a fix(core): update 2024-04-17 19:49:30 +02:00
30ac0ddbb4 2.0.2 2024-04-17 19:49:14 +02:00
4c5105aae7 fix(core): update 2024-04-17 19:49:14 +02:00
1f6e257cb7 2.0.1 2024-04-17 19:10:22 +02:00
0a79087c59 fix(core): update 2024-04-17 19:10:21 +02:00
432a59bcec 2.0.0 2024-04-17 19:09:56 +02:00
10d7c5d8e8 BREAKING CHANGE(core): switch to uInt8Extras 2024-04-17 19:09:55 +02:00
30306f3a40 update tsconfig 2024-04-14 17:23:03 +02:00
9a4859f6a0 update npmextra.json: githost 2024-04-01 21:33:58 +02:00
099a68d19f update npmextra.json: githost 2024-04-01 19:57:44 +02:00
78576b363e update npmextra.json: githost 2024-03-30 21:46:41 +01:00
066dac4bdc 1.0.7 2024-02-29 22:43:37 +01:00
e1faf34660 fix(core): update 2024-02-29 22:43:37 +01:00
031f6449bd 1.0.6 2024-02-25 01:45:49 +01:00
4f5282e5cd fix(core): update 2024-02-25 01:45:48 +01:00
d42bf699f7 1.0.5 2024-02-25 01:33:16 +01:00
a0d3e8b12f fix(core): update 2024-02-25 01:33:15 +01:00
e343caa204 1.0.4 2024-02-25 01:17:48 +01:00
693a2de3e5 fix(core): update 2024-02-25 01:17:47 +01:00
9ef10edf3d switch to new org scheme 2023-07-11 00:17:11 +02:00
7fee4d8612 switch to new org scheme 2023-07-10 02:42:20 +02:00
9fe5a2fcdc 1.0.3 2022-06-16 00:05:31 +02:00
6d28b76601 fix(core): update 2022-06-16 00:05:30 +02:00
15 changed files with 10960 additions and 11368 deletions

@ -1,139 +0,0 @@
# gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: '$CI_BUILD_STAGE'
stages:
- security
- test
- release
- metadata
before_script:
- npm install -g @shipzone/npmci
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
only:
- tags
tags:
- lossless
- docker
- notpriv
auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --production --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=prod --production
tags:
- docker
allow_failure: true
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=dev
tags:
- docker
allow_failure: true
# ====================
# test stage
# ====================
testStable:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- lossless
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
only:
- tags
script:
- npmci command npm install -g typescript
- npmci npm prepare
- npmci npm install
tags:
- lossless
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- lossless
- docker
- notpriv
pages:
stage: metadata
script:
- npmci node install stable
- npmci npm prepare
- npmci npm install
- npmci command npm run buildDocs
tags:
- lossless
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

80
changelog.md Normal file

@ -0,0 +1,80 @@
# Changelog
## 2025-04-12 - 3.0.5 - fix(documentation)
Enhance documentation with extensive usage examples, update project metadata, and remove obsolete CI configuration
- Updated package description and keywords in package.json and npmextra.json to better reflect the library's robust binary data handling capabilities
- Revised README with comprehensive guides, detailed code examples, and advanced use cases for conversions, validations, and integrations
- Removed outdated .gitlab-ci.yml file to streamline CI configuration
- Improved clarity and structure in documentation for both browser and Node.js environments
## 2024-05-29 - 3.0.4 - misc
Updated project description.
- Updated the project description to better reflect current features.
## 2024-04-25 - 3.0.3 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-25 - 3.0.2 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-17 - 3.0.1 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-17 - 3.0.0 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-17 - 2.0.3 - core
Breaking change in core module.
- BREAKING CHANGE (core): Updated core functionality.
## 2024-04-17 - 2.0.2 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-17 - 2.0.1 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-17 - 2.0.0 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-04-17 - 1.0.7 - core, config
Multiple updates including breaking changes and configuration adjustments.
- BREAKING CHANGE (core): Switched to uInt8Extras.
- Updated tsconfig.
- Updated npmextra.json for githost.
## 2024-02-29 - 1.0.6 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-02-25 - 1.0.5 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-02-25 - 1.0.4 - core
Core fixes applied.
- Fixed issues in the core module.
## 2024-02-25 - 1.0.3 - core, org
Core fixes and organizational change.
- Fixed issues in the core module.
- Switched to new organization scheme.
## 2022-06-15 - 1.0.2 - core
Core fixes applied.
- Fixed issues in the core module.
## 2022-06-15 - 1.0.1 - core
Core fixes applied.
- Fixed issues in the core module.
<!--
Note: Routine version bump commits that only updated the version numbers have been omitted for clarity.
-->

@ -1,4 +1,5 @@
Copyright (c) 2022 Lossless GmbH (hello@lossless.com)
Copyright 2011 Jon Leighton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -2,17 +2,32 @@
"gitzone": {
"projectType": "npm",
"module": {
"githost": "gitlab.com",
"gitscope": "pushrocks",
"githost": "code.foss.global",
"gitscope": "push.rocks",
"gitrepo": "smartbuffer",
"description": "handle ArrayBufferLike structures",
"npmPackagename": "@pushrocks/smartbuffer",
"description": "A robust TypeScript library for managing binary data by converting between Base64 strings and Uint8Array, validating buffer-like objects, and ensuring data purity.",
"npmPackagename": "@push.rocks/smartbuffer",
"license": "MIT",
"projectDomain": "push.rocks"
"projectDomain": "push.rocks",
"keywords": [
"ArrayBuffer",
"Uint8Array",
"base64 conversion",
"binary data handling",
"buffer validation",
"TypeScript",
"data transformation",
"ESM",
"utilities",
"npm"
]
}
},
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
},
"tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
}
}

11165
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,8 +1,8 @@
{
"name": "@pushrocks/smartbuffer",
"version": "1.0.2",
"name": "@push.rocks/smartbuffer",
"version": "3.0.5",
"private": false,
"description": "handle ArrayBufferLike structures",
"description": "A robust TypeScript library for managing binary data by converting between Base64 strings and Uint8Array, validating buffer-like objects, and ensuring data purity.",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"type": "module",
@ -10,18 +10,16 @@
"license": "MIT",
"scripts": {
"test": "(tstest test/ --web)",
"build": "(tsbuild --web --allowimplicitany)",
"buildDocs": "(tsdoc)"
"build": "(tsbuild --web --allowimplicitany)"
},
"devDependencies": {
"@gitzone/tsbuild": "^2.1.25",
"@gitzone/tsbundle": "^2.0.5",
"@gitzone/tsdoc": "^1.1.10",
"@gitzone/tstest": "^1.0.44",
"@pushrocks/tapbundle": "^5.0.3",
"@types/node": "^17.0.41"
"@git.zone/tsbuild": "^2.1.25",
"@git.zone/tsbundle": "^2.0.5",
"@git.zone/tsrun": "^1.2.46",
"@git.zone/tstest": "^1.0.44",
"@push.rocks/tapbundle": "^5.0.8",
"@types/node": "^20.11.20"
},
"dependencies": {},
"browserslist": [
"last 1 chrome versions"
],
@ -36,5 +34,26 @@
"cli.js",
"npmextra.json",
"readme.md"
]
],
"keywords": [
"ArrayBuffer",
"Uint8Array",
"base64 conversion",
"binary data handling",
"buffer validation",
"TypeScript",
"data transformation",
"ESM",
"utilities",
"npm"
],
"dependencies": {
"uint8array-extras": "^1.1.0"
},
"homepage": "https://code.foss.global/push.rocks/smartbuffer",
"repository": {
"type": "git",
"url": "https://code.foss.global/push.rocks/smartbuffer.git"
},
"packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6"
}

9838
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

1
readme.hints.md Normal file

@ -0,0 +1 @@

942
readme.md

@ -1,39 +1,925 @@
# @pushrocks/smartbuffer
handle ArrayBufferLike structures
# @push.rocks/smartbuffer
A library for managing ArrayBufferLike structures including conversion between Base64 and Uint8Array, and buffer validation.
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartbuffer)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartbuffer)
* [github.com (source mirror)](https://github.com/pushrocks/smartbuffer)
* [docs (typedoc)](https://pushrocks.gitlab.io/smartbuffer/)
## Install
## Status for master
To install @push.rocks/smartbuffer, simply run:
Status Category | Status Badge
-- | --
GitLab Pipelines | [![pipeline status](https://gitlab.com/pushrocks/smartbuffer/badges/master/pipeline.svg)](https://lossless.cloud)
GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/pushrocks/smartbuffer/badges/master/coverage.svg)](https://lossless.cloud)
npm | [![npm downloads per month](https://badgen.net/npm/dy/@pushrocks/smartbuffer)](https://lossless.cloud)
Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/pushrocks/smartbuffer)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@pushrocks/smartbuffer)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@pushrocks/smartbuffer)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@pushrocks/smartbuffer)](https://lossless.cloud)
Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20Windows%2010/yes/green?icon=windows)](https://lossless.cloud) [![Supports Mac OS X](https://badgen.net/badge/supports%20Mac%20OS%20X/yes/green?icon=apple)](https://lossless.cloud)
```sh
npm install @push.rocks/smartbuffer
```
If you are using yarn:
```sh
yarn add @push.rocks/smartbuffer
```
This module is designed for developers who need advanced utilities for handling binary data in TypeScript applications using ECMAScript Modules (ESM). It provides seamless conversion between Base64 strings and Uint8Array representations, ensures buffer-like objects are valid, and extends capabilities with useful operations from the uint8array-extras package.
## Usage
use TypeScript for best in class intellisense
The following usage guide offers a comprehensive walkthrough of the features provided by @push.rocks/smartbuffer. We will not only show you the basic functions available, but also guide you through advanced techniques, integrating these utilities into complex applications that require reliable binary data manipulation. Every example is written in TypeScript using ESM syntax to ensure modern code quality and compatibility with contemporary development frameworks.
## Contribution
In this guide, we will explore the following topics in detail:
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
1. Introduction to Binary Data Handling
2. Understanding ArrayBufferLike Structures and Uint8Array
3. Overview of @push.rocks/smartbuffer Functions
4. Converting Uint8Array Data to Base64
5. Converting Base64 Strings to Uint8Array
6. Validating Buffer-like Objects in Different Environments
7. Ensuring Data Purity: The ensurePureUint8Array Function
8. Working with Extended Utilities from uint8array-extras
9. Handling Edge Cases and Error Checking
10. Integrating smartbuffer into Real-World Applications
11. Performance Considerations and Best Practices
12. Comprehensive Code Examples and Use Cases
13. Debugging and Testing Your Implementation
14. Advanced Topics and Future Directions
For further information read the linked docs at the top of this readme.
Below, we present detailed explanations and code examples for each of these topics, with real-world scenarios and sophisticated use cases that should address all possible requirements when working with binary data.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
---
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)
### 1. Introduction to Binary Data Handling
When building modern applications, especially those that deal with network communication, media processing, or data storage, binary data handling becomes crucial. Binary data in JavaScript is typically managed through the ArrayBuffer interface, and typed arrays, such as Uint8Array, for better performance and memory management. However, direct manipulation of these structures can be error-prone and requires careful management regarding conversions and validations.
@push.rocks/smartbuffer is a utility library developed to encapsulate many common operations on ArrayBufferLike objects. Whether youre dealing with Base64 encoding/decoding or simply need to validate if an object is buffer-like, this library simplifies these operations into streamlined functions. This makes your development process smoother and reduces chances for bugs.
---
### 2. Understanding ArrayBufferLike Structures and Uint8Array
Before diving into the utilities, it is essential to understand the primary data structures:
- **ArrayBuffer:** A generic, fixed-length binary data buffer. It is the raw data container for typed arrays.
- **Uint8Array:** A typed array that represents an array of 8-bit unsigned integers. It offers a convenient way to work with binary data and is often used to interact with ArrayBuffer.
Operations like converting an image from a server, parsing binary protocols, or even handling cryptographic data require reliable manipulation of these structures. The challenge often lies in converting them into readable formats such as Base64 strings or validating them under various runtime environments.
---
### 3. Overview of @push.rocks/smartbuffer Functions
At its core, @push.rocks/smartbuffer provides several utilities:
- **uInt8ArrayToBase64(uInt8Array: Uint8Array): string**
Converts a Uint8Array to its Base64 encoded string representation.
- **base64ToUint8Array(base64: string): Uint8Array**
Converts a Base64 string back into a Uint8Array, facilitating data transformations between different formats.
- **isBufferLike(obj: any): obj is ArrayBufferLike | Buffer**
Validates if the provided object qualifies as a buffer-like entity. This function checks whether the object has the required byteLength property and, when applicable, additional Node.js Buffer validations.
- **ensurePureUint8Array(bufferArg: Uint8Array | Buffer): Uint8Array**
Returns a new Uint8Array that is a copy of the provided buffer-like object. This function ensures that the returned data is a “pure” Uint8Array, free from any underlying references that might interfere during further operations.
- **uInt8ArrayExtras (as part of the plugins export)**
Offers additional utility methods from the uint8array-extras module. These methods might include extra functionalities for conversion, manipulation, or any niche operations developers require when dealing with typed arrays.
Let's now delve into each function with full, detailed examples to show how these can be used in real-world applications.
---
### 4. Converting Uint8Array Data to Base64
One of the most frequently encountered requirements in data transformation is encoding binary data into a Base64 string. Base64 encoding is used widely for transmitting binary data over channels that only support textual data formats (e.g., JSON, HTML forms).
Lets see a detailed example of how to perform this conversion.
#### Basic Conversion Example
In this simple example, we create an instance of Uint8Array with a few sample bytes and convert them into a Base64 string.
```typescript
import { uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
const sampleBytes = new Uint8Array([72, 101, 108, 108, 111]); // Represents the string "Hello"
const base64String: string = uInt8ArrayToBase64(sampleBytes);
console.log('Base64 String:', base64String);
```
In this case, the output is a Base64 encoded representation of the bytes that constitute the word “Hello”. This functionality is especially useful when you need to embed binary data, such as small images or file fragments, directly into JSON or HTML.
#### Converting Large Data Blocks
Handling large blocks of data requires consideration for performance. The smartbuffer library is designed to perform these operations efficiently, even when the data length is significant.
```typescript
import { uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
function convertLargeDataBlock(): void {
// Create a large Uint8Array. Here we simulate data in the range of 1 MB.
const dataLength = 1024 * 1024;
const largeData = new Uint8Array(dataLength);
// Populate with random data
for (let i = 0; i < largeData.length; i++) {
largeData[i] = Math.floor(Math.random() * 256);
}
const base64Data = uInt8ArrayToBase64(largeData);
console.log('Large Data Base64:', base64Data.substring(0, 100) + '...'); // Display only a snippet
}
convertLargeDataBlock();
```
This example demonstrates how to handle large Uint8Array objects with ease. Note that printing the entire Base64 string might not be feasible if youre dealing with huge data, so consider operating on slices or summaries for logging and debugging purposes.
#### Handling Errors Gracefully
When working with binary data, its vital to add error handling to capture invalid inputs. Although the conversion utility is straightforward, defensive programming practices are encouraged.
```typescript
import { uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
function safeUint8ArrayToBase64(input: any): void {
try {
if (!(input instanceof Uint8Array)) {
throw new Error('Invalid input: Expected Uint8Array.');
}
const base64 = uInt8ArrayToBase64(input);
console.log('Encoded Base64:', base64);
} catch (error) {
console.error('Conversion error:', error);
}
}
// Testing valid input
safeUint8ArrayToBase64(new Uint8Array([1, 2, 3, 4]));
// Testing invalid input
safeUint8ArrayToBase64({ notAnArray: true });
```
In this snippet, we perform a type check before processing and catch any exceptions that might arise from an invalid input. This provides a robust safeguard for operators in a production environment.
---
### 5. Converting Base64 Strings to Uint8Array
The reverse operation, converting a Base64 string to a Uint8Array, is just as important. This conversion becomes essential when receiving binary data encoded as strings over networks, or stored in textual storage formats.
#### Basic Decoding Example
Heres a simple example showing how to decode a Base64 string back to a byte array:
```typescript
import { base64ToUint8Array } from '@push.rocks/smartbuffer';
const sampleBase64 = "SGVsbG8="; // Base64 encoded "Hello"
const byteArray: Uint8Array = base64ToUint8Array(sampleBase64);
console.log('Decoded Uint8Array:', byteArray);
```
This command decodes the Base64 string into a Uint8Array that represents the word “Hello”. The utility offloads all the complexities of mapping each Base64 character back into binary form, ensuring that developers can quickly perform these conversions.
#### Decoding Complex Data
Imagine a scenario where you receive a payload containing an image encoded in Base64 from an API. You need to decode it and generate a Blob object to display the image in a browser:
```typescript
import { base64ToUint8Array } from '@push.rocks/smartbuffer';
async function displayImageFromBase64(base64String: string): Promise<void> {
const uint8Array: Uint8Array = base64ToUint8Array(base64String);
// Create a Blob from the Uint8Array. Adjust the MIME type according to your data.
const imageBlob: Blob = new Blob([uint8Array], { type: 'image/png' });
// Generate a temporary URL for the Blob
const imageUrl: string = URL.createObjectURL(imageBlob);
// Assume there is an image element with ID 'displayImage' in your HTML
const imgElement: HTMLImageElement | null = document.getElementById('displayImage') as HTMLImageElement;
if (imgElement) {
imgElement.src = imageUrl;
}
console.log('Image URL:', imageUrl);
}
const sampleImageBase64 = "iVBORw0KGgoAAAANSUhEUgAA..."; // A truncated Base64 PNG string
displayImageFromBase64(sampleImageBase64);
```
This function demonstrates how to convert Base64 data to a format that can be rendered in a web browser. The process includes decoding the Base64 string, wrapping the resulting Uint8Array in a Blob, and then using a URL.createObjectURL to generate a URL that the <img> tag can consume. Such a sequence is common when dealing with image data received from various APIs or databases.
#### Error Handling in Decoding
As with encoding, you should always ensure that the Base64 string you receive is properly formatted:
```typescript
import { base64ToUint8Array } from '@push.rocks/smartbuffer';
function safeBase64ToUint8Array(input: any): void {
try {
if (typeof input !== 'string') {
throw new Error('Invalid input: Expected a string.');
}
const uint8Array = base64ToUint8Array(input);
console.log('Successfully decoded Uint8Array:', uint8Array);
} catch (error) {
console.error('Decoding error:', error);
}
}
// Testing with a valid Base64 string
safeBase64ToUint8Array("SGVsbG8=");
// Testing with invalid input
safeBase64ToUint8Array(12345);
```
This pattern ensures that your application handles anomalies gracefully and provides useful debug messages, which are essential for maintaining robust data pipelines.
---
### 6. Validating Buffer-like Objects
In JavaScript, data structures are not always guaranteed to conform to ArrayBuffer or typed array standards. Your application might encounter objects that are “buffer-like” (i.e., they have a byteLength property) even if they are not proper ArrayBuffer instances. The isBufferLike function in @push.rocks/smartbuffer is designed to validate these objects.
#### Recognizing Valid Buffer-like Objects
The function isBufferLike performs several checks:
- It confirms the object has a numeric byteLength property.
- On Node.js environments, it checks if the object qualifies as a Buffer using Buffer.isBuffer.
Below is a simple demonstration:
```typescript
import { isBufferLike } from '@push.rocks/smartbuffer';
const validBuffer: ArrayBuffer = new ArrayBuffer(16);
const validUint8Array: Uint8Array = new Uint8Array(validBuffer);
console.log('Is ArrayBuffer valid?:', isBufferLike(validBuffer)); // Expected: true
console.log('Is Uint8Array valid?:', isBufferLike(validUint8Array)); // Expected: true
// Simulate invalid object
const invalidBuffer = { someProperty: 'Not a buffer' };
console.log('Is invalid object buffer-like?:', isBufferLike(invalidBuffer)); // Expected: false
```
#### Cross-Environment Considerations
When developing for both Node.js and the browser, ensuring that an object is truly buffer-like comes with subtle differences. The function abstracts away these differences, making the following examples work seamlessly across platforms:
```typescript
import { isBufferLike } from '@push.rocks/smartbuffer';
function processBuffer(input: any): void {
if (!isBufferLike(input)) {
console.error('Provided input is not a valid buffer-like object.');
return;
}
// Process a valid buffer here safely
console.log('Processing valid buffer-like data.');
}
// Testing in multiple scenarios
const sampleArrayBuffer = new ArrayBuffer(8);
const sampleUint8Array = new Uint8Array(sampleArrayBuffer);
processBuffer(sampleArrayBuffer);
processBuffer(sampleUint8Array);
processBuffer({ random: 123 });
```
This approach ensures you never inadvertently pass an invalid object to functions that require binary data, thus preventing runtime errors and memory issues.
---
### 7. Ensuring Data Purity with ensurePureUint8Array
In many cases, especially when received from servers or buffers provided by external modules, data might not be in a "pure" Uint8Array form. The ensurePureUint8Array function guarantees that you operate on a fresh Uint8Array, ensuring no side effects or shared references can corrupt your data.
#### Example of Purifying Data
This utility comes in handy when you're unsure about the input data type:
```typescript
import { ensurePureUint8Array } from '@push.rocks/smartbuffer';
function processData(buffer: Uint8Array | Buffer): void {
// Ensure that we work with a pure Uint8Array to avoid unintended mutations
const pureArray = ensurePureUint8Array(buffer);
// Proceed with operations on pureArray
console.log('Data length:', pureArray.length);
}
// Example usage with a Uint8Array
const dataUint8 = new Uint8Array([10, 20, 30, 40]);
processData(dataUint8);
// Example usage with a Buffer (in Node.js environments)
// Uncomment the following lines if you are testing in a Node.js environment where Buffer is defined.
// const nodeBuffer = Buffer.from([50, 60, 70, 80]);
// processData(nodeBuffer);
```
This function creates a new Uint8Array and copies the contents from the input buffer. It helps in scenarios where mutating the original buffer might have unintended consequences, or if the input buffer is a Node.js Buffer while your subsequent operations expect a Uint8Array instance.
#### Discussion of Underlying Mechanics
The ensurePureUint8Array function works by:
1. Determining the length of the input buffer.
2. Creating a new Uint8Array with the same length.
3. Copying the content over using the set method.
4. Returning the new, independent array.
This process ensures that even if the original buffer is modified later (for example, through shared state between functions), your operations remain isolated and consistent.
---
### 8. Working with Extended Utilities from uint8array-extras
The @push.rocks/smartbuffer module re-exports a collection of extended functions from the uint8array-extras module. These extra utilities might include methods for additional encoding/decoding schemes, byte-level manipulations, or other niche operations which complement the basic functionalities provided.
#### Importing and Using uInt8ArrayExtras
After installing the package, you can access the extra utilities as follows:
```typescript
import { uInt8ArrayExtras } from '@push.rocks/smartbuffer';
// Example use of a hypothetical utility method provided by uInt8ArrayExtras.
// Assume uint8ArrayExtras provides a method named reverseBytes.
const sampleArray = new Uint8Array([1, 2, 3, 4, 5]);
// Check if the method exists and perform additional operations:
if (uInt8ArrayExtras.reverseBytes) {
const reversedArray = uInt8ArrayExtras.reverseBytes(sampleArray);
console.log('Reversed Array:', reversedArray);
} else {
console.warn('The reverseBytes utility is not available.');
}
// Additionally, you can use other string conversion helpers if available.
if (uInt8ArrayExtras.someUtilityMethod) {
console.log(uInt8ArrayExtras.someUtilityMethod(sampleArray));
}
```
While the example uses a hypothetical "reverseBytes" function, it effectively demonstrates how you can integrate additional utilities into your workflow. Always refer to the latest documentation of uint8array-extras for the currently supported function set.
#### Enhancing Data Manipulation with Extended Utilities
Developers dealing with highly specialized binary protocols can benefit from advanced operations like slicing, merging different Uint8Arrays, or applying transformations on the fly. For example:
```typescript
import { uInt8ArrayExtras } from '@push.rocks/smartbuffer';
function mergeDataFragments(fragments: Uint8Array[]): Uint8Array {
let totalLength = fragments.reduce((sum, frag) => sum + frag.length, 0);
const mergedArray = new Uint8Array(totalLength);
let offset = 0;
for (const fragment of fragments) {
mergedArray.set(fragment, offset);
offset += fragment.length;
}
return mergedArray;
}
const fragment1 = new Uint8Array([10, 20]);
const fragment2 = new Uint8Array([30, 40, 50]);
const fragment3 = new Uint8Array([60]);
const completeData = mergeDataFragments([fragment1, fragment2, fragment3]);
console.log('Merged Uint8Array:', completeData);
```
This example, though independent of the uInt8ArrayExtras utilities, shows how you can combine the extended functionalities and custom implementations to manage complex data scenarios efficiently.
---
### 9. Handling Edge Cases and Error Checking
When working with conversions and buffer validations, it is beneficial to understand and plan for edge cases. Incorrect or unexpected input could lead to exceptions, unhandled rejections, or corrupted data flows. Below are detailed examples of error handling and other defensive programming techniques.
#### Example: Dealing with Null or Undefined Inputs
```typescript
import { uInt8ArrayToBase64, base64ToUint8Array, isBufferLike } from '@push.rocks/smartbuffer';
function processInput(input: any): void {
if (input == null) {
console.error('Input is null or undefined.');
return;
}
if (isBufferLike(input)) {
// Try converting buffer-like object to Base64 if applicable.
try {
// Assuming input is a valid Uint8Array
const base64Encoded = uInt8ArrayToBase64(new Uint8Array(input as ArrayBuffer));
console.log('Safe conversion to Base64:', base64Encoded);
} catch (e) {
console.error('Error during conversion:', e);
}
} else if (typeof input === 'string') {
try {
// Process as Base64
const data = base64ToUint8Array(input);
console.log('Converted Base64 to Uint8Array:', data);
} catch (e) {
console.error('Error decoding Base64 string:', e);
}
} else {
console.warn('Unhandled type of input:', input);
}
}
// Testing with various edge cases
processInput(undefined);
processInput(null);
processInput("InvalidBase64Data***");
processInput(new ArrayBuffer(10));
```
In this sample, different types of input are managed carefully. The function checks for null or undefined, verifies if the input is buffer-like, and takes the appropriate conversion path while catching errors.
#### Example: Robust Type Checking
For robust data conversion, verifying input types can pre-empt many runtime errors. The following example creates a type guard and leverages it to safely process binary data:
```typescript
import { isBufferLike, uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
function safeProcessBuffer(input: unknown): void {
if (isBufferLike(input)) {
const uint8array = input instanceof Uint8Array ? input : new Uint8Array(input as ArrayBuffer);
try {
const encoded = uInt8ArrayToBase64(uint8array);
console.log('Encoded safely:', encoded);
} catch (err) {
console.error('Error encoding buffer:', err);
}
} else {
console.error('Input is not buffer-like. Skipping processing.');
}
}
safeProcessBuffer(new ArrayBuffer(8));
safeProcessBuffer({ byteLength: 8 });
```
This pattern helps ensure that your applications core logic remains robust and impervious to malformed data. In mission-critical systems, such defensive practices can greatly reduce bugs and production issues.
---
### 10. Integrating smartbuffer into Real-World Applications
Applications that process binary data often incorporate several of the functions we have reviewed. Below are scenarios illustrating how to integrate smartbuffer into complex and real-world systems.
#### Scenario 1: File Upload and Processing in a Web Application
Suppose you are building a web application where users can upload images. Once an image is uploaded, you need to:
- Read the file as an ArrayBuffer.
- Convert it into a Base64 string to store temporarily or transfer via JSON.
- Validate and potentially adjust the binary data.
- Present the image back to the user via a Blob URL.
Below is a comprehensive TypeScript example illustrating this process:
```typescript
import { base64ToUint8Array, uInt8ArrayToBase64, isBufferLike, ensurePureUint8Array } from '@push.rocks/smartbuffer';
async function handleFileUpload(file: File): Promise<void> {
// Step 1: Read file as ArrayBuffer
const fileBuffer: ArrayBuffer = await file.arrayBuffer();
// Step 2: Create a Uint8Array from the ArrayBuffer
const fileUint8Array = new Uint8Array(fileBuffer);
// Step 3: Validate the buffer-like object
if (!isBufferLike(fileUint8Array)) {
console.error('Uploaded file is not a valid buffer-like object.');
return;
}
// Step 4: Convert the Uint8Array to a Base64 string for potential storage/transmission
const base64Representation = uInt8ArrayToBase64(fileUint8Array);
console.log('Base64 representation of the file:', base64Representation.substring(0, 100) + '...');
// Step 5: Use ensurePureUint8Array to create a copy we can safely manipulate
const pureUint8Array = ensurePureUint8Array(fileUint8Array);
// Step 6: Create a Blob object from the pure data
const imageBlob = new Blob([pureUint8Array], { type: file.type });
// Step 7: Create a URL for the Blob and set it to an image element for preview
const imageUrl = URL.createObjectURL(imageBlob);
const imageElement = document.getElementById('previewImage') as HTMLImageElement;
if (imageElement) {
imageElement.src = imageUrl;
}
}
// Example integration with an input element
const fileInputElement = document.getElementById('fileInput') as HTMLInputElement;
if (fileInputElement) {
fileInputElement.addEventListener('change', (event: Event) => {
const target = event.target as HTMLInputElement;
if (target.files && target.files.length > 0) {
handleFileUpload(target.files[0]).catch((error) => {
console.error('Error handling file upload:', error);
});
}
});
}
```
In this integration example, each function from @push.rocks/smartbuffer plays a critical role in ensuring that file data is processed reliably. The data is validated, converted, and then safely reassembled into a format that is both easy to work with and compatible with web standards.
#### Scenario 2: Network Communication and Data Serialization
In a server-client application, binary data must often be serialized for network transmission. Using smartbuffer, you can serialize data into Base64 strings and then deserialize it on the other end.
```typescript
import { base64ToUint8Array, uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
// Function sending binary data over HTTP as a JSON payload
async function sendBinaryData(url: string, binaryData: Uint8Array): Promise<void> {
const base64Payload = uInt8ArrayToBase64(binaryData);
const jsonPayload = JSON.stringify({ data: base64Payload });
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: jsonPayload,
});
console.log('Response status:', response.status);
}
// Function receiving the JSON payload and converting it back to binary data
async function receiveBinaryData(response: Response): Promise<Uint8Array> {
const json = await response.json();
return base64ToUint8Array(json.data);
}
// Example usage during API communication
(async () => {
const serverUrl = 'https://api.example.com/upload';
const sampleData = new Uint8Array([100, 101, 102, 103, 104]); // Sample binary payload
await sendBinaryData(serverUrl, sampleData);
})();
```
This snippet outlines how to convert binary data into a Base64 representation, encapsulate it within a JSON payload, and later decode that payload back into a usable Uint8Array. This is particularly useful when binary data must be transmitted via WebSockets or RESTful APIs that expect text-based data.
#### Scenario 3: Data Processing in Node.js
In a Node.js environment, you might need to work directly with Node Buffers, but still want to ensure compatibility with operations that expect Uint8Array. The following example demonstrates such interoperability:
```typescript
import { ensurePureUint8Array, isBufferLike, uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
import { readFile } from 'fs/promises';
async function processLocalFile(filePath: string): Promise<void> {
try {
// Reading a file returns a Node.js Buffer
const fileBuffer = await readFile(filePath);
// Validate that fileBuffer is a buffer-like object
if (!isBufferLike(fileBuffer)) {
throw new Error('The file is not a valid buffer-like object.');
}
// Convert Buffer to a pure Uint8Array to ensure consistency
const pureArray = ensurePureUint8Array(fileBuffer);
// Now convert the pure Uint8Array to a Base64 encoded string
const base64Data = uInt8ArrayToBase64(pureArray);
console.log('File in Base64 format:', base64Data.substring(0, 100) + '...');
} catch (error) {
console.error('Error processing file:', error);
}
}
processLocalFile('./assets/sample.bin');
```
This code snippet illustrates the interoperability when you work with Node.js Buffers. The use of ensurePureUint8Array ensures that regardless of the underlying Buffers characteristics, your data pipeline remains consistent with typed arrays.
---
### 11. Performance Considerations and Best Practices
When processing binary data—especially in performance-critical applications—it is essential to consider both speed and memory overhead. Here are some best practices when using @push.rocks/smartbuffer:
1. Always validate your inputs using isBufferLike before performing conversions.
2. Use ensurePureUint8Array to break any shared references. This prevents side effects if the original data changes unexpectedly.
3. For large data blocks, try processing data in chunks to avoid exhausting memory.
4. When converting between representations (e.g., Base64 to Uint8Array), prefer stream-based approaches if your runtime supports them.
5. Monitor performance when using utility functions from uint8array-extras, as some extended operations might introduce overhead in critical sections of your application.
#### Memory Management Example
Consider the scenario where you need to process large binary files. Instead of loading the entire file into memory, you could process it in manageable chunks:
```typescript
import { uInt8ArrayToBase64 } from '@push.rocks/smartbuffer';
async function processLargeFileInChunks(file: File): Promise<void> {
const chunkSize = 1024 * 64; // 64KB per chunk
const fileSize = file.size;
let offset = 0;
while (offset < fileSize) {
const slice = file.slice(offset, offset + chunkSize);
const arrayBuffer = await slice.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
// Process each chunk by converting to Base64 (or any processing logic)
const base64Chunk = uInt8ArrayToBase64(uint8Array);
console.log(`Processing chunk from offset ${offset}:`, base64Chunk.substring(0, 50) + '...');
offset += chunkSize;
}
}
const fileInput = document.getElementById('largeFileInput') as HTMLInputElement;
if (fileInput) {
fileInput.addEventListener('change', (event: Event) => {
const target = event.target as HTMLInputElement;
if (target.files && target.files.length > 0) {
processLargeFileInChunks(target.files[0])
.catch(err => console.error('Error processing large file:', err));
}
});
}
```
This pattern is useful when dealing with streaming data or very large files, thereby keeping your application responsive.
---
### 12. Comprehensive Code Examples and Use Cases
Below is a complete consolidated example that demonstrates multiple functionalities of @push.rocks/smartbuffer integrated within a single project. The following code snippet simulates a scenario where binary data is received, transformed, validated, and used to generate a visual output on a web page.
```typescript
import {
uInt8ArrayToBase64,
base64ToUint8Array,
isBufferLike,
ensurePureUint8Array,
uInt8ArrayExtras,
} from '@push.rocks/smartbuffer';
// Simulate receiving binary data from an external service.
async function fetchBinaryData(url: string): Promise<Uint8Array> {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
return new Uint8Array(arrayBuffer);
}
// Process the binary data:
// 1. Validate the data.
// 2. Convert to Base64.
// 3. Manipulate using extended utilities.
// 4. Render image on a webpage.
async function processAndRenderImage(url: string): Promise<void> {
try {
const binaryData = await fetchBinaryData(url);
if (!isBufferLike(binaryData)) {
console.error('The fetched data is not buffer-like.');
return;
}
// Convert binary data to Base64
const base64Encoded = uInt8ArrayToBase64(binaryData);
console.log('Encoded data (first 100 chars):', base64Encoded.substring(0, 100) + '...');
// Using the extra utilities (if available, e.g., reversing the byte order)
if (uInt8ArrayExtras && typeof uInt8ArrayExtras.reverseBytes === 'function') {
const reversed = uInt8ArrayExtras.reverseBytes(binaryData);
console.log('Reversed data example:', reversed.slice(0, 10));
}
// Convert the Base64 string back to a Uint8Array
const decodedData = base64ToUint8Array(base64Encoded);
// Ensure we are working with a pure Uint8Array
const cleanedData = ensurePureUint8Array(decodedData);
// Create a Blob from the cleaned data
const imageBlob = new Blob([cleanedData], { type: 'image/jpeg' });
const imageUrl = URL.createObjectURL(imageBlob);
// Create an image element dynamically and attach to the DOM
const imgElement = document.createElement('img');
imgElement.src = imageUrl;
imgElement.alt = 'Processed Image';
imgElement.style.maxWidth = '100%';
document.body.appendChild(imgElement);
console.log('Image rendered successfully.');
} catch (error) {
console.error('Error processing and rendering image:', error);
}
}
// Example usage: Replace the URL below with the path to your binary image data.
processAndRenderImage('https://example.com/path/to/binary/image');
```
This end-to-end example illustrates how you might receive binary data, perform all necessary transformations, and integrate with both network and DOM elements. The modular design of @push.rocks/smartbuffer makes it easy to swap out or extend functionalities as required by your application's evolving needs.
---
### 13. Debugging and Testing Your Implementation
A rigorous testing strategy is essential when working with binary data. Utilize unit tests to verify that:
- Uint8Array conversions maintain data integrity.
- Invalid inputs are correctly rejected.
- Edge cases (such as empty arrays or mismatched encodings) are handled gracefully.
Consider using the testing framework provided by @push.rocks/tapbundle for your unit tests:
```typescript
import { expect, tap } from '@push.rocks/tapbundle';
import {
uInt8ArrayToBase64,
base64ToUint8Array,
isBufferLike,
ensurePureUint8Array,
} from '@push.rocks/smartbuffer';
tap.test('Conversion Integrity Test', async () => {
const original = new Uint8Array([65, 66, 67, 68]); // Represents "ABCD"
const base64Result = uInt8ArrayToBase64(original);
const converted = base64ToUint8Array(base64Result);
// Ensure that the conversion cycle retains all information
expect(converted.length).toBe(original.length);
for (let i = 0; i < original.length; i++) {
expect(converted[i]).toBe(original[i]);
}
});
tap.test('Buffer-like Validation Test', async () => {
const arrayBuffer = new ArrayBuffer(10);
const uint8Array = new Uint8Array(arrayBuffer);
expect(isBufferLike(arrayBuffer)).toBe(true);
expect(isBufferLike(uint8Array)).toBe(true);
expect(isBufferLike({ random: true })).toBe(false);
});
tap.start();
```
These tests help ensure that your implementations using smartbuffer behave as expected and provide a reliable safety net during development and continuous integration.
---
### 14. Advanced Topics and Future Directions
As you integrate @push.rocks/smartbuffer into your projects, you might uncover advanced scenarios that require additional considerations. Below are several advanced topics and suggestions for extending the functionality within your own environment:
#### Custom Conversions and Interoperability
Developers may wish to implement custom conversion routines that go beyond standard Base64 encoding. For example, you might need to support URL-safe Base64 variants or other encoding schemes (e.g., hexadecimal). You can achieve this by combining smartbuffer utilities with additional libraries—enhancing your data pipeline without losing the core benefits of validated conversions and pure typed arrays.
#### Integration with WebAssembly
When performance is paramount, especially for data-intensive tasks, consider offloading certain conversion routines to WebAssembly. Using WebAssembly modules alongside smartbuffer can greatly boost performance when processing large volumes of binary data.
#### Extending uInt8ArrayExtras
The exported uInt8ArrayExtras module from smartbuffer is a gateway to several advanced typed array operations. Future development might include new methods for handling compression, encryption, or even more complex transformations. Contributing to and extending these utilities can be a path for collaborative development in your team.
#### Debugging Binary Data
Tools like hex editors or custom debugging utilities can be integrated into your development workflow. By converting Uint8Arrays into human-readable formats (such as formatted hexadecimal strings), you can enhance your ability to detect subtle errors in data streams. Consider adding helper functions to your project that utilize smartbuffer's conversion methods as a starting point for deeper diagnostics.
#### Cross-Platform Considerations
Different runtime environments handle binary data in subtly different ways. While smartbuffer abstracts many of these differences, be mindful when sharing data between web browsers, Node.js backends, or even mobile platforms. Rigorous cross-platform testing is advisable when deploying applications that heavily rely on binary data transformations.
#### Scalability and Efficiency
As your application scales, efficiency in data processing becomes critical. Measure performance impacts when converting very large arrays or processing frequent network messages. Profiling your code and leveraging asynchronous operations where necessary can prevent bottlenecks in production systems.
---
### Detailed Walkthrough of Advanced Use Cases
To further extend our discussion, below is an in-depth analysis of a complex use case where multiple functionalities of smartbuffer are integrated into a single workflow.
Imagine you are designing a real-time collaborative whiteboard application. This web application communicates with a server via WebSockets. Binary data representing drawing actions (e.g., strokes, shapes, colors) are transmitted between clients and the server. For performance and security reasons, the drawing data are encoded in Base64 format for transmission and immediately decoded on the client side to update the drawing canvas.
#### Step-by-Step Process
1. The client collects drawing actions which are stored in a sequence of Uint8Arrays.
2. Prior to transmission, these Uint8Arrays are converted to a Base64 string using uInt8ArrayToBase64.
3. The data is then packaged into a JSON payload and sent over a WebSocket connection.
4. Upon receiving the message, the client's application uses base64ToUint8Array to decode the string back to its binary form.
5. The decoded data is validated using isBufferLike.
6. The drawing actions are then applied to the collaborative canvas.
##### Client-Side Implementation Example
```typescript
import {
uInt8ArrayToBase64,
base64ToUint8Array,
isBufferLike,
ensurePureUint8Array
} from '@push.rocks/smartbuffer';
// Function to prepare drawing data for sending
function prepareDrawingData(drawingActions: Uint8Array[]): string {
const mergedData = drawingActions.reduce((acc, curr) => {
const temp = new Uint8Array(acc.length + curr.length);
temp.set(acc, 0);
temp.set(curr, acc.length);
return temp;
}, new Uint8Array());
return uInt8ArrayToBase64(mergedData);
}
// Function to process received drawing data
function processReceivedData(base64Data: string): void {
const decodedArray = base64ToUint8Array(base64Data);
if (!isBufferLike(decodedArray)) {
console.error('Received drawing data is not valid.');
return;
}
const pureArray = ensurePureUint8Array(decodedArray);
// Interpret the pureArray data as drawing actions
// (For demonstration, we simply log the extracted values)
console.log('Received drawing actions:', pureArray);
// In a real scenario, further logic will convert the pureArray into actionable drawing commands
}
// Simulated WebSocket message handling
function simulateWebSocket(): void {
// Example drawing actions as Uint8Array fragments
const action1 = new Uint8Array([1, 50, 100]);
const action2 = new Uint8Array([2, 150, 200]);
// Client encodes drawing actions before sending
const encodedMessage = prepareDrawingData([action1, action2]);
console.log('Encoded drawing data for transmission:', encodedMessage.substring(0, 100) + '...');
// Simulate receiving the same message
processReceivedData(encodedMessage);
}
simulateWebSocket();
```
#### Discussion
- In this detailed example, we see how the merging of Uint8Array fragments is handled seamlessly.
- The encoded message, a Base64 string, ensures that the data transmitted over the WebSocket is text-safe.
- On reception, a series of validations and transformations convert the message back into actionable data.
- This modular design allows for easy replacement or extension of each step, enabling future improvements such as compression or encryption.
---
### Summing Up the Extensive Usage Details
The comprehensive examples described above demonstrate the many capabilities of @push.rocks/smartbuffer. They range from simple data conversions to intricate workflows involving network data transmission and real-time application updates. Each function provided by the module plays a specific role in ensuring that binary data is handled efficiently, accurately, and securely.
By adopting these utilities, you can focus your development efforts on business logic and application features rather than the intricacies of binary data manipulation. The modules robust error handling, logging, and defensive design patterns help mitigate common pitfalls related to low-level data processing.
We encourage developers to integrate these techniques and adjust them according to their unique requirements. Whether you are processing image uploads, handling real-time data from a collaborative app, or simply managing buffer validations, @push.rocks/smartbuffer offers a versatile toolkit that promises reliability and performance across various environments.
Throughout this detailed guide, we have explored every critical aspect of working with ArrayBufferLike structures—from encoding to validation, handling large data sets, interoperating between different runtime environments, and even integrating helper functionalities that push the boundaries of typical binary data handling in TypeScript.
As you incorporate these practices into your applications, you will find that adhering to robust conversion patterns and thorough validation not only improves the reliability of your codebase but also simplifies maintenance and future feature expansion.
Happy coding and exploring the many advanced aspects of binary data manipulation with @push.rocks/smartbuffer!
## License and Legal Information
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
### Company Information
Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

21
test/test.both.ts Normal file

@ -0,0 +1,21 @@
import { expect, expectAsync, tap } from '@push.rocks/tapbundle';
import * as smartbuffer from '../ts/index.js';
tap.test('first test', async () => {
console.log(smartbuffer);
});
tap.test('should recognize different buffer like objects', async () => {
// const testBuffer = Buffer.from('test');
const testArrayBuffer = new ArrayBuffer(4);
const testUint8Array = new Uint8Array(testArrayBuffer);
testUint8Array[0] = 116;
testUint8Array[1] = 101;
testUint8Array[2] = 115;
testUint8Array[3] = 116;
// expect(smartbuffer.isBufferLike(testBuffer)).toBeTrue();
expect(smartbuffer.isBufferLike(testArrayBuffer)).toBeTrue();
expect(smartbuffer.isBufferLike(testUint8Array)).toBeTrue();
});
tap.start();

@ -1,8 +0,0 @@
import { expect, expectAsync, tap } from '@pushrocks/tapbundle';
import * as smartbuffer from '../ts/index.js';
tap.test('first test', async () => {
console.log(smartbuffer);
});
tap.start();

@ -1,8 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@pushrocks/smartbuffer',
version: '1.0.2',
description: 'handle ArrayBufferLike structures'
name: '@push.rocks/smartbuffer',
version: '3.0.5',
description: 'A robust TypeScript library for managing binary data by converting between Base64 strings and Uint8Array, validating buffer-like objects, and ensuring data purity.'
}

@ -1,3 +1,38 @@
import * as plugins from './smartbuffer.plugins.js';
export let demoExport = 'Hi there! :) This is an exported string';
export const uInt8ArrayExtras = plugins.uInt8ArrayExtras;
export function uInt8ArrayToBase64(uInt8Array: Uint8Array): string {
return plugins.uInt8ArrayExtras.uint8ArrayToBase64(uInt8Array);
}
export function base64ToUint8Array(base64: string): Uint8Array {
return plugins.uInt8ArrayExtras.base64ToUint8Array(base64);
}
export const isUint8Array = (obj: any): obj is Uint8Array => {
return plugins.uInt8ArrayExtras.isUint8Array(obj);
};
export function isBufferLike(obj: any): obj is ArrayBufferLike | Buffer {
// Check for ArrayBufferLike objects in any environment
if (obj && typeof obj.byteLength === 'number') {
return true;
}
// Additional check specific to Node.js environment for Buffer objects
if (typeof Buffer !== 'undefined' && Buffer.isBuffer) {
return Buffer.isBuffer(obj);
}
return false;
}
export function ensurePureUint8Array(bufferArg: Uint8Array | Buffer): Uint8Array {
// Create a new Uint8Array with the same length as the buffer
const uint8Array: Uint8Array = new Uint8Array(bufferArg.length);
// Copy the contents of the Buffer to the new Uint8Array
uint8Array.set(bufferArg);
return uint8Array;
}

@ -1,2 +1,5 @@
const removeme = {};
export { removeme };
import * as uInt8ArrayExtras from 'uint8array-extras';
export {
uInt8ArrayExtras,
}

@ -3,7 +3,12 @@
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "nodenext"
}
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true
},
"exclude": [
"dist_*/**/*.d.ts"
]
}