# Tales

[![npm version](https://img.shields.io/npm/v/@dikolab/tales)](https://www.npmjs.com/package/@dikolab/tales)
[![license](https://img.shields.io/npm/l/@dikolab/tales)](./LICENSE)

Organize scripts based on a high-level Use-case methodology as a startup intent of the package. Additional features will be introduced in upcoming releases.

## Installation

```bash
npm install @dikolab/tales
```

## [Release Notes](docs/release-notes.md)

## Usage

The following sections provide examples of how to declare components of a Use Case and run them.

### Declarations

Defining Boundary and goals

```ts
export const UserDomain = defineScope('Entity:User');

export const UserIsCreated = UserDomain.defineGoal('User is Created');

export const UserHasLoggedIn = UserDomain.defineGoal('User has Logged-in');
```

Defining Use-case

```ts
import { UserDomain } from '../user.domain.ts';
import { UserIsCreated } from '../user.goals.ts';

export const CreateUser = UserDomain.
   as('administrator', 'manager').
   iCan('Create User').
   soThat(UserIsCreated).
   implementedAs(
      (name: string, birthday: Date) => {
         // other processes here...
         return {
            name,
            birthday
         }
      }
   );


```

Defining Actor and roles

```ts
export const Admin = iAm('admin').as(
   // can define 2 or more roles
   'administrator',
   'manager'
);
```

### Execution

Running a Usecase by assuming an Actor

```ts

import { Admin } from './actors/admin.actor.ts';
import { CreateUser } from './user/user-cases/create-user.usecase.ts';

export class SomeUserController {
   async createUser(name: string, birthday: Date): Promise<User> {
      const newUser = await assume(Admin)
         .perform(
            CreateUser,
            name,
            birthday
         );

      // do some side effects here...

      return newUser;
   }
}
```

### Listening to events

You can listen to events by using listen().

```ts
import { listen } from '@dikolab/tales';

import { MakePaymentUsecase } from './payments/usecases/make-payment.usecase.ts';

listen(MakePaymentUsecase, 'perform',
   (result, usecase) => {
      console.log(`Use-case performed successfully: ${usecase}`);
      console.log(`Result is: ${result}`);
   }
);


```


## TODO

1. Implement plugins for flexibility
2. State Management and Store

## License

[ISC](./LICENSE)
