diff --git a/Axium.md b/Axium.md index 152bbb5..de2e0a9 100644 --- a/Axium.md +++ b/Axium.md @@ -89,6 +89,9 @@ Please avoid using these qualities, but are providing explanations to understand * setMode - If your concept requires a specific modification to the functionality of the stream. This will set the mode index to that stream. Specifically this shouldn't have to be used. But is left to the developer if they run into such a case. * setDefaultModeIndex - Should be used if your mode is to be considered the default mode of your application. For utilization within a strategy after setMode. Be sure to a run time search for your concept name and mode, after your concept is added via the addConcept strategy found below. Be mindful that modeName is just your Concept Name and the creation of new Modes should be the last go To for your applications functionality. * clearDialog - Clears the currently stored STRX dialog, may be used within a strategy. +* 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. ## Axium Strategies Concept Set Transformation ```typescript diff --git a/Concept.md b/Concept.md index 6bf70f0..67bc18c 100644 --- a/Concept.md +++ b/Concept.md @@ -27,7 +27,8 @@ export type Quality = { methodCreator?: MethodCreator; method?: Method; subject?: Subject; - keyedSelectors?: KeyedSelector[] + keyedSelectors?: KeyedSelector[]; + analytics?: Record; }; ``` * actionType - Is the type of action and logical explanation of functionality @@ -36,6 +37,7 @@ export type Quality = { * method - Is the implementation of the strategy pattern via to facilitate higher order functionality to enable additional composability. * subject - Used within the mode to inform the method of an action to be consumed. * keyedSelector - Ops-in the quality or actions into the ownership paradigm and likewise can be used to select some aspect of state from the set of concepts. +* analytics - This field holds record entries such as time, cost, and success rate. This is for advanced systems that perform analytics to better describe ActionStrategies and their selection at run time. ## The Programmed Definition of a Concept ```typescript diff --git a/README.md b/README.md index 6f67108..fe4c7c0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The inspiration for STRX was that of Redux and its origin via the FLUX design pa ![Ghostbusters - "We'll Cross the Streams" - (HD) - Scenes from the 80s - (1984)](https://github.com/Phuire-Research/STRX/blob/main/CrossTheStreams.gif?raw=true) ### Concept Index -* [ActionStrategy](https://github.com/Phuire-Research/STRX/blob/main/ActionStrategy.md) - Created in 2018, this is the governing concept that allows for the Unified Turing Machine to have a strong halting quality. Likewise the direct analog of higher order logic. +* [ActionStrategy](https://github.com/Phuire-Research/STRX/blob/main/ActionStrategy.md) - Created in 2018, this is the governing concept that allows for the Unified Turing Machine to have a strong halting quality. Likewise the direct analog of higher order logic and universal transformer. * [Axium](https://github.com/Phuire-Research/STRX/blob/main/Axium.md) - Governing concept that contains the set of concepts that formalizes each axium. * [Concept](https://github.com/Phuire-Research/STRX/blob/main/Concept.md) - The programming abstraction of a concept that is decomposable to the sum of its parts via: state, qualities, principles, and mode. * [Stage](https://github.com/Phuire-Research/STRX/blob/main/Stage.md) - Introducing the stage design pattern. A specific helper function to prevent action overflow in action dispatches in subscriptions. diff --git a/Stage.md b/Stage.md index 1f84401..40718a5 100644 --- a/Stage.md +++ b/Stage.md @@ -1,8 +1,10 @@ ## Stage ### Abstract -This is derived from the newly created UnifiedSubject to handle the main point of vulnerability that a recursive machine carries. As the main point of dispatching new actions in the system would traditionally be informed via the subscription to listen to state changes. This Design Pattern allows one to safely dispatch in a tightly patterned subscription. This design pattern watches each stage for the potential of a runaway configuration which would normally prevent this machine from halting. But since the Unified Turing Machine was created to be halting complete. The UnifiedSubject internally watches each stage of your application independently and the actions that it dispatches via the supplied dispatch function. If a similar action is dispatched in rapid Succession denoted by its type and no debounce option. That Stage will close and be added to the axium's badStages property. +This is derived from the newly created UnifiedSubject to handle the main point of vulnerability that a recursive machine carries. As the main point of dispatching new actions in the system would traditionally be informed via the subscription to listen to state changes. This Design Pattern allows one to safely dispatch in a tightly patterned subscription. This design pattern watches each stage for the potential of a runaway configuration which would normally prevent this machine from halting. But since the Unified Turing Machine was created to be halting complete. The UnifiedSubject internally watches each stage of your application independently and the actions that it dispatches via the supplied dispatch function. If a similar action is dispatched in rapid Succession denoted by its type and no debounce option. That Stage will close and be added to the axium's badPlans property. -Once attached to the badStage property, it would be possible to reinitialize said stage via your concept's principle utilizing the stage's title. But places that burden of responsibility on the developer. As the scope of a Unified Turing Machine is to be designed to specification and halt appropriately. We accept failure as likewise the ability to halt. +Once attached to the badPlan property, it would be possible to reinitialize said stage via your concept's principle utilizing the stage's title. But places that burden of responsibility on the developer. As the scope of a Unified Turing Machine is to be designed to specification and halt appropriately. We accept failure as likewise the ability to halt. + +"You stage a plan and a plan has multiple stages." ## Working with the Stage Paradigm ```typescript @@ -86,7 +88,7 @@ const staged = axium.stage('Stage DispatchOptions Test', console.log('Stage 3 ', counter, runCount); // Will cause an action overflow forcing the stage to close and add itself to bad Stages dispatch(counterSubtract(), { - // Enabling will cause this test to timeout via the subscription watching for badStages to never be ran. + // Enabling will cause this test to timeout via the subscription watching for badPlans to never be ran. // debounce: 500 // This demonstrates the fault resistance of the Stage paradigm, despite STRX's recursive functionality. }); @@ -96,11 +98,11 @@ const staged = axium.stage('Stage DispatchOptions Test', const sub = axium.subscribe((concepts) => { const axiumState = concepts[0].state as AxiumState; // This will run once the last step of the stage we created overflows, this is for demonstration purposes only. - if (axiumState.badStages.length > 0) { - const badStage = axiumState.badStages[0]; + if (axiumState.badPlans.length > 0) { + const badPlan = axiumState.badPlans[0]; const counter = selectState(concepts, counterName); - console.log('Stage Ran Away, badStages.length: ', axiumState.badStages.length, 'Count: ', counter.count); - expect(badStage.stepFailed).toBe(2); + console.log('Stage Ran Away, badPlans.length: ', axiumState.badPlans.length, 'Count: ', counter.count); + expect(badPlan.stepFailed).toBe(2); expect(counter.count).toBe(2); sub.unsubscribe(); } diff --git a/package.json b/package.json index 88402cd..1b4a377 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@phuire/strx", - "version": "0.0.19", + "version": "0.0.20", "description": "Unified Turing Machine", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/src/concepts/axium/axium.concept.ts b/src/concepts/axium/axium.concept.ts index e0ef70f..96b1eaa 100644 --- a/src/concepts/axium/axium.concept.ts +++ b/src/concepts/axium/axium.concept.ts @@ -22,6 +22,9 @@ import { setModeQuality } from './qualities/setMode.quality'; import { setDefaultModeIndexQuality } from './qualities/setDefaultModeIndex.quality'; import { clearDialogQuality } from './qualities/clearDialog.quality'; import { Plan, UnifiedSubject } from '../../model/unifiedSubject'; +import { clearBadActionTypeFromBadActionListQuality } from './qualities/clearBadActionTypeFromBadActionList.quality'; +import { clearBadStrategyTopicFromBadActionListQuality } from './qualities/clearBadStrategyTopicFromBadActionList.quality'; +import { clearBadPlanFromBadPlanListQuality } from './qualities/clearBadPlanFromBadPlanList.quality'; export type NamedSubscriber = { name: string; @@ -48,7 +51,7 @@ export type AxiumState = { addConceptQue: Concept[], removeConceptQue: Concept[], subConcepts$: UnifiedSubject; - badStages: Plan[]; + badPlans: Plan[]; badActions: Action[]; } @@ -74,7 +77,7 @@ const createAxiumState = (name: string, storeDialog?: boolean, logging?: boolean addConceptQue: [] as Concept[], removeConceptQue: [] as Concept[], subConcepts$: new UnifiedSubject(), - badStages: [], + badPlans: [], badActions: [] }; }; @@ -100,6 +103,9 @@ export const createAxiumConcept = (name: string, storeDialog?: boolean, logging? appendConceptsToRemoveQueQuality, removeConceptsViaQueQuality, setModeQuality, + clearBadActionTypeFromBadActionListQuality, + clearBadStrategyTopicFromBadActionListQuality, + clearBadPlanFromBadPlanListQuality ], [axiumPrinciple], [blockingMode, permissiveMode] diff --git a/src/concepts/axium/axium.selector.ts b/src/concepts/axium/axium.selector.ts index e16e074..aacb08c 100644 --- a/src/concepts/axium/axium.selector.ts +++ b/src/concepts/axium/axium.selector.ts @@ -10,9 +10,9 @@ export const axiumSelectLastStrategy: KeyedSelector = { stateKeys: 'lastStrategy', }; -export const axiumSelectBadStages: KeyedSelector = { +export const axiumSelectBadPlans: KeyedSelector = { conceptName: 'axium', - stateKeys: 'badStages', + stateKeys: 'badPlans', }; export const axiumSelectBadActions: KeyedSelector = { diff --git a/src/concepts/axium/qualities/clearBadActionTypeFromBadActionList.quality.ts b/src/concepts/axium/qualities/clearBadActionTypeFromBadActionList.quality.ts new file mode 100644 index 0000000..18e1cfa --- /dev/null +++ b/src/concepts/axium/qualities/clearBadActionTypeFromBadActionList.quality.ts @@ -0,0 +1,21 @@ +import { defaultMethodCreator, createQuality } from '../../../model/concept'; +import { Action, ActionType, prepareActionCreator } from '../../../model/action'; +import { AxiumState } from '../axium.concept'; + +export const axiumClearBadActionTypeFromBadActionListType: ActionType = 'clear ActionType from Axium\'s badAction list'; +export const axiumClearBadActionTypeFromBadActionList = prepareActionCreator(axiumClearBadActionTypeFromBadActionListType); +export type ClearBadActionTypeFromBadActionListPayload = ActionType; + +function clearBadActionTypeFromBadActionListReducer(state: AxiumState, action: Action): AxiumState { + const actionType = action.payload as ClearBadActionTypeFromBadActionListPayload; + return { + ...state, + badActions: state.badActions.filter(act => act.type !== actionType), + }; +} + +export const clearBadActionTypeFromBadActionListQuality = createQuality( + axiumClearBadActionTypeFromBadActionListType, + clearBadActionTypeFromBadActionListReducer, + defaultMethodCreator, +); diff --git a/src/concepts/axium/qualities/clearBadPlanFromBadPlanList.quality.ts b/src/concepts/axium/qualities/clearBadPlanFromBadPlanList.quality.ts new file mode 100644 index 0000000..05a9ee9 --- /dev/null +++ b/src/concepts/axium/qualities/clearBadPlanFromBadPlanList.quality.ts @@ -0,0 +1,21 @@ +import { defaultMethodCreator, createQuality } from '../../../model/concept'; +import { Action, ActionType, prepareActionCreator } from '../../../model/action'; +import { AxiumState } from '../axium.concept'; + +export const axiumClearBadPlanFromBadPlanListType: ActionType = 'clear Plan Topic from Axium\'s badPlan list'; +export const axiumClearBadPlanFromBadPlanList = prepareActionCreator(axiumClearBadPlanFromBadPlanListType); +export type ClearBadPlanFromBadPlanListPayload = string; + +function clearBadPlanFromBadPlanListReducer(state: AxiumState, action: Action): AxiumState { + const title = action.payload as ClearBadPlanFromBadPlanListPayload; + return { + ...state, + badPlans: state.badPlans.filter(act => act.title !== title), + }; +} + +export const clearBadPlanFromBadPlanListQuality = createQuality( + axiumClearBadPlanFromBadPlanListType, + clearBadPlanFromBadPlanListReducer, + defaultMethodCreator, +); diff --git a/src/concepts/axium/qualities/clearBadStrategyTopicFromBadActionList.quality.ts b/src/concepts/axium/qualities/clearBadStrategyTopicFromBadActionList.quality.ts new file mode 100644 index 0000000..3b2928e --- /dev/null +++ b/src/concepts/axium/qualities/clearBadStrategyTopicFromBadActionList.quality.ts @@ -0,0 +1,28 @@ +import { defaultMethodCreator, createQuality } from '../../../model/concept'; +import { Action, ActionType, prepareActionCreator } from '../../../model/action'; +import { AxiumState } from '../axium.concept'; + +export const axiumClearBadStrategyTopicFromBadActionListType: ActionType = 'clear Strategy Topic from Axium\'s badAction list'; +export const axiumClearBadStrategyTopicFromBadActionList = prepareActionCreator(axiumClearBadStrategyTopicFromBadActionListType); +export type ClearBadStrategyTopicFromBadActionListPayload = string; + +function clearBadStrategyTopicFromBadActionListReducer(state: AxiumState, action: Action): AxiumState { + const strategyTopic = action.payload as ClearBadStrategyTopicFromBadActionListPayload; + const badActions = state.badActions.filter(act => { + if (act.strategy && act.strategy.topic !== strategyTopic) { + return true; + } else { + return false; + } + }); + return { + ...state, + badActions, + }; +} + +export const clearBadStrategyTopicFromBadActionListQuality = createQuality( + axiumClearBadStrategyTopicFromBadActionListType, + clearBadStrategyTopicFromBadActionListReducer, + defaultMethodCreator, +); diff --git a/src/index.ts b/src/index.ts index b63503a..8cfe9fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,7 +35,7 @@ export type { OwnershipTicket, OwnershipTicketStub, OwnershipLedger } from './mo // Axium export { AxiumState, axiumName, createAxiumConcept } from './concepts/axium/axium.concept'; export { blockingMode, permissiveMode } from './concepts/axium/axium.mode'; -export { axiumSelectOpen, axiumSelectLastStrategy, axiumSelectBadActions, axiumSelectBadStages } from './concepts/axium/axium.selector'; +export { axiumSelectOpen, axiumSelectLastStrategy, axiumSelectBadActions, axiumSelectBadPlans } from './concepts/axium/axium.selector'; // Qualities export { axiumConcludeType } from './concepts/axium/qualities/conclude.quality'; export { axiumOpen, axiumOpenType } from './concepts/axium/qualities/open.quality'; diff --git a/src/model/concept.ts b/src/model/concept.ts index d827127..2767e20 100644 --- a/src/model/concept.ts +++ b/src/model/concept.ts @@ -28,7 +28,8 @@ export type Quality = { methodCreator?: MethodCreator; method?: Method; subject?: Subject; - keyedSelectors?: KeyedSelector[] + keyedSelectors?: KeyedSelector[]; + analytics?: Record; }; export type Concept = { @@ -61,7 +62,7 @@ export function createConcept( state, qualities, principles, - mode + mode, }; } @@ -107,13 +108,15 @@ export function createQuality( reducer: Reducer, methodCreator?: MethodCreator, // eslint-disable-next-line @typescript-eslint/no-explicit-any - keyedSelectors?: KeyedSelector[] + keyedSelectors?: KeyedSelector[], + analytics?: Record ): Quality { return { actionType, reducer, methodCreator, - keyedSelectors + keyedSelectors, + analytics }; } diff --git a/src/model/unifiedSubject.ts b/src/model/unifiedSubject.ts index ac3fff4..e99fa6a 100644 --- a/src/model/unifiedSubject.ts +++ b/src/model/unifiedSubject.ts @@ -188,7 +188,7 @@ export class UnifiedSubject extends Subject { plan.stage = plan.stages.length; const deleted = this.currentStages.delete(key); if (deleted) { - axiumState.badStages.push(plan); + axiumState.badPlans.push(plan); } } } diff --git a/src/test/stageDisptachOptions.test.ts b/src/test/stageDisptachOptions.test.ts index a82a737..30c7f16 100644 --- a/src/test/stageDisptachOptions.test.ts +++ b/src/test/stageDisptachOptions.test.ts @@ -11,11 +11,11 @@ test('Axium Stage Dispatch Options Test', (done) => { const axium = createAxium('axiumStageDispatchOptionsTest', [createCounterConcept()], true); axium.subscribe((concepts) => { const axiumState = concepts[0].state as AxiumState; - if (axiumState.badStages.length > 0) { - const badStage = axiumState.badStages[0]; + if (axiumState.badPlans.length > 0) { + const badPlan = axiumState.badPlans[0]; const counter = selectState(concepts, counterName); - console.log('Stage Ran Away, badStages.length: ', axiumState.badStages.length, 'Count: ', counter.count); - expect(badStage.stageFailed).toBe(2); + console.log('Stage Ran Away, badPlans.length: ', axiumState.badPlans.length, 'Count: ', counter.count); + expect(badPlan.stageFailed).toBe(2); expect(counter.count).toBe(2); setTimeout(() => {done();}, 500); staged.close(); @@ -53,7 +53,7 @@ test('Axium Stage Dispatch Options Test', (done) => { console.log('Stage 3 ', counter, runCount); // Will cause an action overflow forcing the stage to close and add itself to bad Stages dispatch(counterSubtract(), { - // Enabling will cause this test to timeout via the subscription watching for badStages to never be ran. + // Enabling will cause this test to timeout via the subscription watching for badPlans to never be ran. // debounce: 500 // This demonstrates the fault resistance of the Stage paradigm, despite STRX's recursive functionality. });