Skip to content

Commit

Permalink
fix(extensions): fixed actions extension test failing
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewcourtice committed Jul 31, 2021
1 parent 89586df commit 81fe605
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 46 deletions.
42 changes: 13 additions & 29 deletions extensions/actions/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import {
Extension,
InternalStore,
createStore,
Mutator
} from '@harlem/core';

Expand All @@ -11,33 +9,34 @@ import type {
ActionPredicate,
ActionStoreState,
AddActionInstancePayload,
ComposedAction,
RemoveActionInstancePayload
} from './types';

export * from './types';

export default function actionsExtension<TState>(store: InternalStore<TState>) {

const _store = store as unknown as InternalStore<TState & ActionStoreState>;

store.write('$add-actions', '$actions-extension', state => {
_store.write('$add-actions', '$actions-extension', state => {
state.$actions = {};
});

const addActionInstance = store.mutation<AddActionInstancePayload>('$add-action-instance', (state, payload) => {
const addActionInstance = _store.mutation<AddActionInstancePayload>('$add-action-instance', (state, payload) => {
const {
actionName,
instanceId,
instancePayload
} = payload;

if (!state.$actions[actionName]) {
state.$actions[actionName] = new Map<symbol, any>();
state.$actions[actionName] = new Map<symbol, unknown>();
}

state.$actions[actionName].set(instanceId, instancePayload);
});

const removeActionInstance = store.mutation<RemoveActionInstancePayload>('$remove-action-instance', (state, payload) => {
const removeActionInstance = _store.mutation<RemoveActionInstancePayload>('$remove-action-instance', (state, payload) => {
const {
actionName,
instanceId,
Expand All @@ -51,9 +50,9 @@ export default function actionsExtension<TState>(store: InternalStore<TState>) {
});

function action<TPayload, TResult = void>(name: string, body: ActionBody<TState, TPayload, TResult>): Action<TPayload, TResult> {
const mutate = (mutator: Mutator<TState, undefined, void>) => store.write(name, '$actions-extension', mutator);
const mutate = (mutator: Mutator<TState, undefined, void>) => _store.write(name, '$actions-extension', mutator);

const _action = async (payload: TPayload) => {
return (async (payload: TPayload) => {
const id = Symbol(name);

addActionInstance({
Expand All @@ -74,35 +73,20 @@ export default function actionsExtension<TState>(store: InternalStore<TState>) {
}

return result;
};

_action.name = name;

return _action as Action<TPayload, TResult>;
}) as Action<TPayload, TResult>;
}

function isActionRunnng<TPayload = any>(name: string, instancePredicate?: ActionPredicate<TPayload>) {
const predicate = instancePredicate || (() => true);
const instances = store.state.$actions[name];
function isActionRunning<TPayload = unknown>(name: string, predicate: ActionPredicate<TPayload> = () => true) {
const instances = _store.state.$actions[name];

return !!instances && Array
.from(instances.values())
.some(payload => predicate(payload));
}

function useAction<TPayload, TResult>(action: Action<TPayload, TResult>): ComposedAction<TPayload, TResult> {
const isRunning = (predicate?: ActionPredicate<TPayload>) => isActionRunnng(action.name, predicate);

return [
action,
isRunning
];
.some(payload => predicate(payload as TPayload));
}

return {
action,
isActionRunnng,
useAction
isActionRunning
};

};
15 changes: 4 additions & 11 deletions extensions/actions/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,18 @@ import {
} from '../../../core/dist';

export type ActionBody<TState, TPayload = undefined, TResult = void> = (payload: TPayload, mutator: (mutate: Mutator<TState, undefined, void>) => void) => Promise<TResult>;
//export type Action<TPayload, TResult = void> = undefined extends TPayload ? (payload?: TPayload) => Promise<TResult> : (payload: TPayload) => Promise<TResult>;
export type ActionPredicate<TPayload = any> = (payload?: TPayload) => boolean;
export type Action<TPayload, TResult = void> = undefined extends TPayload ? (payload?: TPayload) => Promise<TResult> : (payload: TPayload) => Promise<TResult>;
export type ActionPredicate<TPayload = unknown> = (payload?: TPayload) => boolean;
export type ComposedAction<TPayload, TResult = void> = [Action<TPayload, TResult>, (predicate: ActionPredicate<TPayload>) => boolean];

export interface Action<TPayload, TResult = void> {
(payload?: TPayload): Promise<TResult>;
name: string
}

export interface ActionStoreState {
$actions: {
[key: string]: Map<symbol, any>;
}
$actions: Record<string, Map<symbol, unknown>>;
}

export interface AddActionInstancePayload {
actionName: string;
instanceId: symbol;
instancePayload?: any;
instancePayload?: unknown;
}

export interface RemoveActionInstancePayload {
Expand Down
30 changes: 24 additions & 6 deletions extensions/actions/test/actions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,47 @@ import {
createStore
} from '@harlem/core';

import actionsExtension from '../src/index';
import actionsExtension from '../src';

describe('Actions Extension', () => {

test('Performs a root reset', () => {
test('Runs an action', async () => {
const {
action
state,
action,
isActionRunning
} = createStore('test', {
givenName: 'John',
surname: 'Smith'
surname: 'Smith',
age: 28
}, {
extensions: [
actionsExtension
]
});

const loadUserInfo = action('load-user-info', async (id, mutate) => {
const actionName = 'load-user-info';

const loadUserInfo = action(actionName, async (name: string, mutate) => {
return new Promise(resolve => setTimeout(() => {
mutate(state => {
state.
state.givenName = name;
state.age = 26;
});

resolve(true);
}, 300));
});

const promise = loadUserInfo('Jane');

expect(isActionRunning(actionName)).toBe(true);

await promise;

expect(state.givenName).toBe('Jane');
expect(state.age).toBe(26);
expect(isActionRunning(actionName)).toBe(false);
});

});

0 comments on commit 81fe605

Please sign in to comment.