@inglorious/utils 3.7.0 → 3.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,86 +1,86 @@
1
- # Inglorious Utils
2
-
3
- [![NPM version](https://img.shields.io/npm/v/@inglorious/utils.svg)](https://www.npmjs.com/package/@inglorious/utils)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
-
6
- A set of general-purpose utility functions designed with functional programming principles in mind. This package is part of the [Inglorious Engine](https://github.com/IngloriousCoderz/inglorious-engine) monorepo.
7
-
8
- ---
9
-
10
- ## Overview
11
-
12
- This package provides a collection of pure, composable helper functions to streamline development in any JavaScript or TypeScript project. It embraces a data-oriented and functional approach, operating on plain data structures like objects and arrays.
13
-
14
- ---
15
-
16
- ## Installation
17
-
18
- ```bash
19
- npm install @inglorious/utils
20
- ```
21
-
22
- ---
23
-
24
- ## Usage
25
-
26
- Here are a few examples of how you can use the utilities in this package.
27
-
28
- ### `pipe`
29
-
30
- Compose functions together in a readable, left-to-right sequence.
31
-
32
- ```javascript
33
- import { pipe } from "@inglorious/utils/functions/functions"
34
-
35
- const add = (a) => (b) => a + b
36
- const multiply = (a) => (b) => a * b
37
-
38
- const calculate = pipe(
39
- add(5), // 10 + 5 = 15
40
- multiply(2), // 15 * 2 = 30
41
- add(10), // 30 + 10 = 40
42
- )
43
-
44
- const result = calculate(10) // 40
45
- ```
46
-
47
- ### Vector Math
48
-
49
- Perform vector operations on plain objects.
50
-
51
- ```javascript
52
- import { add } from "@inglorious/utils/math/vector.js"
53
-
54
- const position = [10, 20]
55
- const velocity = [2, -1]
56
-
57
- const newPosition = add(position, velocity)
58
- // => [12, 19]
59
- ```
60
-
61
- ---
62
-
63
- ## API
64
-
65
- This package is designed to be used with subpath imports, which helps with tree-shaking.
66
-
67
- - **`@inglorious/utils/algorithms`**: Utilities for AI algorithms, like decision trees and A\*.
68
- - **`@inglorious/utils/functions`**: Utilities for function composition.
69
- - **`@inglorious/utils/math`**: Utilities for math operations.
70
- - **`@inglorious/utils/physics`**: Utilities for calculations on friction, acceleration, and gravity.
71
-
72
- ---
73
-
74
- ## License
75
-
76
- **MIT License - Free and open source**
77
-
78
- Created by [Matteo Antony Mistretta](https://github.com/IngloriousCoderz)
79
-
80
- You're free to use, modify, and distribute this software. See [LICENSE](./LICENSE) for details.
81
-
82
- ---
83
-
84
- ## Contributing
85
-
86
- We welcome contributions! Please see the root `CONTRIBUTING.md` file for more details.
1
+ # Inglorious Utils
2
+
3
+ [![NPM version](https://img.shields.io/npm/v/@inglorious/utils.svg)](https://www.npmjs.com/package/@inglorious/utils)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A set of general-purpose utility functions designed with functional programming principles in mind. This package is part of the [Inglorious Forge](https://github.com/IngloriousCoderz/inglorious-forge) monorepo.
7
+
8
+ ---
9
+
10
+ ## Overview
11
+
12
+ This package provides a collection of pure, composable helper functions to streamline development in any JavaScript or TypeScript project. It embraces a data-oriented and functional approach, operating on plain data structures like objects and arrays.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @inglorious/utils
20
+ ```
21
+
22
+ ---
23
+
24
+ ## Usage
25
+
26
+ Here are a few examples of how you can use the utilities in this package.
27
+
28
+ ### `pipe`
29
+
30
+ Compose functions together in a readable, left-to-right sequence.
31
+
32
+ ```javascript
33
+ import { pipe } from "@inglorious/utils/functions/functions"
34
+
35
+ const add = (a) => (b) => a + b
36
+ const multiply = (a) => (b) => a * b
37
+
38
+ const calculate = pipe(
39
+ add(5), // 10 + 5 = 15
40
+ multiply(2), // 15 * 2 = 30
41
+ add(10), // 30 + 10 = 40
42
+ )
43
+
44
+ const result = calculate(10) // 40
45
+ ```
46
+
47
+ ### Vector Math
48
+
49
+ Perform vector operations on plain objects.
50
+
51
+ ```javascript
52
+ import { add } from "@inglorious/utils/math/vector.js"
53
+
54
+ const position = [10, 20]
55
+ const velocity = [2, -1]
56
+
57
+ const newPosition = add(position, velocity)
58
+ // => [12, 19]
59
+ ```
60
+
61
+ ---
62
+
63
+ ## API
64
+
65
+ This package is designed to be used with subpath imports, which helps with tree-shaking.
66
+
67
+ - **`@inglorious/utils/algorithms`**: Utilities for AI algorithms, like decision trees and A\*.
68
+ - **`@inglorious/utils/functions`**: Utilities for function composition.
69
+ - **`@inglorious/utils/math`**: Utilities for math operations.
70
+ - **`@inglorious/utils/physics`**: Utilities for calculations on friction, acceleration, and gravity.
71
+
72
+ ---
73
+
74
+ ## License
75
+
76
+ **MIT License - Free and open source**
77
+
78
+ Created by [Matteo Antony Mistretta](https://github.com/IngloriousCoderz)
79
+
80
+ You're free to use, modify, and distribute this software. See [LICENSE](./LICENSE) for details.
81
+
82
+ ---
83
+
84
+ ## Contributing
85
+
86
+ We welcome contributions! Please see the root `CONTRIBUTING.md` file for more details.
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@inglorious/utils",
3
- "version": "3.7.0",
3
+ "version": "3.7.2",
4
4
  "description": "A set of general-purpose utility functions designed with functional programming principles in mind.",
5
5
  "author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/IngloriousCoderz/inglorious-engine.git",
9
+ "url": "git+https://github.com/IngloriousCoderz/inglorious-forge.git",
10
10
  "directory": "packages/utils"
11
11
  },
12
12
  "homepage": "https://inglorious-engine.vercel.app/",
13
13
  "bugs": {
14
- "url": "https://github.com/IngloriousCoderz/inglorious-engine/issues"
14
+ "url": "https://github.com/IngloriousCoderz/inglorious-forge/issues"
15
15
  },
16
16
  "keywords": [
17
17
  "functional-programming",
@@ -33,7 +33,8 @@
33
33
  },
34
34
  "files": [
35
35
  "src",
36
- "types"
36
+ "types",
37
+ "!src/**/*.test.js"
37
38
  ],
38
39
  "publishConfig": {
39
40
  "access": "public"
@@ -42,14 +43,14 @@
42
43
  "prettier": "^3.6.2",
43
44
  "vite": "^7.1.3",
44
45
  "vitest": "^1.6.1",
45
- "@inglorious/eslint-config": "1.0.1"
46
+ "@inglorious/eslint-config": "1.1.1"
46
47
  },
47
48
  "engines": {
48
49
  "node": ">= 22"
49
50
  },
50
51
  "scripts": {
51
- "format": "prettier --write '**/*.{js,jsx}'",
52
- "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
52
+ "format": "prettier --write .",
53
+ "lint": "eslint .",
53
54
  "test:watch": "vitest",
54
55
  "test": "vitest run"
55
56
  }
@@ -24,7 +24,7 @@ const NEXT_LEVEL = 2
24
24
  * @returns {T} A deep clone of the input value.
25
25
  */
26
26
  export function clone(obj) {
27
- return structuredClone(obj)
27
+ return deserialize(serialize(obj))
28
28
  }
29
29
 
30
30
  /**
@@ -1,154 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { length } from "../math/vector.js"
4
- import { subtract } from "../math/vectors.js"
5
- import { v } from "../v.js"
6
- import { decide } from "./decision-tree.js"
7
-
8
- test("it should make a decision based on a binary decision tree", () => {
9
- const entity = { state: "sleeping", position: v(0, 0, 0) }
10
- const target = { position: v(10, 0, 0) }
11
- const tree = {
12
- test({ entity }) {
13
- return entity.state === "idle"
14
- },
15
- true() {
16
- return {
17
- test({ entity, target }) {
18
- const distance = length(subtract(target.position, entity.position))
19
- return distance < 250
20
- },
21
- true() {
22
- return "aware"
23
- },
24
- }
25
- },
26
- false() {
27
- return {
28
- test({ entity }) {
29
- return entity.state === "chasing"
30
- },
31
- true() {
32
- return {
33
- test({ entity, target }) {
34
- const distance = length(
35
- subtract(target.position, entity.position),
36
- )
37
- return distance >= 250
38
- },
39
- true() {
40
- return "idle"
41
- },
42
- false() {
43
- return {
44
- test({ entity, target }) {
45
- const distance = length(
46
- subtract(target.position, entity.position),
47
- )
48
- return distance < 10
49
- },
50
- true() {
51
- return "sleepy"
52
- },
53
- }
54
- },
55
- }
56
- },
57
- false() {
58
- return {
59
- test({ entity }) {
60
- return ["sleepy", "sleeping"].includes(entity.state)
61
- },
62
- true() {
63
- return {
64
- test({ entity, target }) {
65
- const distance = length(
66
- subtract(target.position, entity.position),
67
- )
68
- return distance >= 10
69
- },
70
- true() {
71
- return "aware"
72
- },
73
- }
74
- },
75
- }
76
- },
77
- }
78
- },
79
- }
80
-
81
- const state = decide(tree, { entity, target })
82
-
83
- expect(state).toBe("aware")
84
- })
85
-
86
- test("it should make a decision on a multi-child tree", () => {
87
- const entity = { state: "sleeping", position: v(0, 0, 0) }
88
- const target = { position: v(10, 0, 0) }
89
- const wakeUp = () => ({
90
- test({ entity, target }) {
91
- const distance = length(subtract(target.position, entity.position))
92
- return distance >= 10
93
- },
94
- true() {
95
- return "aware"
96
- },
97
- false({ entity }) {
98
- return entity.state
99
- },
100
- })
101
-
102
- const tree = {
103
- test({ entity }) {
104
- return entity.state
105
- },
106
- idle() {
107
- return {
108
- test({ entity, target }) {
109
- const distance = length(subtract(target.position, entity.position))
110
- return distance < 250
111
- },
112
- true() {
113
- return "aware"
114
- },
115
- false({ entity }) {
116
- return entity.state
117
- },
118
- }
119
- },
120
- chasing() {
121
- return {
122
- test({ entity, target }) {
123
- const distance = length(subtract(target.position, entity.position))
124
- return distance >= 250
125
- },
126
- true() {
127
- return "idle"
128
- },
129
- false() {
130
- return {
131
- test({ entity, target }) {
132
- const distance = length(
133
- subtract(target.position, entity.position),
134
- )
135
- return distance < 10
136
- },
137
- true() {
138
- return "sleepy"
139
- },
140
- false({ entity }) {
141
- return entity.state
142
- },
143
- }
144
- },
145
- }
146
- },
147
- sleepy: wakeUp,
148
- sleeping: wakeUp,
149
- }
150
-
151
- const state = decide(tree, { entity, target })
152
-
153
- expect(state).toBe("aware")
154
- })
@@ -1,151 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import {
4
- createBoard,
5
- down,
6
- downRight,
7
- right,
8
- } from "../data-structures/board.js"
9
- import { findPath } from "./path-finding.js"
10
-
11
- test("it should find the shortest path in a trivial example", () => {
12
- const graph = {
13
- nodes: {
14
- A: [0, 0],
15
- B: [2, 0],
16
- },
17
- arcs: [{ from: "A", to: "B", cost: 2 }],
18
- }
19
- const start = "A"
20
- const end = "B"
21
- const expectedResult = ["A", "B"]
22
-
23
- expect(findPath(graph, start, end)).toStrictEqual(expectedResult)
24
- })
25
-
26
- test("it should find the shortest path between two nodes with default heuristic", () => {
27
- const graph = {
28
- nodes: {
29
- A: [0, 0],
30
- B: [2, 0],
31
- C: [3, 2],
32
- D: [4, 4],
33
- E: [1, 1],
34
- F: [2, 3],
35
- G: [0, 4],
36
- },
37
- arcs: [
38
- { from: "A", to: "B" },
39
- { from: "B", to: "C" },
40
- { from: "C", to: "D" },
41
- { from: "A", to: "E" },
42
- { from: "E", to: "F" },
43
- { from: "F", to: "G" },
44
- { from: "G", to: "D" },
45
- ],
46
- }
47
- const start = "A"
48
- const end = "D"
49
- const expectedResult = ["A", "B", "C", "D"]
50
-
51
- expect(findPath(graph, start, end)).toStrictEqual(expectedResult)
52
- })
53
-
54
- test("it should find the shortest path between two nodes with node costs", () => {
55
- const graph = {
56
- nodes: [
57
- { id: "A", position: [0, 0], cost: 0 },
58
- { id: "B", position: [2, 0], cost: 7 },
59
- { id: "C", position: [3, 2], cost: 3 },
60
- { id: "D", position: [4, 4], cost: 2 },
61
- { id: "E", position: [1, 1], cost: 1.5 },
62
- { id: "F", position: [2, 3], cost: 2 },
63
- { id: "G", position: [0, 4], cost: 3 },
64
- ],
65
- arcs: [
66
- { from: "A", to: "B" },
67
- { from: "B", to: "C" },
68
- { from: "C", to: "D" },
69
- { from: "A", to: "E" },
70
- { from: "E", to: "F" },
71
- { from: "F", to: "G" },
72
- { from: "G", to: "D" },
73
- ],
74
- }
75
- const start = "A"
76
- const end = "D"
77
- const expectedResult = ["A", "E", "F", "G", "D"]
78
-
79
- expect(findPath(graph, start, end)).toStrictEqual(expectedResult)
80
- })
81
-
82
- test("it should find the shortest path between two nodes with arc costs", () => {
83
- const graph = {
84
- nodes: {
85
- A: [0, 0],
86
- B: [2, 0],
87
- C: [3, 2],
88
- D: [4, 4],
89
- E: [1, 1],
90
- F: [2, 3],
91
- G: [0, 4],
92
- },
93
- arcs: [
94
- { from: "A", to: "B", cost: 7 },
95
- { from: "B", to: "C", cost: 3 },
96
- { from: "C", to: "D", cost: 2 },
97
- { from: "A", to: "E", cost: 1.5 },
98
- { from: "E", to: "F", cost: 2 },
99
- { from: "F", to: "G", cost: 3 },
100
- { from: "G", to: "D", cost: 4 },
101
- ],
102
- }
103
- const start = "A"
104
- const end = "D"
105
- const expectedResult = ["A", "E", "F", "G", "D"]
106
-
107
- expect(findPath(graph, start, end)).toStrictEqual(expectedResult)
108
- })
109
-
110
- test("it should find the best path in a board graph", () => {
111
- const rows = 5
112
- const columns = 5
113
- const size = [rows, columns]
114
- const filler = (i, j) => ({ id: `${i}${j}`, position: [i, j] })
115
- const board = createBoard(size, filler)
116
-
117
- const graph = {
118
- nodes: board,
119
- arcs: [],
120
- }
121
-
122
- for (let i = 0; i < rows; i++) {
123
- for (let j = 0; j < columns; j++) {
124
- const current = `${i}${j}`
125
- if (i + 1 < rows) {
126
- graph.arcs.push({
127
- from: current,
128
- to: down([i, j], size).join(""),
129
- })
130
- }
131
- if (j + 1 < columns) {
132
- graph.arcs.push({
133
- from: current,
134
- to: right([i, j], size).join(""),
135
- })
136
- }
137
- if (i + 1 < rows && j + 1 < columns) {
138
- graph.arcs.push({
139
- from: current,
140
- to: downRight([i, j], size).join(""),
141
- })
142
- }
143
- }
144
- }
145
-
146
- const start = "00"
147
- const end = "44"
148
- const expectedResult = ["00", "11", "22", "33", "44"]
149
-
150
- expect(findPath(graph, start, end)).toStrictEqual(expectedResult)
151
- })