Skip to content

Commit

Permalink
feat: add state helper
Browse files Browse the repository at this point in the history
  • Loading branch information
bondiano committed Sep 23, 2023
1 parent ff7f7a2 commit 507432a
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 38 deletions.
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
coverage
docs
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class BaseEntity extends TypeOrmBaseEntity {

@Entity('order')
class Order extends StateMachineEntity({
itemsStatus: {
itemsStatus: state({
id: 'orderItemsStatus',
initial: OrderItemState.draft,
persistContext: true,
Expand Down Expand Up @@ -111,7 +111,7 @@ class Order extends StateMachineEntity({
OrderItemState.delivered,
),
],
},
}),
},
BaseEntity, // It's optional
) {
Expand Down
69 changes: 69 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@commitlint/config-conventional": "^17.7.0",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@swc/core": "^1.3.87",
"@types/better-sqlite3": "^7.6.4",
"@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.4.1",
Expand All @@ -46,6 +47,7 @@
"eslint": "^8.47.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-node": "^0.3.9",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-lodash": "^7.4.0",
"eslint-plugin-node": "^11.1.0",
Expand All @@ -57,7 +59,6 @@
"typedoc": "^0.25.0",
"typedoc-plugin-mermaid": "^1.10.0",
"typescript": "^5.2.2",
"@swc/core": "^1.3.87",
"unplugin-swc": "^1.4.2",
"vitest": "^0.34.5"
},
Expand Down
31 changes: 15 additions & 16 deletions src/__tests__/examples/file-upload.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { Column, DataSource, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
import {
Column,
DataSource,
Entity,
PrimaryGeneratedColumn,
BaseEntity as TypeOrmBaseEntity,
} from 'typeorm';
import { StateMachineEntity,t } from '../..';

import { StateMachineEntity, t, state } from '../..';

/**
* First, user submits a file to the server.
Expand All @@ -28,20 +23,24 @@ enum FileEvent {

@Entity('file')
class File extends StateMachineEntity({
status: {
status: state({
id: 'fileStatus',
initial: FileState.pending,
transitions: [
t(FileState.pending, FileEvent.start, FileState.uploading),
t(FileState.uploading, FileEvent.finish, FileState.completed,{
async onEnter(this: File, _ctx, url: string | null){
t(FileState.uploading, FileEvent.finish, FileState.completed, {
async onEnter(this: File, _context, url: string | null) {
this.url = url;
}
},
}),
t([FileState.pending, FileState.uploading], FileEvent.fail, FileState.failed),
t(
[FileState.pending, FileState.uploading],
FileEvent.fail,
FileState.failed,
),
],
},
}){
}),
}) {
@PrimaryGeneratedColumn()
id: string;

Expand Down Expand Up @@ -82,7 +81,7 @@ describe('File upload', () => {
id,
},
});
}
};

it('should change state', async () => {
const file = new File();
Expand Down
21 changes: 14 additions & 7 deletions src/__tests__/fsm.entity.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { describe, expect, it, vi, afterEach, beforeAll, afterAll } from 'vitest';

import {
Column,
DataSource,
Entity,
PrimaryGeneratedColumn,
BaseEntity as TypeOrmBaseEntity,
} from 'typeorm';
import {
describe,
expect,
it,
vi,
afterEach,
beforeAll,
afterAll,
} from 'vitest';

import { StateMachineEntity, t } from '../';
import { StateMachineEntity, state, t } from '../';

enum OrderState {
draft = 'draft',
Expand Down Expand Up @@ -51,7 +58,7 @@ class BaseEntity extends TypeOrmBaseEntity {
@Entity('order')
class Order extends StateMachineEntity(
{
status: {
status: state({
id: 'orderStatus',
initial: OrderState.draft,
transitions: [
Expand All @@ -60,8 +67,8 @@ class Order extends StateMachineEntity(
t(OrderState.paid, OrderEvent.ship, OrderState.shipped),
t(OrderState.shipped, OrderEvent.complete, OrderState.completed),
],
},
itemsStatus: {
}),
itemsStatus: state({
id: 'orderItemsStatus',
initial: OrderItemState.draft,
persistContext: true,
Expand Down Expand Up @@ -99,7 +106,7 @@ class Order extends StateMachineEntity(
OrderItemState.delivered,
),
],
},
}),
},
BaseEntity,
) {
Expand Down
21 changes: 9 additions & 12 deletions src/fsm.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ type ExtractState<
Column extends keyof Parameters,
> = Parameters[Column] extends IStateMachineEntityColumnParameters<
infer State,
AllowedNames,
object
any,
any
>
? State extends AllowedNames
? State
Expand All @@ -43,9 +43,9 @@ type ExtractEvent<
Parameters extends object,
Column extends keyof Parameters,
> = Parameters[Column] extends IStateMachineEntityColumnParameters<
AllowedNames,
any,
infer Event,
object
any
>
? Event extends AllowedNames
? Event
Expand All @@ -56,8 +56,8 @@ type ExtractContext<
Parameters extends object,
Column extends keyof Parameters,
> = Parameters[Column] extends IStateMachineEntityColumnParameters<
AllowedNames,
AllowedNames,
any,
any,
infer Context
>
? Context extends object
Expand Down Expand Up @@ -183,12 +183,8 @@ function initializeStateMachine<
* }}) {}
*/
export const StateMachineEntity = function <
Parameters extends {
[Column in Columns]: IStateMachineEntityColumnParameters<
AllowedNames,
AllowedNames,
any
>;
const Parameters extends {
[Column in Columns]: IStateMachineEntityColumnParameters<any, any, any>;
},
Entity extends BaseEntity,
const Columns extends keyof Parameters = keyof Parameters,
Expand Down Expand Up @@ -292,6 +288,7 @@ export const StateMachineEntity = function <
return _StateMachineEntity as unknown as {
new (): BaseEntity &
Entity & {
params: Parameters;
fsm: {
[Column in keyof Parameters]: IStateMachine<
ExtractState<Parameters, Column>,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export {
isStateMachineError,
} from 'fsmoothy';
export { StateMachineEntity } from './fsm.entity';
export { state } from './state';
11 changes: 11 additions & 0 deletions src/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { AllowedNames } from 'fsmoothy/types';

import { IStateMachineEntityColumnParameters } from './fsm.entity';

export const state = <
const State extends AllowedNames,
const Event extends AllowedNames,
const Context extends object,
>(
parameters: IStateMachineEntityColumnParameters<State, Event, Context>,
) => parameters;

0 comments on commit 507432a

Please sign in to comment.