Skip to content

Commit

Permalink
Merge pull request #98 from Phuire-Research/UI
Browse files Browse the repository at this point in the history
UI
  • Loading branch information
REllEK-IO authored Oct 19, 2023
2 parents f22348e + c86ff8e commit ec889b7
Show file tree
Hide file tree
Showing 39 changed files with 953 additions and 151 deletions.
33 changes: 33 additions & 0 deletions ActionStrategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,36 @@ The same is true when accessing the payload from a reducer, method, or principle
SomethingFactory<AnotherFactor<Factory>>
```
This was a purposeful design choice, if you find yourself doing such. Known this system is already complicated enough.

## Helper Functions for Standard Method Creators
*You still need to create a function of type MethodCreator to use these Helpers. :MethodCreator = () => methodCreator*
```typescript
export const createMethod =
(method: (action: Action) => Action): [Method, Subject<Action>] => {}
export const createMethodWithConcepts =
(method: (action: Action) => Action, concepts$: UnifiedSubject): [Method, Subject<Action>] => {}
export const createAsyncMethod =
(asyncMethod: (controller: ActionController, action: Action) => void): [Method, Subject<Action>] => {}
export const createAsyncMethodWithConcepts =
(asyncMethodWithConcepts: (controller: ActionController, action: Action, concepts: Concept[]) => void, concepts$: UnifiedSubject)
: [Method, Subject<Action>] => {}
export const createMethodDebounce =
(method: (action: Action) => Action, duration: number): [Method, Subject<Action>] => {}
export const createMethodDebounceWithConcepts =
(methodWithConcepts: (action: Action, concepts: Concept[]) => Action, concepts$: UnifiedSubject, duration: number)
: [Method, Subject<Action>] => {}
export const createAsyncMethodDebounce =
(asyncMethod: (controller: ActionController, action: Action) => void, duration: number): [Method, Subject<Action>] => {}
export const createAsyncMethodDebounceWithConcepts =
(asyncMethodWithConcepts: (controller: ActionController, action: Action, concepts: Concept[]) =>
void, concepts$: UnifiedSubject, duration: number): [Method, Subject<Action>] => {}
```
* createMethod - Your standard method, be sure to handle the action.strategy via one of the strategy decision functions, in addition to passing the action if there is no attached strategy.
* createMethodWithConcepts - This will allow your method to have the most recent concepts to be accessed via the asyncMethod function.
* createAsyncMethod - Handled differently than the rest, you will have to use the passed controller to fire your actions back into the action stream.
* createAsyncMethodWithConcepts - Will also have access to the most recent concepts.
*Note if you are implementing your own debounceAction how these methods work. They are handling a passed conclude from debounceAction within their map/switchMap*
* createMethodDebounce - After the first action, this will filter actions within the duration to be set to the conclude action.
* createMethodDebounceWithConcepts - Will filter actions within the duration while providing access to the most recent concepts.
* createAsyncMethodDebounce - Will not disengage the initial ActionController, but will allow debounced actions to pass through when filtered as conclude actions. And will fire the first action upon its own conditions are met asynchronously.
* createAsyncMethodDebounceWithConcepts - Filters and then first the first action once conditions are met, and provides access to the most recent concepts.
3 changes: 3 additions & 0 deletions Axium.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type AxiumState {
dialog: string;
storeDialog: boolean;
lastStrategy: string;
lastStrategyData: unknown;
generation: number;
modeIndex: number;
defaultModeIndex: number;
Expand All @@ -46,6 +47,7 @@ export type AxiumState {
* dialog - Is the internal representation of the strategies that the axium has ran.
* storeDialog - This is set to false by default to save on memory, but if true will store each dialog, and allows such to be subscribed to.
* lastStrategy - Informs specifically the of the last ActionStrategy topic to have ran through the system. This is used via testing or the deployment of addition strategies upon completion.
* lastStrategyData - Paired with lastStrategy. Use to access thee last data of the previous strategy.
* generation - This iterates each time the Set of Concepts is transformed. And if an action is received of the wrong generation. Will be primed at run time, if not found this will emit a badAction that if logging is set to True. Will be emitted to the console alongside the invalidated action as payload.
* modeIndex - This determines which Mode is currently being ran from the lists of modes stored on the axium concept.
* defaultModeIndex - This determines what mode will be set by setDefaultMode. Of importance for adding and removing strategies.
Expand Down Expand Up @@ -92,6 +94,7 @@ Please avoid using these qualities, but are providing explanations to understand
* clearBadActionTypeFromBadActionList - This is to allow for plans to take into account for expired actions and clear such.
* clearBadStrategyTopicFromBadActionList - Allows plans to accounts for specific ActionStrategy topics that might find themselves in badActions and clear such.
* clearBadPlanFromBadPlanList - This additionally allows for concepts to take into account potentially failed plans that are set by axium.stage(). Via their topic as payload and clears such.
* kick - This is a pure action that will just trigger the next function via the UnifiedSubject to prime subscribers or stages. Noting that the downside of STRX's halting quality, is you have to kick it into gear if it hasn't received an action recently for your staged Plans to operate as intended.

## Axium Strategies Concept Set Transformation
```typescript
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ let finalRun = true;
const axium = createAxium('ownershipTest', [
createOwnershipConcept(),
createCounterConcept(),
createExperimentConcept(createExperimentActionQueState(), [checkInStrategyQuality], [experimentActionQuePrinciple])
createExperimentConcept(createExperimentState(), [checkInStrategyQuality], [experimentActionQuePrinciple])
], true, true);
const plan = axium.stage(
'Testing Ownership Staging', [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@phuire/strx",
"version": "0.0.36",
"version": "0.0.38",
"description": "Unified Turing Machine",
"main": "dist/index.js",
"module": "dist/index.mjs",
Expand Down
4 changes: 4 additions & 0 deletions src/concepts/axium/axium.concept.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { clearBadActionTypeFromBadActionListQuality } from './qualities/clearBad
import { clearBadStrategyTopicFromBadActionListQuality } from './qualities/clearBadStrategyTopicFromBadActionList.quality';
import { clearBadPlanFromBadPlanListQuality } from './qualities/clearBadPlanFromBadPlanList.quality';
import { registerStagePlannerQuality } from './qualities/registerStagePlanner.quality';
import { kickQuality } from './qualities/kick.quality';

export type NamedSubscription = {
name: string;
Expand All @@ -40,6 +41,7 @@ export type AxiumState = {
dialog: string;
storeDialog: boolean;
lastStrategy: string;
lastStrategyData: unknown;
generation: number;
cachedSemaphores: Map<string,Map<string,[number,number,number, number]>>
modeIndex: number;
Expand Down Expand Up @@ -67,6 +69,7 @@ const createAxiumState = (name: string, storeDialog?: boolean, logging?: boolean
dialog: '',
storeDialog: storeDialog ? storeDialog : false,
lastStrategy: '',
lastStrategyData: '',
generation: 0,
cachedSemaphores: new Map<string, Map<string, [number, number, number, number]>>(),
modeIndex: 0,
Expand All @@ -90,6 +93,7 @@ export const createAxiumConcept = (name: string, storeDialog?: boolean, logging?
axiumName,
createAxiumState(name, storeDialog, logging),
[
kickQuality,
openQuality,
badActionQuality,
closeQuality,
Expand Down
5 changes: 5 additions & 0 deletions src/concepts/axium/axium.selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export const axiumSelectLastStrategy: KeyedSelector = {
stateKeys: 'lastStrategy',
};

export const axiumSelectLastStrategyData: KeyedSelector = {
conceptName: 'axium',
stateKeys: 'lastStrategyData',
};

export const axiumSelectBadPlans: KeyedSelector = {
conceptName: 'axium',
stateKeys: 'badPlans',
Expand Down
2 changes: 1 addition & 1 deletion src/concepts/axium/qualities/addConceptsFromQue.quality.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function addConceptsFromQueReducer(state: AxiumState, _ : Action) {
addConceptsQue.forEach(concept => {
concept.qualities.forEach(quality => {
if (quality.methodCreator) {
[quality.method, quality.subject] = quality.methodCreator(state.subConcepts$);
[quality.method, quality.subject] = quality.methodCreator(state.concepts$);
quality.method.pipe(
catchError((err: unknown, caught: Observable<Action>) => {
if (state.logging) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import { selectPayload } from '../../../model/selector';
export type AppendActionListToDialogPayload = {
actionList: Array<string>;
strategyTopic: string;
strategyData: unknown;
}
export const axiumAppendActionListToDialogType: ActionType = 'append Action List to Axium\'s Dialog';
export const axiumAppendActionListToDialog =
prepareActionWithPayloadCreator<AppendActionListToDialogPayload>(axiumAppendActionListToDialogType);

export function appendActionListToDialogReducer(state: AxiumState, action: Action) {
export function appendActionListToDialogReducer(state: AxiumState, action: Action): AxiumState {
const payload = selectPayload<AppendActionListToDialogPayload>(action);
let newDialog = '';
if (state.storeDialog) {
Expand All @@ -25,11 +26,13 @@ export function appendActionListToDialogReducer(state: AxiumState, action: Actio
...state,
dialog: state.dialog + newDialog,
lastStrategy: payload.strategyTopic,
lastStrategyData: payload.strategyData
};
}
return {
...state,
lastStrategy: payload.strategyTopic
lastStrategy: payload.strategyTopic,
lastStrategyData: payload.strategyData
};
}

Expand Down
15 changes: 13 additions & 2 deletions src/concepts/axium/qualities/close.quality.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { createQuality } from '../../../model/concept';
import { Action, ActionType, prepareActionCreator } from '../../../model/action';
import { Action, ActionType, prepareActionWithPayloadCreator } from '../../../model/action';
import { AxiumState } from '../axium.concept';
import { selectPayload } from '../../../model/selector';

/**
* @parm exit - If set to true, will exit the current process.
*/
export type ClosePayload = {
exit: boolean
};
export const axiumCloseType: ActionType = 'Close Axium';
export const axiumClose = prepareActionCreator(axiumCloseType);
export const axiumClose = prepareActionWithPayloadCreator(axiumCloseType);

export function closeReducer(state: AxiumState, _action: Action): AxiumState {
const {exit} = selectPayload<ClosePayload>(_action);
state.generalSubscribers.forEach(named => named.subscription.unsubscribe());
state.methodSubscribers.forEach(named => named.subscription.unsubscribe());
state.stagePlanners.forEach(named => named.conclude());
state.action$.complete();
state.concepts$.complete();
state.subConcepts$.complete();
if (exit) {
process.exit();
}
return {
...state,
methodSubscribers: [],
Expand Down
12 changes: 12 additions & 0 deletions src/concepts/axium/qualities/kick.quality.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defaultMethodCreator, defaultReducer } from '../../../model/concept';
import { ActionType, prepareActionCreator } from '../../../model/action';
import { createQuality } from '../../../model/concept';

export const axiumKickType: ActionType = 'Kick Axium';
export const axiumKick = prepareActionCreator(axiumKickType);

export const kickQuality = createQuality(
axiumKickType,
defaultReducer,
defaultMethodCreator
);
25 changes: 9 additions & 16 deletions src/concepts/axium/qualities/log.quality.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,19 @@ import { Action, ActionType, prepareActionCreator } from '../../../model/action'
import { createQuality } from '../../../model/concept';
import { axiumConclude } from './conclude.quality';
import { strategySuccess } from '../../../model/actionStrategy';
import { createMethod } from '../../../model/method';

export const axiumLogType: ActionType = 'logged a message passed to Axium';
export const axiumLog = prepareActionCreator(axiumLogType);

const createLogMethodCreator: MethodCreator = () => {
const logSubject = new Subject<Action>();
const logMethod: Method = logSubject.pipe(
map((action: Action) => {
console.log('Logging: ', action);
if (action.strategy) {
return strategySuccess(action.strategy);
}
return axiumConclude();
})
);
return [
logMethod,
logSubject
];
};
export const createLogMethodCreator: MethodCreator = () => createMethod((action) => {
console.log('Logging: ', action);
if (action.strategy) {
return strategySuccess(action.strategy);
} else {
return axiumConclude();
}
});

export const logQuality = createQuality(
axiumLogType,
Expand Down
31 changes: 13 additions & 18 deletions src/concepts/axium/qualities/setMode.quality.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { AxiumState } from '../axium.concept';
import { Action, createAction, prepareActionWithPayloadCreator} from '../../../model/action';
import { createQuality, MethodCreator, Method } from '../../../model/concept';
import { Subject, map } from 'rxjs';
import { axiumConcludeType } from './conclude.quality';
import { axiumConclude, axiumConcludeType } from './conclude.quality';
import { strategySuccess } from '../../../model/actionStrategy';
import { selectPayload } from '../../../model/selector';
import { createMethod } from '../../../model/method';

export type SetModePayload = {
modeIndex: number;
Expand All @@ -14,22 +15,16 @@ export type SetModePayload = {
export const axiumSetModeType = 'set Axium Mode';
export const axiumSetMode = prepareActionWithPayloadCreator<SetModePayload>(axiumSetModeType);

export const createOwnershipMethodCreator: MethodCreator = () : [Method, Subject<Action>] => {
const defaultSubject = new Subject<Action>();
const defaultMethod: Method = defaultSubject.pipe<Action>(
map((action: Action) => {
const payload = action.payload as SetModePayload;
if (action.strategy) {
action.strategy.currentNode.successNotes = {
denoter: `to ${payload.modeName}.`
};
return strategySuccess(action.strategy);
}
return createAction(axiumConcludeType);
}),
);
return [defaultMethod, defaultSubject];
};
export const axiumSetModeMethodCreator: MethodCreator = () => createMethod((action) => {
const payload = action.payload as SetModePayload;
if (action.strategy) {
action.strategy.currentNode.successNotes = {
denoter: `to ${payload.modeName}.`
};
return strategySuccess(action.strategy);
}
return action;
});

export function setModeReducer(state: AxiumState, _action: Action) {
const payload = selectPayload<SetModePayload>(_action);
Expand All @@ -42,5 +37,5 @@ export function setModeReducer(state: AxiumState, _action: Action) {
export const setModeQuality = createQuality(
axiumSetModeType,
setModeReducer,
createOwnershipMethodCreator
axiumSetModeMethodCreator
);
32 changes: 10 additions & 22 deletions src/concepts/counter/qualities/add.quality.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,30 @@
import { map, Subject } from 'rxjs';
import { Action, ActionType, prepareActionCreator } from '../../../model/action';
import { Method, MethodCreator } from '../../../model/concept';
import { strategySuccess } from '../../../model/actionStrategy';
import { defaultMethodCreator, Method, MethodCreator } from '../../../model/concept';
import { Counter } from '../counter.concept';
import { createQuality } from '../../../model/concept';
import { counterSelectCount } from '../counter.selector';
import { axiumConclude } from '../../axium/qualities/conclude.quality';
// import { createMethod } from '../../../model/method';
// import { strategySuccess } from '../../../model/actionStrategy';

export const counterAddType: ActionType = 'Counter Add';

export const counterAdd = prepareActionCreator(counterAddType);

// const createAddMethodCreator: MethodCreator = () => createMethod((action) => {
// if (action.strategy) {
// return strategySuccess(action.strategy);
// }
// return action;
// });
export function addReducer(state: Counter, _: Action) {
return {
...state,
count: state.count + 1
};
}

const addMethodCreator: MethodCreator = () => {
const addSubject = new Subject<Action>();
const addMethod: Method = addSubject.pipe<Action>(
map((action: Action) => {
if (action.strategy) {
return strategySuccess(action.strategy);
}
return axiumConclude();
})
);
return [
addMethod,
addSubject
];
};

export const addQuality = createQuality(
counterAddType,
addReducer,
addMethodCreator,
defaultMethodCreator,
[counterSelectCount]
);
20 changes: 2 additions & 18 deletions src/concepts/counter/qualities/subtract.quality.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { map, Subject } from 'rxjs';
import { strategySuccess } from '../../../model/actionStrategy';
import { Method, MethodCreator } from '../../../model/concept';
import { defaultMethodCreator, Method, MethodCreator } from '../../../model/concept';
import { Counter } from '../counter.concept';
import { Action, ActionType, createAction, prepareActionCreator } from '../../../model/action';
import { createQuality } from '../../../model/concept';
Expand All @@ -18,25 +18,9 @@ export function subtractReducer(state: Counter) {
};
}

const subtractMethodCreator: MethodCreator = () => {
const subtractSubject = new Subject<Action>();
const subtractMethod: Method = subtractSubject.pipe<Action>(
map((action: Action) => {
if (action.strategy) {
return strategySuccess(action.strategy);
}
return axiumConclude();
})
);
return [
subtractMethod,
subtractSubject
];
};

export const subtractQuality = createQuality(
counterSubtractType,
subtractReducer,
subtractMethodCreator,
defaultMethodCreator,
[counterSelectCount]
);
Loading

0 comments on commit ec889b7

Please sign in to comment.