-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# @wroud/preconditions | ||
|
||
[![ESM-only package][package]][esm-info-url] | ||
[![NPM version][npm]][npm-url] | ||
|
||
<!-- [![Install size][size]][size-url] --> | ||
|
||
[package]: https://img.shields.io/badge/package-ESM--only-ffe536.svg | ||
[esm-info-url]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c | ||
[npm]: https://img.shields.io/npm/v/@wroud/preconditions.svg | ||
[npm-url]: https://npmjs.com/package/@wroud/preconditions | ||
[size]: https://packagephobia.com/badge?p=@wroud/preconditions | ||
[size-url]: https://packagephobia.com/result?p=@wroud/preconditions | ||
|
||
@wroud/preconditions is a flexible and extensible library for managing preconditions in JavaScript and TypeScript applications. It simplifies the process of validating and preparing entities (e.g., nodes, connections, features) by providing a robust framework for defining and applying preconditions. | ||
|
||
## Features | ||
|
||
- **Entity-Specific Managers**: Manage preconditions independently for different types of entities. | ||
- **Dynamic Applicability**: Apply preconditions selectively to specific instances based on their data. | ||
- **Extensibility**: Add new preconditions dynamically in a plugin-style manner. | ||
- **Check-Only and Fulfill Modes**: Support both validating preconditions and attempting to fulfill them. | ||
- **TypeScript Support**: Provides strong typing for enhanced developer experience. | ||
- [Pure ESM package][esm-info-url] | ||
|
||
## Installation | ||
|
||
Install via npm: | ||
|
||
```sh | ||
npm install @wroud/preconditions | ||
``` | ||
|
||
Install via yarn: | ||
|
||
```sh | ||
yarn add @wroud/preconditions | ||
``` | ||
|
||
## Documentation | ||
|
||
For detailed usage and API reference, visit the [documentation site](https://wroud.dev). | ||
|
||
## Example | ||
|
||
### Define Your Entities | ||
|
||
```ts | ||
export interface Node { | ||
id: string; | ||
data: { | ||
requiresDatabaseConnection?: boolean; | ||
}; | ||
} | ||
``` | ||
|
||
### Define Preconditions | ||
|
||
```ts | ||
import type { IPrecondition } from "@wroud/preconditions"; | ||
|
||
export class DatabaseConnectionPrecondition implements IPrecondition<Node> { | ||
isApplicable(node: Node): boolean { | ||
return node.data.requiresDatabaseConnection === true; | ||
} | ||
|
||
async check(node: Node): Promise<boolean> { | ||
return databaseConnection.isEstablished(); | ||
} | ||
|
||
async fulfill(node: Node): Promise<void> { | ||
await databaseConnection.connect(); | ||
} | ||
} | ||
``` | ||
|
||
### Set Up a Precondition Manager | ||
|
||
```ts | ||
import { PreconditionManager } from "@wroud/preconditions"; | ||
import { Node } from "./Node"; | ||
import { DatabaseConnectionPrecondition } from "./NodePreconditions"; | ||
|
||
const nodePreconditionManager = new PreconditionManager<Node>(); | ||
nodePreconditionManager.register(new DatabaseConnectionPrecondition()); | ||
``` | ||
|
||
### Check and Fulfill Preconditions | ||
|
||
```ts | ||
const node: Node = { id: "node1", data: { requiresDatabaseConnection: true } }; | ||
|
||
const canLoad = await nodePreconditionManager.checkPreconditions(node); | ||
|
||
if (canLoad) { | ||
console.log("Node can be loaded."); | ||
} else { | ||
try { | ||
await nodePreconditionManager.fulfillPreconditions(node); | ||
console.log("Preconditions fulfilled. Node is ready to load."); | ||
} catch (error) { | ||
console.error("Failed to fulfill preconditions:", error); | ||
} | ||
} | ||
``` | ||
|
||
## Changelog | ||
|
||
All notable changes to this project will be documented in the [CHANGELOG](./CHANGELOG.md) file. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "@wroud/preconditions", | ||
"type": "module", | ||
"sideEffects": [], | ||
"exports": { | ||
".": "./lib/index.js", | ||
"./*": "./lib/*.js" | ||
}, | ||
"scripts": { | ||
"ci:release": "yarn ci release --prefix preconditions-v", | ||
"ci:git-tag": "yarn ci git-tag --prefix preconditions-v", | ||
"ci:release-github": "yarn ci release-github --prefix preconditions-v", | ||
"clear": "rimraf lib", | ||
"build": "tsc -b", | ||
"watch": "tsc -b -w" | ||
}, | ||
"files": [ | ||
"package.json", | ||
"LICENSE", | ||
"README.md", | ||
"CHANGELOG.md", | ||
"lib", | ||
"!lib/**/*.d.ts.map", | ||
"!lib/**/*.test.js", | ||
"!lib/**/*.test.d.ts", | ||
"!lib/**/*.test.d.ts.map", | ||
"!lib/**/*.test.js.map", | ||
"!lib/tests", | ||
"!.tsbuildinfo" | ||
], | ||
"packageManager": "[email protected]", | ||
"devDependencies": { | ||
"@wroud/ci": "workspace:^", | ||
"@wroud/tsconfig": "workspace:^", | ||
"rimraf": "^6", | ||
"typescript": "^5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export interface IPrecondition<T> { | ||
/** | ||
* Determines if this precondition applies to the given data. | ||
* @param data - The data to check applicability for. | ||
* @return {boolean} - True if applicable, false otherwise. | ||
*/ | ||
isApplicable(data: T): boolean; | ||
|
||
/** | ||
* Checks if the precondition is already fulfilled. | ||
* @param data - The data context. | ||
* @return {Promise<boolean>} - Resolves to true if fulfilled, false otherwise. | ||
*/ | ||
check(data: T): Promise<boolean>; | ||
|
||
/** | ||
* Attempts to fulfill the precondition. | ||
* @param data - The data context. | ||
* @return {Promise<void>} | ||
*/ | ||
fulfill(data: T): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import type { IPrecondition } from "./IPrecondition.js"; | ||
|
||
export class PreconditionManager<T> { | ||
private preconditions: IPrecondition<T>[] = []; | ||
|
||
/** | ||
* Registers a new precondition for this entity type. | ||
* @param precondition - The precondition to register. | ||
*/ | ||
public register(precondition: IPrecondition<T>): void { | ||
this.preconditions.push(precondition); | ||
} | ||
|
||
/** | ||
* Checks if all applicable preconditions are fulfilled for the given entity instance. | ||
* @param entity - The entity instance. | ||
* @return {Promise<boolean>} - Resolves to true if all applicable preconditions are fulfilled. | ||
*/ | ||
public async checkPreconditions(entity: T): Promise<boolean> { | ||
for (const precondition of this.getApplicablePreconditions(entity)) { | ||
const isFulfilled = await precondition.check(entity); | ||
if (!isFulfilled) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Attempts to fulfill all applicable preconditions for the given entity instance. | ||
* @param entity - The entity instance. | ||
* @return {Promise<void>} | ||
*/ | ||
public async fulfillPreconditions(entity: T): Promise<void> { | ||
for (const precondition of this.getApplicablePreconditions(entity)) { | ||
const isFulfilled = await precondition.check(entity); | ||
if (!isFulfilled) { | ||
await precondition.fulfill(entity); | ||
} | ||
} | ||
} | ||
|
||
public *getApplicablePreconditions(entity: T): Iterable<IPrecondition<T>> { | ||
for (const precondition of this.preconditions) { | ||
if (precondition.isApplicable(entity)) { | ||
yield precondition; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./IPrecondition.js"; | ||
export * from "./PreconditionManager.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"extends": "@wroud/tsconfig/tsconfig.json", | ||
"compilerOptions": { | ||
"tsBuildInfoFile": "./lib/.tsbuildinfo", | ||
"rootDir": "src", | ||
"rootDirs": [ | ||
"src" | ||
], | ||
"outDir": "lib", | ||
"incremental": true, | ||
"composite": true | ||
}, | ||
"include": [ | ||
"src" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters