A lightweight TypeScript library for basic data management.
npm install @typescript-package/data
[![npm version][typescript-package-npm-badge-svg]][typescript-package-npm-badge]
[![GitHub issues][typescript-package-badge-issues]][typescript-package-issues]
[![GitHub license][typescript-package-badge-license]][typescript-package-license]
A lightweight TypeScript library for basic data management.
- Shape: The shape of all data objects as interface.
- Immutability: Instance methods to freeze, seal, and lock to enforce the data immutability, or determine the state.
- Asynchronous: Synchronous by default, supports switching to asynchronous via the generic variable R switchable by async param.
- Core: The core abstract implementation build on shape providing standard mutation methods clear, destroy, and set.
- Adapter: Extensible adapter abstraction for the pluggable adapters to customize data logic, hooks and side effects.
- Base: The base abstraction layer combining adapter with direct value handling.
- Concrete: Final concrete implementation to instantiate base functionality.
- Installation
- Api
- Abstract
- AdapterData
- BaseData
- DataCore
- Immutability
- Concrete
- Data
- Immutability
- Sealed
- Frozen
- Locked
- Contributing
- Support
- Code of Conduct
- Git
- Commit
- Versioning
- License
``bash`
npm install @typescript-package/data --save-peer
`typescript`
import {
// Abstract.
AdapterData,
BaseData,
DataCore,
Immutability,
// Concrete.
Data,
} from '@typescript-package/data';
The abstract AdapterData class extends DataCore adding functionality for managing data value by adapter with arbitrary arguments.
Designed to create data containers managed by adapters that require constructor arguments.
`typescript
import { AdapterData } from '@typescript-package/data';
import { DataAdapter } from "@typedly/data";
// Create example classes extending AdapterData
export class AnyCollectionData<
T,
E = unknown,
R extends boolean = false,
A extends DataAdapter
> extends AdapterData
constructor(async: R, adapter: {new (...args: E[]): A}, ...elements: E[]) {
super(async, adapter, ...elements);
}
}
// Create the adapter implementation of DataAdapter interface.
export class AnyCollectionAdapter
#value: Set
constructor(...elements: T[]) {
this.#value = new Set(elements) as Set
}
clear(): this { return this; }
destroy(): this { return this; }
lock(): this { return this; }
set(value: Set
get value(): Set
return this.#value;
}
}
// Create an instance of AnyCollectionData.
// const anyCollectionData: AnyCollectionData
const anyCollectionData = new AnyCollectionData(false, AnyCollectionAdapter, 1, 2, 3);
anyCollectionData.adapter;
// Another example class extending AdapterData but of specific Set type.
export class SetCollectionData<
T,
G extends T[] = T[],
R extends boolean = false,
A extends DataAdapter
> extends AdapterData
constructor(async: R, adapter: {new (...args: G): A}, ...elements: G) {
super(async, adapter, ...elements);
}
}
// Create the adapter implementation of DataAdapter interface for Set type.
export class SetCollectionAdapter
#value: Set
constructor(...elements: T[]) {
this.#value = new Set(elements) as Set
}
clear(): this { return this; }
destroy(): this { return this; }
lock(): this { return this; }
set(value: Set
get value(): Set
return this.#value;
}
}
// Create a new instance of SetCollectionData.
// const collectionData: CollectionData
const setCollectionData = new SetCollectionData(false, SetCollectionAdapter, 1, 2, 3);
// SetCollectionAdapter
setCollectionData.adapter;
`
The BaseData is an abstract class that extends core features, adding functionality for managing the data value directly or through the adapter.
- It represents a data structure that can hold a value of type T and provides methods to manipulate and access that value.
- The class supports the use of adapters for custom data handling and can operate in both synchronous and asynchronous modes based on the generic parameters provided.
`typescript
import { BaseData } from '@typescript-package/data';
import { DataAdapter } from "@typedly/data";
// Create example classes extending BaseData.
export class TestBaseData<
T,
G extends unknown[] = unknown[],
R extends boolean = false,
A extends DataAdapter
// C extends {new (...args: G): DataAdapter
> extends BaseData<
T,
G,
R,
A
// InstanceType
> {
constructor(
async: R,
value: T,
// adapter: C,
adapter: {new (value: T, ...args: G): A} | undefined,
...args: G
) {
super(
async,
value,
// adapter as unknown as new (value: T, ...args: G) => InstanceType
adapter,
...args
);
}
}
// Create the adapter implementation of DataAdapter interface.
export class SetAdapter
#value: T;
constructor(value?: Iterable
this.#value = new Set(value) as T;
}
newMethod() {}
clear(): this { return this; }
destroy(): this { return this; }
lock(): this { return this; }
set(value: T): this { this.#value = value; return this; }
get value(): T {
return this.#value;
}
}
// const setData: TestBaseData
const setData = new TestBaseData(false, new Set('a'), SetAdapter);
// Call new method.
setData.adapter?.newMethod();
// SetAdapter
setData.adapter
`
The core abstraction with immutability for handling data-related classes.
`typescript`
import { DataCore } from '@typescript-package/data';
Manages the immutability states of this current instance.
`typescript`
import { Immutability } from '@typescript-package/data';
The Data class is a concrete implementation that extends the BaseData abstract class, providing instantiable base functionality.
`typescript
import { Data } from '@typescript-package/data';
// Example subclass of Data
class StringData extends Data
constructor(value: string) {
super(false, value);
}
}
const stringData = new StringData("Hello, world!");
// Access the current value
console.log(stringData.value); // ➝ Hello, world!
// Update the value
stringData.set("New value");
console.log(stringData.value); // ➝ New value
// Destroy the value
stringData.destroy();
console.log(stringData.value); // Throws error or undefined (based on how it's handled)
`
Example with adapter to handle the value with onSet hook.
`typescript
import { Data } from '@typescript-package/data';
import { DataAdapter } from '@typedly/data';
// Create the adapter implementation of DataAdapter interface.
export class RxDataAdapter<
T = string,
G extends unknown[] = unknown[]
> implements DataAdapter
#onSet: (value: T) => T = (value: T) => value;
#value: T;
constructor(value: T, ...args: G) {
this.#value = value || '' as T;
console.log(args);
}
// New method specific to this reactive adapter.
onSet(callbackfn: (value: T) => T): this { this.#onSet = callbackfn; return this; }
clear(): this { return this; }
destroy(): this { return this; }
lock(): this { return this; }
set(value: T): this { this.#value = this.#onSet(value); return this; }
get value(): T {
return this.#value;
}
}
// const data: Data
const data = new Data(false, 'Initial value' as string, RxDataAdapter);
data.adapter?.onSet(value => Reactive: ${value});`
data.set('New value'); // logs: 'Reactive: New value'
Example with asynchronous adapter.
`typescript
import { Data } from '@typescript-package/data';
import { DataAdapter } from '@typedly/data';
// Create the Async adapter implementation of DataAdapter interface.
export class AsyncAdapter<
T = string,
G extends unknown[] = unknown[]
> implements DataAdapter
#value: T;
constructor(value: T, ...args: G) {
this.#value = value || '' as T;
console.log(args);
}
async ready(): Promise
async clear(): Promise
async destroy(): Promise
lock(): this { return this; }
async set(value: T): Promise
get value(): T {
return this.#value;
}
}
// const asyncData: Data
const asyncData = new Data(true, 'Initial async value' as string, AsyncAdapter);
asyncData.adapter?.ready().then(value => {
console.log('Async value:', value);
});
`
Provides structural immutability, but not value immutability. The least strict form of immutability.
Sealing an object prevents adding or removing properties, but it does not restrict modifying the values of existing properties.
Provides structural and shallow immutability. Stricter than seal.
Freezing an object prevents changes to the object’s properties at the top level. This means that you cannot modify, add, or delete properties, but nested objects can still be mutated.
Combines the features of freeze, but extends immutability to nested structures(deep immutability).
Locking(deep) an object prevents changing any properties at any level, including properties within nested objects.
Your contributions are valued! If you'd like to contribute, please feel free to submit a pull request. Help is always appreciated.
If you find this package useful and would like to support its and general development, you can contribute through one of the following payment methods. Your support helps maintain the packages and continue adding new.
Support via:
- Stripe
- Revolut
- GitHub
- DonorBox
- Patreon
or via Trust Wallet
- XLM
- USDT (BEP20)
- ETH
- BTC
- BNB
Thanks for your support!
By participating in this project, you agree to follow Code of Conduct.
- [AngularJS Git Commit Message Conventions][git-commit-angular]
- [Karma Git Commit Msg][git-commit-karma]
- [Conventional Commits][git-commit-conventional]
[Semantic Versioning 2.0.0][git-semver]
Given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
FAQ
How should I deal with revisions in the 0.y.z initial development phase?
> The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.
How do I know when to release 1.0.0?
> If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should probably already be 1.0.0.
MIT © typescript-package ([license][typescript-package-license])
| Package | Description |
|---------------------------|---------------------------------------------------|
| @typescript-package/async-data | A lightweight TypeScript library for basic asynchronous data management. |
| @typescript-package/collection | A lightweight TypeScript library for data collection management. |
| @typescript-package/map | A lightweight TypeScript library for enhanced map management. |@typescript-package/set
| | A lightweight TypeScript library for enhanced set management. |@typescript-package/weak-data
| | A lightweight TypeScript library for basic weakly referenced data management. |
- @typescript-package/affix: A lightweight TypeScript library for the affix - prefix and suffix.
- @typescript-package/are: Type-safe are checkers for validating value types in TypeScript.map
- @typescript-package/descriptor: A lightweight TypeScript library for property descriptor.
- @typescript-package/guard: Type-safe guards for guarding the value types in TypeScript.c
- @typescript-package/history: A TypeScript package for tracking history of values.
- @typescript-package/is: Type-safe is checkers for validating value types in TypeScript.
- @typescript-package/map: A lightweight TypeScript library for enhanced management.set` management.
- @typescript-package/name: A lightweight TypeScript library for the name with prefix and suffix.
- @typescript-package/property: A lightweight TypeScript package with features to handle object properties.
- @typescript-package/queue: A lightweight TypeScript library for managing various queue and stack structures.
- @typescript-package/range: A lightweight TypeScript library for managing various types of ranges.
- @typescript-package/regexp: A lightweight TypeScript library for RegExp.
- @typescript-package/set: A lightweight TypeScript library for enhanced
- @typescript-package/state: Simple state management for different types in TypeScript.
- @typescript-package/storage: The storage of data under allowed names.
- @typescript-package/type: Utility types to enhance and simplify TypeScript development.
- @typescript-package/wrapper: A lightweight TypeScript library to wrap the text with the opening and closing chars.
[typescript-package-badge-issues]: https://img.shields.io/github/issues/typescript-package/data
[isscript-package-badge-forks]: https://img.shields.io/github/forks/typescript-package/data
[typescript-package-badge-stars]: https://img.shields.io/github/stars/typescript-package/data
[typescript-package-badge-license]: https://img.shields.io/github/license/typescript-package/data
[typescript-package-issues]: https://github.com/typescript-package/data/issues
[typescript-package-forks]: https://github.com/typescript-package/data/network
[typescript-package-license]: https://github.com/typescript-package/data/blob/master/LICENSE
[typescript-package-stars]: https://github.com/typescript-package/data/stargazers
[typescript-package-npm-badge-svg]: https://badge.fury.io/js/@typescript-package%2Fdata.svg
[typescript-package-npm-badge]: https://badge.fury.io/js/@typescript-package%2Fdata
[git-semver]: http://semver.org/
[git-commit-angular]: https://gist.github.com/stephenparish/9941e89d80e2bc58a153
[git-commit-karma]: http://karma-runner.github.io/0.10/dev/git-commit-msg.html
[git-commit-conventional]: https://www.conventionalcommits.org/en/v1.0.0/