Zajno's re-usable utilities for JS/TS projects
npm install @zajno/common
This is a library with a useful utils/helpers to share across our projects.
The motivation to have this – just to control and organize some shared code that we ever wanted to write by ourselves.
* API: a middle-layer REST API endpoints definition helpers, to have communication described declarative & type-safely.
* Async
* Timeouts: a promisified setTimeout - setTimeoutAsync; timeoutPromise - a promise that rejects after a timeout;
* ManualPromise: a promise that can be resolved/rejected manually;
* Array extensions: someAsync, everyAsync, forEachAsync, mapAsync (previously were Array.prototype extensions);
* Date extensions & helpers: operations with granularity, date formatting etc;
* Period: a structure to work with date periods e.g. 1 day, 5 years etc;
* CalendarIndex: a structure to work with day, week, month indexes;
* Shift dates: shift dates by period, get start/end of with granularity etc;
* Fields: work with object fields: skip/filter falsy, transfer falsy/changed; merge arrays of objects.
* Functions: assert, IDisposable/Disposable/Disposer, DebounceAction/DebounceProcessor.
* Lazy: Lazy (sync), LazyPromise.
* Logger interface & console implementation: create instance of logger, inject your own implementation or globally enable/disable logger instances by calling setMode.
* Math
* General helpers: clamp, round, random, intersections helpers and more;
* Array helpers: compare, max, min, average, count, normalize, shuffle, etc;
* Math Objects helpers: do arithmetical operations on objects with number fields;
* Distribution: simple distribution by a type;
* Models: helpers for moving on towards OOP world.
- EntityWithStatus: a base class for entities with a string status, keeps history of status changes;
- Model: a simple base class (box) for values setter/getter;
- LoadingModel: aggregates multiple loading flags into one;
- LogicModel: a helper base class which helps to run async logic with PromiseExtended (see below);
- various interfaces and helpers for models.
* Observing
- Event: a simple event emitter;
- OneTimeLateEvent: an event emitter that can be listened to after it's been emitted;
- Others: DebouncedEvent, Timer, ProgressTracker and more.
* Storage: abstractions + helpers for sync/async storages;
* Structures
- Path: a helper to build (almost) type-safe dynamic paths (useful for routing definitions);
- Queues: ParallelQueue (helps run & track multiple prioritized async tasks), TasksQueue (a simple queue for async tasks with a limit for concurrent tasks);
- PromiseCache: a cache for Promise'd values; supports TTL, invalidation, custom keys, deferred getters and more;
- PromiseExtended: a Promise wrapper which never rejects but provides onSuccess and onError callbacks;
- PromiseProxy: a Promise wrapper to mimic (fake) a resolved value's properties until it's actually resolved;
- Enum helpers: EnumHelper, EnumStringHelper, EnumBitwiseHelper;
- Misc: Pool, LinkedList, TempoCache (invalidates sync values after a timeout), ExpireTracker, NamesHelper and more.
* Types: DeepReadonly, DeepMutable, DeepPartial, DeepRequired etc., Getter, Ident and various others.
* Validation: abstractions & helpers for validation.
Tests are written with Vitest, coverage is (kinda) tracked with Coveralls. Test coverage is mainly dictated by real-world usage in the projects.
Sources are in TypeScript, shipped as CJS & ESM modules targeted on ES2022.
There's no barrel exports, so you can import each module separately. Each index.ts file is outlined in generated package.json's exports field. Might require tslib as a peer dependency.
The package does't really use semver for now, breaking changes to existing modules can be introduced in minor versions, so it's recommended to use ~ in your package.json's dependencies. New modules can be introduced in minor & patch versions.
1. Install from NPM:
```
npm i @zajno/common
2. In your code, use each module separately:
`typescript`
import logger, { ILogger } from '@zajno/common/logger';
If you plan to update the sources while using it in your project, we'd recommend using yalc. It does some magic to allow both using it in your project and updating it.
The flow will look like the following. [1] – operations made on this project, [2] – operations made on dependant project.
1. install yalc globally[1]
2. fork (if you're outside Zajno) and clone this project, do npm i[1]
3. run yalc publish --private[2]
4. run yalc add @zajno/common && npm i[1]
5. make changes in local copy, run tests etc.[1]
6. run some magic: npm run publish:local – this should deliver your updated copy to local project(s) [2][2]
7. notice the changes in your project, repeat 5-7 until you're done[2]
8. to cleanup, run yalc remove @zajno/common or just yalc remove --all[1]
9. push your changes after making sure it's OK, we'd say thank you for a PR![2]
9. re-add the package into your project or specify tag/commit (e.g. npm upgrade @zajno/common`)