A TypeScript library that provides powerful abstractions for managing asynchronous concurrency, state machines, and completion patterns. It offers type-safe primitives for building concurrent applications with guaranteed completion semantics.
Open interfacenpm install @jonloucks/concurrency-ts
For comprehensive examples and detailed API documentation, see DOCUMENTATION.md.
import { createConcurrency, Waitable, Completable, StateMachine } from '@jonloucks/concurrency-ts';
// Create a Concurrency instance
const concurrency = createConcurrency({});
using closeConcurrency = concurrency.open();
// Create a Waitable for thread-safe value storage
const waitable: Waitable<number> = concurrency.createWaitable({ initialValue: 0 });
using closeWaitable = waitable.open();
waitable.consume(42);
console.log(waitable.supply()); // 42
// Create a Completable to track async operations
const completable: Completable<string> = concurrency.createCompletable({});
using closeCompletable = completable.open();
completable.onCompletion((completion) => {
console.log('Task completed:', completion.state, completion.value);
});
completable.notify({ state: 'SUCCEEDED', value: 'Done!' });
// Create a StateMachine for state management
type AppState = 'IDLE' | 'RUNNING' | 'STOPPED';
const stateMachine: StateMachine<AppState> = concurrency.createStateMachine({
initialValue: 'IDLE',
states: ['IDLE', 'RUNNING', 'STOPPED'],
getStateRules: (state) => {
switch (state) {
case 'IDLE':
return [{ event: 'start', allowedStates: ['RUNNING'] }];
case 'RUNNING':
return [{ event: 'stop', allowedStates: ['STOPPED'] }];
default:
return [];
}
}
});
using closeStateMachine = stateMachine.open();
console.log(stateMachine.getState()); // 'IDLE'
stateMachine.setState('start', 'RUNNING');
console.log(stateMachine.getState()); // 'RUNNING'
See DOCUMENTATION.md for more examples and advanced usage patterns.
npm install
npm run build
npm test
npm run test:watch
npm run test:coverage
npm run lint
npm run lint:fix
npm run docs
npm run badges
concurrency-ts
├── .github
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows
│ ├── main-pull-request-matrix.yml
│ ├── main-pull-request.yml
│ ├── main-push.yml
│ └── main-release.yml
├── CODE_OF_CONDUCT.md
├── CODING_STANDARDS.md
├── CONTRIBUTING.md
├── editorconfig
├── eslint.config.mjs
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── scripts
│ ├── badge-template.svg.dat
│ └── tsconfig.json
├── SECURITY.md
├── src
│ ├── index.ts
│ ├── version.ts
│ ├── api
│ │ ├── *.ts
│ │ ├── *.api.ts
│ ├── auxiliary
│ │ ├── *.ts
│ │ ├── *.impl.ts
│ │ ├── *.test.ts // internal implementation specific
│ │ └── *.api.ts
│ ├── impl
│ │ ├── *.ts
│ │ ├── *.impl.ts
│ │ ├── *.test.ts // internal implementation specific
│ │ └── *.api.ts
│ ├── test
│ │ └── *.test.ts
│ └── never-publish // non shippable development scripts
│ ├── *.ts
│ ├── *.*. // data files etc
│ └── *.test.ts
├── tsconfig.json
└── typedoc.json
The CI workflow runs on every push and pull request to main branch. It:
The GitHub publishings workflows are run to make an official release.
To set up your own publishing:
npm pkg delete private to remove the private flag from the package.name field in package.json to your desired package name.MIT