Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Pathfinder

This library was generated with Angular CLI version 7.2.0.

Summary

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran. The functionality will be described in regards to navigation, but the pathfinder service can be used on its own outside of the navigation scope.

Installation

npm install @softheon/pathfinder

Usage

The following sections will provide information code snippets on how to use and configure Pathfinder

Setup

First, the module must be imported into one of the existing modules in the project

import{PathfinderModule}from'@softheon/pathfinder';NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,PathfinderModule],providers: [],bootstrap: [AppComponent]})

This will initialize the PathfinderService and allow usage of any of the included components.

Configuration

This section will explain the configuration structure, and how to configure Pathfinder.

Terms

Path -- The main class for Pathfinder, the steps are all available states for the service

Step -- One step in the path, contains the information of the step and the conditions of where the step can lead to

Condition -- Logic for evaluating how to determine the next Step in the Path

Classes

Path
PropertyDescriptionType
snapshot$The observable of the snapshot of the pathObservable<Array<Step>>
stepsThe steps of the pathArray<Step>
Method NameDescriptionArgumentsReturn Type
updateSnapshotUpdates the snapshot with the current steps or provided stepssteps: Array<Step>void
Step
PropertyDescriptionType
idThe step id`string
labelThe text to display for the stepstring
isMainStepTrue if the step is a main step (navigation purposes)boolean
groupThe group the step is a part of (navigation purposes)`string
isStartTrue if the step is a start stepboolean
isEndTrue if the step is an end stepboolean
isCurrentTrue if the step is the current stepboolean
isCompleteTrue if the step has been completedboolean
conditionsThe array of conditions for determining what step is nextArray<Condition>
actionThe action used to get to the stepany
actionTypeThe action type used to get to the step`'route'
Condition
PropertyDescriptionType
stepIdThe id of the step the condition leads to`string
predicateTypeDetermines the type of logic being given for resolving the condition`'boolean'
predicateThe logic to be run to resolve the conditionunknown
actionThe action to take when a condition is resolved to trueany
actionTypeHow to run the provided action`'route'
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
ArrayCondition
PropertyDescriptionType
logicalOperatorsDetermines if all or some of the predicate conditions need to be met`'and'
predicateThe key values pairs to use for array matching{[ key: string ]: any}

Structure

The path class must be provided to the PathfinderService, currently, this done through the initialize function in the PathfinderService. it takes an argument of type Array<Step> which denotes all possible steps of the path. Each step contains an Array<Condition> which determines which step would be the next step in the Path. And example Step in JSON format is provided below.

{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
...
]
}

Every Step available to the Path is provided in the Steps property of the Path. The conditions denote where the step can lead and how to get there. Below is the same Step json except the conditions array has been populated.

"steps": [
{
"id": "begin",
"label": "Ascend",
"isMainStep": true,
"group": "group1",
"isStart": true,
"action": "/start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}
]
},
{
"id": "minor-passive-1",
"group": "group2",
"label": "Minor Passive 1",
"conditions": [
...
]
}
]

The way the above example is read is the 'begin' step has a condition that leads to the 'minor-passive-1' step. The 'minor-passive-1' step has been provided in the 'steps' which signifies all possible steps of the Path. It should be noted that a step can have multiple conditions and that conditions are evaluated in the order provided. The first condition that is evaluated to be true, will be the one used and conditions following that will not be run.

Condition Predicates

The predicate and predicateType properties of the condition are what Pathfinder uses to determine the next step. The available predicate types are:

  • boolean
  • object
  • function
Boolean

The boolean predicate type is a simple true or false conditional. The example condition shown below has boolean predicate type:

{
"stepId": "minor-passive-1",
"predicateType": "boolean",
"predicate": true,
"actionType": "route",
"action": "./minor-passive-1"
}

The above condition will always resolve to true, which means this predicate type should be used when a step only has one possible next step (linear) or as a fall back for if none of the previous conditions resolve to true (default).

Object

The object predicate type is a bit more complex. The PathfinderService has a data property. This property plays a key role in the object predicate type. The data property can be any object or any value and the predicate provides paths to values of the data property and values to compare them to. An example condition is shown below with a JSON snippet of the data for this path.

"condition": {
"stepId": "natures-reprisal",
"predicateType": "object",
"logicalOperator": "or",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
}
"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}

The above example is a condition regarding what is required to move to the natures-reprisal step. The selector in the condition follows the syntax used for accessing a JSON object. So first it will get the ability, then the damageTypes property. Since this property is an array, the predicate uses the ArrayCondition class. A logical operator is provided, in this case, and meaning all provided values must resolve to true when compared to the values in the data. An or logical operator means at least one of the provided values must resolve to true.

Translating to English, the data.ability.damageTypes list must contain an entry where the element property equals "poison" and the type property equals "dot" and the amount property is greater than 0. By fulfilling the requirements the condition will be resolved to true and the determined step will be the natures-reprisal step.

In order to get the data into the PathfinderService follow the code snippet bellow.

exportclassAppComponent{constructor(privatepathfinder: PathfinderService){this.pathfinder.path=// provide your path herethis.pathfinder.data=// provide your data herethis.pathfinder.initialize();}
...

Numbers -- when dealing with numbers, Pathfinder supports the following character preceding the number value

< -- Less than value

> -- Greater than value

<= -- Less than or equal to value

>= -- Greater than or equal to

! -- Not equal (also works for strings)

Function

The function predicateType allows for writing typescript arrow function directly in the predicate property. This predicateType also works off the data property of the PathfinderService. This type allows for the most customization but is also the hardest to use as it requires knowledge of the typescript/javascript language. An example condition is provided below. The function mirrors the logic defined in the example above but shows an alternate way of writing it. The same data is used for this example

"condition": {
"stepId": "natures-reprisal",
"predicateType": "function",
"predicate": "(context) => { return context.ability.damageTypes.findIndex(x => {x.element === 'poison' && x.type === 'dot' && x.amount > 0 }) > -1; }"
}

This condition has the same logic as the object predicateType example provided above except it uses the function predicateType note the use of the findIndex function of an array. This notation allows for extremely complex logic but requires knowledge of the language in order to utilize it. This predicate type is meant to fill in the gaps that the object predicate type can't fulfill and should be used only when needed.

Full Example

A complete navigation example is provided below with the example data, all from in JSON format so it can be loaded from a file or an API call.

"data": {
"ability" : {
"damageTypes": [
{
"element": "poison",
"type": "dot",
"amount": "9000"
}
]
}
}
"path": {
"steps": [
{
"id": "start",
"label": "Ascend",
"group": "group1",
"isStart": true,
"action": "./start",
"actionType": "route",
"conditions": [
{
"stepId": "minor-passive-1",
"predicateType": "object",
"logicalOperator": "or",
"action": "/minor-passive-1",
"actionType": "route",
"predicate": {
"ability.damageTypes": {
"logicalOperator": "and",
"predicate": {
"element": "poison",
"type": "dot",
"amount": ">0"
}
}
}
},
{
"stepId": "minor-passive-3",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-3",
"actionType": "route"
}
]
},
{
"id": "minor-passive-1",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "natures-reprisal",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-reprisal",
"actionType": "route"
}
]
},
{
"id": "natures-reprisal",
"label": "Nature's Reprisal",
"group": "group2",
"conditions": [
{
"stepId": "minor-passive-2",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-2",
"actionType": "route"
}
]
},
{
"id": "minor-passive-2",
"label": "Flask Effect, Chaos Damage",
"group": "group2",
"conditions": [
{
"stepId": "master-toxicist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-toxist",
"actionType": "route"
}
]
},
{
"id": "master-toxicist",
"label": "Master Toxicist",
"group": "group2",
"isEnd": true
},
{
"id": "minor-passive-3",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "natures-boon",
"predicateType": "boolean",
"predicate": true,
"action": "./natures-boon",
"actionType": "route"
}
]
},
{
"id": "natures-boon",
"label": "Nature's Boon",
"group": "group3",
"conditions": [
{
"stepId": "minor-passive-4",
"predicateType": "boolean",
"predicate": true,
"action": "./minor-passive-4",
"actionType": "route"
}
]
},
{
"id": "minor-passive-4",
"label": "Flask Effect and Charges Gained",
"group": "group3",
"conditions": [
{
"stepId": "master-alchemist",
"predicateType": "boolean",
"predicate": true,
"action": "./master-alchemist",
"actionType": "route"
}
]
},
{
"id": "master-alchemist",
"label": "Master Alchemist",
"group": "group3",
"isEnd": true
}
]
}

The figure below shows a visual representation of the path provided

Sample Path Visual

Action and Action Type

The action and actionType property control what should happen when the condition is resolved to true. The currently supported action types are listed below:

route -- Uses the angular router to navigate to the provided route, ex ./master-alchemist

internalPath -- Uses the base path of the site to navigation to the provide href, ex /some/url

externalUrl -- Opens a new tab with provided full URL, ex https://google.com

dummy -- skips the action and moves to the next step (allows for steps to show with out having actions)

Navfinder

The NavFinder component allows for a quick @softheon/workshop themed multi-stepper. This navigation is rendered off the provided path in the PathfinderService. Inputs can be found below:

NameDescriptionRequiredType
dataThe data to use for the PathfinderServiceTrueany
pathThe path to use for the navigationTruePath
navTextThe text that displays on top of the navigationFalsestring
currentMainStepIdHighlights the current main step based on provided valueFalse`string
skipAheadTrue if skip ahead is enabledFalseboolean

The nav finder component uses a snapshot of the current path to display the navigation. In order to navigate to the next step, the PathfinderService's takeStepForward() function can be used. This will advance the stepper and update the snapshot re-running all the logic to show a preview of the path.

About

Softheon Pathfinder is a deterministic finite automaton (DFA) based service that allows for highly configurable state logic to be provided and ran

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages