Skip to content

Commit

Permalink
Merge pull request #207 from Phuire-Research/dx
Browse files Browse the repository at this point in the history
v0.1.58
  • Loading branch information
REllEK-IO authored May 3, 2024
2 parents 323abb8 + 3fafd9f commit 1fe891a
Show file tree
Hide file tree
Showing 15 changed files with 408 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ When in doubt simplify.
* [Unified Turing Machine](https://github.com/Phuire-Research/Stratimux/blob/main/The-Unified-Turing-Machine.md) - The governing concept for this entire framework.

## Change Log ![Tests](https://github.com/Phuire-Research/Stratimux/actions/workflows/node.js.yml/badge.svg)
### v0.1.58 5/03/24
* Ensured that changes that happen between a stage's beat interval are accumulated
### v0.1.57 5/02/24
* Added the ability to set specific stages of their selectors, priority, and beat values.
* Note that by setting these values, this will not force the internal priority selector cache mechanism to trigger. Use set for stages your are iterating to or changing due to some circumstance. The new stage options will force the priority selector cache to trigger.
Expand Down
4 changes: 2 additions & 2 deletions StagePlanner.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type Plan = {
```typescript
export type dispatchOptions = {
runOnce?: boolean;
throttle?: number;
iterateStage?: boolean;
setStage?: number;
setStageSelectors?: {
Expand All @@ -39,7 +40,6 @@ export type dispatchOptions = {
stage: number,
beat: number
};
throttle?: number;
newSelectors?: KeyedSelector[];
newPriority?: number;
newBeat?: number;
Expand All @@ -61,7 +61,7 @@ This utilizes Stratimux's KeyedSelectors to control when a stage would run as a
Of the the main issues with utilizing a single point of observation, is that some plans you might devise should take precedence over others. For example the Axium's own close principle has the highest priority of all observations and will force a shutdown of the entire Axium upon observation. We have likewise provided the set and new stage options for the priority value to allow some intelligence to be at play, keeping in mind Stratimux is designed to act as a form of logical embodiment for this generation's probabilistic AI.

#### Stage Beat
The beat value each stage may have, is a new concept similar to the throttle and debounce found in reactive programming. Except here the first observation will run, and any subsequent observations will be delayed until just have the beat value expires. This ensures a constant stream of observations, while allowing for gaps of time that will instantly resume once the observation becomes relevant again. Think Frames Per Second (FPS).
The beat value each stage may have, is a new concept similar to the throttle and debounce found in reactive programming. Except here the first observation will run, and any subsequent observations will be delayed until just have the beat value expires. This ensures a constant stream of observations, while allowing for gaps of time that will instantly resume once the observation becomes relevant again, aggregating all changes that occurred between beats. Think Frames Per Second (FPS).

### Stage Planner Internals
```typescript
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stratimux",
"license": "GPL-3.0",
"version": "0.1.57",
"version": "0.1.58",
"description": "Unified Turing Machine",
"main": "dist/index.js",
"module": "dist/index.mjs",
Expand Down
29 changes: 26 additions & 3 deletions src/model/stagePlanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export type Plan = {
stageFailed: number;
beat: number;
offBeat: number;
timer: NodeJS.Timeout[]
timer: NodeJS.Timeout[];
changeAggregator: Record<string, KeyedSelector>;
}

export type Stage = (
Expand Down Expand Up @@ -344,7 +345,18 @@ export class UnifiedSubject extends Subject<Concepts> {
};
});
const beat = staged[0].beat;
return {id: planId, space, title, stages: staged, stage: 0, stageFailed: -1, beat: beat ? beat : -1, offBeat: -1, timer: []};
return {
id: planId,
space,
title,
stages: staged,
stage: 0,
stageFailed: -1,
beat: beat ? beat : -1,
offBeat: -1,
timer: [],
changeAggregator: {}
};
}

protected initPlan(plan: Plan): StagePlanner {
Expand Down Expand Up @@ -630,6 +642,7 @@ export class UnifiedSubject extends Subject<Concepts> {
stageDelimiter.prevActions = [];
stageDelimiter.unionExpiration = [];
stageDelimiter.runOnceMap = new Map();
plan.changeAggregator = {};
this.stageDelimiters.set(plan.id, stageDelimiter);
}
if (evaluate && next === -1) {
Expand Down Expand Up @@ -679,11 +692,21 @@ export class UnifiedSubject extends Subject<Concepts> {
plan.offBeat = Date.now() + plan.beat;
this.execute(plan, index, changes);
} else if (timer.length === 0 && plan.offBeat > now) {
// Logic to push changes into aggregator
changes.forEach(key => {
plan.changeAggregator[key.keys] = key;
});
timer.push(setTimeout(() => {
const changeAggregation = Object.keys(plan.changeAggregator).map(k => plan.changeAggregator[k]);
plan.changeAggregator = {};
plan.timer = [];
plan.offBeat = Date.now() + plan.beat;
this.execute(plan, index, changes);
this.execute(plan, index, changeAggregation);
}, plan.offBeat - Date.now()));
} else {
changes.forEach(key => {
plan.changeAggregator[key.keys] = key;
});
}
} else {
this.execute(plan, index, changes);
Expand Down
52 changes: 52 additions & 0 deletions src/test/beatSelectorChanges/beatSelectorChanges.concept.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*<$
For the asynchronous graph programming framework Stratimux generate an Experiment Concept that will be used to test deferred changes
accumulated for stage that has a beat and selectors
$>*/
/*<#*/
import { beatSelectorChangesAddToCountOneQuality } from './qualities/addToCountOne.quality';
import { createConcept } from '../../model/concept';
import { beatSelectorChangesAddToCountTwoQuality } from './qualities/addToCountTwo.quality';
import { beatSelectorChangesAddToCountThreeQuality } from './qualities/addToCountThree.quality';
import { beatSelectorChangesAddToCountFourQuality } from './qualities/addToCountFour.quality';
import { beatSelectorChangesAddToCountFiveQuality } from './qualities/addToCountFive.quality';
import { beatSelectorChangesAddToCountSixQuality } from './qualities/addToCountSix.quality';
import { beatSelectorChangesAddToCountSevenQuality } from './qualities/addToCountSeven.quality';

export type BeatSelectorChangesState = {
countOne: number
countTwo: number
countThree: number
countFour: number
countFive: number
countSix: number
countSeven: number
}

export const beatSelectorChangesName = 'beatSelectorChanges';

const initialBeatSelectorChangesState: BeatSelectorChangesState = {
countOne: 0,
countTwo: 0,
countThree: 0,
countFour: 0,
countFive: 0,
countSix: 0,
countSeven: 0,
};

export const createBeatSelectorChangesConcept = () => {
return createConcept(
beatSelectorChangesName,
initialBeatSelectorChangesState,
[
beatSelectorChangesAddToCountOneQuality,
beatSelectorChangesAddToCountTwoQuality,
beatSelectorChangesAddToCountThreeQuality,
beatSelectorChangesAddToCountFourQuality,
beatSelectorChangesAddToCountFiveQuality,
beatSelectorChangesAddToCountSixQuality,
beatSelectorChangesAddToCountSevenQuality,
]
);
};
/*#>*/
23 changes: 23 additions & 0 deletions src/test/beatSelectorChanges/beatSelectorChanges.selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*<$
For the asynchronous graph programming framework Stratimux and BeatSelectorChanges Concept,
generate a KeyedSelector for the BeatSelectorChanges's count variants state properties.
$>*/
/*<#*/
import { KeyedSelector, createConceptKeyedSelector } from '../../model/selector';
import { BeatSelectorChangesState } from './beatSelectorChanges.concept';

export const beatSelectorChangesSelectCountOne: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countOne');
export const beatSelectorChangesSelectCountTwo: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countTwo');
export const beatSelectorChangesSelectCountThree: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countThree');
export const beatSelectorChangesSelectCountFour: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countFour');
export const beatSelectorChangesSelectCountFive: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countFive');
export const beatSelectorChangesSelectCountSix: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countSix');
export const beatSelectorChangesSelectCountSeven: KeyedSelector =
createConceptKeyedSelector<BeatSelectorChangesState>('beatSelectorChanges', 'countSeven');
/*#>*/
67 changes: 67 additions & 0 deletions src/test/beatSelectorChanges/beatSelectorChanges.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*<$
For the asynchronous graph programming framework Stratimux generate a test that ensures that changes are properly deferred
utilizing the provided BeatSelectorChanges concept
$>*/
/*<#*/
import { createAxium, getAxiumState } from '../../model/axium';
import { createStage } from '../../model/stagePlanner';
import { generateRandomCountingStrategy } from './strategies/generateCountingStrategy.strategy';
import { beatSelectorChangesName, createBeatSelectorChangesConcept } from './beatSelectorChanges.concept';
import { initializeTopic } from '../../concepts/axium/strategies/initialization.strategy';
import { strategyBegin } from '../../model/actionStrategy';
import {
beatSelectorChangesSelectCountFive,
beatSelectorChangesSelectCountFour,
beatSelectorChangesSelectCountOne,
beatSelectorChangesSelectCountSeven,
beatSelectorChangesSelectCountSix,
beatSelectorChangesSelectCountThree,
beatSelectorChangesSelectCountTwo
} from './beatSelectorChanges.selector';
import { selectSlice, selectState } from '../../model/selector';
jest.setTimeout(30000);
test('Deferred Beat Selector Changes Test', (done) => {
const beat = 7000;
const [tally, strategy, topic] = generateRandomCountingStrategy();
const axium = createAxium('Beat Selector Changes properly defers accumulated changes', [
createBeatSelectorChangesConcept()
]);
const plan = axium.plan('Prolonged Counting Strategy', [
createStage((concepts, dispatch) => {
if (getAxiumState(concepts).lastStrategy === initializeTopic) {
dispatch(strategyBegin(strategy), {
iterateStage: true
});
}
}),
createStage((concepts, _, changes) => {
if (getAxiumState(concepts).lastStrategy === topic) {
expect(selectSlice(concepts, beatSelectorChangesSelectCountOne)).toBe(tally[0]);
expect(selectSlice(concepts, beatSelectorChangesSelectCountTwo)).toBe(tally[1]);
expect(selectSlice(concepts, beatSelectorChangesSelectCountThree)).toBe(tally[2]);
expect(selectSlice(concepts, beatSelectorChangesSelectCountFour)).toBe(tally[3]);
expect(selectSlice(concepts, beatSelectorChangesSelectCountFive)).toBe(tally[4]);
expect(selectSlice(concepts, beatSelectorChangesSelectCountSix)).toBe(tally[5]);
expect(selectSlice(concepts, beatSelectorChangesSelectCountSeven)).toBe(tally[6]);
expect(changes?.length).toBe(tally.length);
setTimeout(() => {
plan.conclude();
axium.close();
done();
}, 500);
}
}, {
beat,
selectors: [
beatSelectorChangesSelectCountOne,
beatSelectorChangesSelectCountTwo,
beatSelectorChangesSelectCountThree,
beatSelectorChangesSelectCountFour,
beatSelectorChangesSelectCountFive,
beatSelectorChangesSelectCountSix,
beatSelectorChangesSelectCountSeven,
]
})
]);
});
/*#>*/
24 changes: 24 additions & 0 deletions src/test/beatSelectorChanges/qualities/addToCountFive.quality.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*<$
For the asynchronous graph programming framework Stratimux and BeatSelectorChanges Concept,
generate a quality that will increment the state's countFive by one.
$>*/
/*<#*/
import { defaultMethodCreator } from '../../../model/concept';
import { BeatSelectorChangesState } from '../beatSelectorChanges.concept';
import { createQualitySet } from '../../../model/quality';

export const [
beatSelectorChangesAddToCountFive,
beatSelectorChangesAddToCountFiveType,
beatSelectorChangesAddToCountFiveQuality
] = createQualitySet({
type: 'BeatSelectorChanges AddToCountFive',
reducer: (state: BeatSelectorChangesState) => {
return {
...state,
countFive: state.countFive + 1
};
},
methodCreator: defaultMethodCreator,
});
/*#>*/
24 changes: 24 additions & 0 deletions src/test/beatSelectorChanges/qualities/addToCountFour.quality.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*<$
For the asynchronous graph programming framework Stratimux and BeatSelectorChanges Concept,
generate a quality that will increment the state's countFour by one.
$>*/
/*<#*/
import { defaultMethodCreator } from '../../../model/concept';
import { BeatSelectorChangesState } from '../beatSelectorChanges.concept';
import { createQualitySet } from '../../../model/quality';

export const [
beatSelectorChangesAddToCountFour,
beatSelectorChangesAddToCountFourType,
beatSelectorChangesAddToCountFourQuality
] = createQualitySet({
type: 'BeatSelectorChanges AddToCountFour',
reducer: (state: BeatSelectorChangesState) => {
return {
...state,
countFour: state.countFour + 1
};
},
methodCreator: defaultMethodCreator,
});
/*#>*/
24 changes: 24 additions & 0 deletions src/test/beatSelectorChanges/qualities/addToCountOne.quality.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*<$
For the asynchronous graph programming framework Stratimux and BeatSelectorChanges Concept,
generate a quality that will increment the state's countOne by one.
$>*/
/*<#*/
import { defaultMethodCreator } from '../../../model/concept';
import { BeatSelectorChangesState } from '../beatSelectorChanges.concept';
import { createQualitySet } from '../../../model/quality';

export const [
beatSelectorChangesAddToCountOne,
beatSelectorChangesAddToCountOneType,
beatSelectorChangesAddToCountOneQuality
] = createQualitySet({
type: 'BeatSelectorChanges AddToCountOne',
reducer: (state: BeatSelectorChangesState) => {
return {
...state,
countOne: state.countOne + 1
};
},
methodCreator: defaultMethodCreator,
});
/*#>*/
24 changes: 24 additions & 0 deletions src/test/beatSelectorChanges/qualities/addToCountSeven.quality.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*<$
For the asynchronous graph programming framework Stratimux and BeatSelectorChanges Concept,
generate a quality that will increment the state's countSeven by one.
$>*/
/*<#*/
import { defaultMethodCreator } from '../../../model/concept';
import { BeatSelectorChangesState } from '../beatSelectorChanges.concept';
import { createQualitySet } from '../../../model/quality';

export const [
beatSelectorChangesAddToCountSeven,
beatSelectorChangesAddToCountSevenType,
beatSelectorChangesAddToCountSevenQuality
] = createQualitySet({
type: 'BeatSelectorChanges AddToCountSeven',
reducer: (state: BeatSelectorChangesState) => {
return {
...state,
countSeven: state.countSeven + 1
};
},
methodCreator: defaultMethodCreator,
});
/*#>*/
24 changes: 24 additions & 0 deletions src/test/beatSelectorChanges/qualities/addToCountSix.quality.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*<$
For the asynchronous graph programming framework Stratimux and BeatSelectorChanges Concept,
generate a quality that will increment the state's countSix by one.
$>*/
/*<#*/
import { defaultMethodCreator } from '../../../model/concept';
import { BeatSelectorChangesState } from '../beatSelectorChanges.concept';
import { createQualitySet } from '../../../model/quality';

export const [
beatSelectorChangesAddToCountSix,
beatSelectorChangesAddToCountSixType,
beatSelectorChangesAddToCountSixQuality
] = createQualitySet({
type: 'BeatSelectorChanges AddToCountSix',
reducer: (state: BeatSelectorChangesState) => {
return {
...state,
countSix: state.countSix + 1
};
},
methodCreator: defaultMethodCreator,
});
/*#>*/
Loading

0 comments on commit 1fe891a

Please sign in to comment.