https://github.com/flinedev/laserfocuskit-swift
Utility library for calculations for applying the "Laser Focus" priority strategy.
https://github.com/flinedev/laserfocuskit-swift
Last synced: 8 months ago
JSON representation
Utility library for calculations for applying the "Laser Focus" priority strategy.
- Host: GitHub
- URL: https://github.com/flinedev/laserfocuskit-swift
- Owner: FlineDev
- License: gpl-3.0
- Created: 2021-09-25T10:19:32.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-08-03T11:53:44.000Z (9 months ago)
- Last Synced: 2025-08-17T10:08:29.587Z (8 months ago)
- Language: Swift
- Size: 48.8 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

# LaserFocusKit-Swift
Utility library for calculations when applying the [Laser Focus](https://dev.to/jeehut/laser-focus-priority-strategy-31ok) priority strategy.
## Usage

This library calculates the overall priority for a given graph of categorized actionable items, such as features or tasks. It supports any number of actionable item levels, e.g. you can provide an entire range of levels like "Epic", "Story", "Feature", "Task", "Sub-Task", "Step" as input. The main method takes just the top level ("Epic" in this case) and walks through the other children levels automatically.
For example, imagine you have the features "A", "B", and "C". Some of them have 3 tasks "1", "2", and "3". And some of the tasks have subtasks, "x", "y", and "z". So the input is this top level array with its children:
```swift
let inputs: [ActionableInput] = [
.init(name: "A", localCategory: .vital, children: [
.init(name: "A1", localCategory: .vital, children: [
.init(name: "A1x", localCategory: .vital),
.init(name: "A1y", localCategory: .essential),
.init(name: "A1z", localCategory: .completing)]
),
.init(name: "A2", localCategory: .essential),
.init(name: "A3", localCategory: .completing, children: [
.init(name: "A3x", localCategory: .vital),
.init(name: "A3y", localCategory: .essential),
.init(name: "A3z", localCategory: .completing)]
)]
),
.init(name: "B", localCategory: .optional, children: [
.init(name: "B1", localCategory: .vital),
.init(name: "B2", localCategory: .essential, children: [
.init(name: "B2x", localCategory: .vital),
.init(name: "B2y", localCategory: .retracting),
.init(name: "B2z", localCategory: .completing)]
)]
),
.init(name: "C", localCategory: .completing)
]
```
What we want to know in the Laser Focus strategy, is the global category for each "leaf" element in the graph, or the elements without children, the "atomic" elements, so to say. These elements are not further split(table) and can directly be worked on. Just calling the `LaserFocus.prioritizedAtoms(inputs:)` gives us exactly these elements:
```swift
let outputs: [ActionableOutput] = LaserFocus.prioritizedAtoms(inputs: inputs)
```
Each element in `ActionableOutput` has a `globalCategory` which includes the overall category of the atomic actionable, which serves as the primary prioritization point. Additionally, each `ActionableOutput` also has an `averageCategoryRawValue` numeric property which can be used to prioritize tasks with the same `globalCategory` for improved precision.
The simplest way to get the list of tasks in the correct priority order is to just call `sorted()` on the outputs as `ActionableOutput` is `Comparable`:
```swift
let sortedOutputs: [ActionableOutput] = outputs.sorted()
print(sortedOutputs.map(\.name)) // => ["A1x", "A1y", "A2", "A1z", "A3x", "A3y", "A3z", "C", "B2x", "B1", "B2z", "B2y"]
```
Note that both the input `ActionableInput` and output type `ActionableOutput` are `Codable` and can therefore be easily read from & written to JSON.