@argila/core 0.0.0-alpha-20250607064138

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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/dist/Argila.d.ts +24 -0
  3. package/dist/Argila.d.ts.map +1 -0
  4. package/dist/Argila.js +62 -0
  5. package/dist/Argila.test.d.ts +2 -0
  6. package/dist/Argila.test.d.ts.map +1 -0
  7. package/dist/Argila.test.js +150 -0
  8. package/dist/Canvas.d.ts +117 -0
  9. package/dist/Canvas.d.ts.map +1 -0
  10. package/dist/Canvas.js +311 -0
  11. package/dist/Canvas.test.d.ts +2 -0
  12. package/dist/Canvas.test.d.ts.map +1 -0
  13. package/dist/Canvas.test.js +311 -0
  14. package/dist/Common.d.ts +11 -0
  15. package/dist/Common.d.ts.map +1 -0
  16. package/dist/Common.js +64 -0
  17. package/dist/Common.test.js +118 -0
  18. package/dist/Event.d.ts +10 -0
  19. package/dist/Event.d.ts.map +1 -0
  20. package/dist/Event.js +23 -0
  21. package/dist/Event.test.js +72 -0
  22. package/dist/LinkedList.d.ts +44 -0
  23. package/dist/LinkedList.d.ts.map +1 -0
  24. package/dist/LinkedList.js +95 -0
  25. package/dist/LinkedList.test.d.ts +2 -0
  26. package/dist/LinkedList.test.d.ts.map +1 -0
  27. package/dist/LinkedList.test.js +197 -0
  28. package/dist/Vector3.d.ts +104 -0
  29. package/dist/Vector3.d.ts.map +1 -0
  30. package/dist/Vector3.js +185 -0
  31. package/dist/Vector3.test.d.ts +2 -0
  32. package/dist/Vector3.test.d.ts.map +1 -0
  33. package/dist/Vector3.test.js +127 -0
  34. package/dist/common.test.d.ts +2 -0
  35. package/dist/common.test.d.ts.map +1 -0
  36. package/dist/event.test.d.ts +2 -0
  37. package/dist/event.test.d.ts.map +1 -0
  38. package/dist/index.d.ts +29 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +41 -0
  41. package/dist/systems/Draw.d.ts +8 -0
  42. package/dist/systems/Draw.d.ts.map +1 -0
  43. package/dist/systems/Draw.js +15 -0
  44. package/dist/systems/Entity.d.ts +18 -0
  45. package/dist/systems/Entity.d.ts.map +1 -0
  46. package/dist/systems/Entity.js +44 -0
  47. package/dist/systems/Input.d.ts +127 -0
  48. package/dist/systems/Input.d.ts.map +1 -0
  49. package/dist/systems/Input.js +191 -0
  50. package/dist/systems/Loop.d.ts +29 -0
  51. package/dist/systems/Loop.d.ts.map +1 -0
  52. package/dist/systems/Loop.js +93 -0
  53. package/dist/systems/Render.d.ts +21 -0
  54. package/dist/systems/Render.d.ts.map +1 -0
  55. package/dist/systems/Render.js +112 -0
  56. package/dist/systems/Shape.d.ts +48 -0
  57. package/dist/systems/Shape.d.ts.map +1 -0
  58. package/dist/systems/Shape.js +146 -0
  59. package/dist/systems/System.d.ts +22 -0
  60. package/dist/systems/System.d.ts.map +1 -0
  61. package/dist/systems/System.js +20 -0
  62. package/dist/systems/World.d.ts +24 -0
  63. package/dist/systems/World.d.ts.map +1 -0
  64. package/dist/systems/World.js +84 -0
  65. package/dist/systems/debugs/Debug.d.ts +9 -0
  66. package/dist/systems/debugs/Debug.d.ts.map +1 -0
  67. package/dist/systems/debugs/Debug.js +12 -0
  68. package/dist/systems/debugs/InputDebug.d.ts +7 -0
  69. package/dist/systems/debugs/InputDebug.d.ts.map +1 -0
  70. package/dist/systems/debugs/InputDebug.js +11 -0
  71. package/dist/systems/debugs/LoopDebug.d.ts +7 -0
  72. package/dist/systems/debugs/LoopDebug.d.ts.map +1 -0
  73. package/dist/systems/debugs/LoopDebug.js +11 -0
  74. package/package.json +79 -0
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ import { it, expect } from "vitest";
3
+ import {
4
+ angle,
5
+ clamp,
6
+ degreesToRadians,
7
+ distance,
8
+ pair,
9
+ radiansToDegrees,
10
+ unpairX,
11
+ unpairY,
12
+ random
13
+ } from "./Common";
14
+ it("should clamp the number value", () => {
15
+ const valueA = clamp(10, 2, 6);
16
+ const valueB = clamp(-8, -6, -2);
17
+ expect(valueA).toBe(6);
18
+ expect(valueB).toBe(-6);
19
+ });
20
+ it("should calc the distance between two 2d vectors", () => {
21
+ const valueA = distance(100, 100, 100, 100);
22
+ const valueB = distance(100, 100, 300, 100);
23
+ expect(valueA).toBe(0);
24
+ expect(valueB).toBe(200);
25
+ });
26
+ it("should pair and unpair 2 numbers", () => {
27
+ const numberX = 10;
28
+ const numberY = 123;
29
+ const value = pair(numberX, numberY);
30
+ expect(unpairX(value)).toBe(numberX);
31
+ expect(unpairY(value)).toBe(numberY);
32
+ });
33
+ it("should pair and unpair two negative numbers", () => {
34
+ const numberX = -1230;
35
+ const numberY = -123;
36
+ const value = pair(numberX, numberY);
37
+ expect(unpairX(value)).toBe(numberX);
38
+ expect(unpairY(value)).toBe(numberY);
39
+ });
40
+ it("should convert degreesToRadians", () => {
41
+ const value = degreesToRadians(60);
42
+ expect(value).toBeCloseTo(1.0472);
43
+ });
44
+ it("should convert degreesToRadians", () => {
45
+ const value = radiansToDegrees(1.0472);
46
+ expect(value).toBeCloseTo(60);
47
+ });
48
+ it("should convert degreesToRadians", () => {
49
+ const value = radiansToDegrees(1.0472);
50
+ expect(value).toBeCloseTo(60);
51
+ });
52
+ it("should calc the angle between two 2d vectors", () => {
53
+ const value = angle(10, 10, 30, 100);
54
+ expect(value).toBeCloseTo(1.3522);
55
+ });
56
+ it("should generate a random number within the range", () => {
57
+ const min = 5;
58
+ const max = 10;
59
+ const value = random(min, max);
60
+ expect(value).toBeGreaterThanOrEqual(min);
61
+ expect(value).toBeLessThanOrEqual(max);
62
+ });
63
+ it("should resample if the random number is out of range", () => {
64
+ const min = 0;
65
+ const max = 1;
66
+ const skew = 1;
67
+ const spy = vi.spyOn(global.Math, "random").mockReturnValueOnce(1.1).mockReturnValueOnce(0.5);
68
+ const value = random(min, max, skew);
69
+ expect(value).toBeGreaterThanOrEqual(min);
70
+ expect(value).toBeLessThanOrEqual(max);
71
+ spy.mockRestore();
72
+ });
73
+ it("should generate a random number within the range with default skew", () => {
74
+ const min = 0;
75
+ const max = 1;
76
+ const value = random(min, max);
77
+ expect(value).toBeGreaterThanOrEqual(min);
78
+ expect(value).toBeLessThanOrEqual(max);
79
+ });
80
+ it("should generate a random number with skew", () => {
81
+ const min = 0;
82
+ const max = 1;
83
+ const skew = 2;
84
+ const value = random(min, max, skew);
85
+ expect(value).toBeGreaterThanOrEqual(min);
86
+ expect(value).toBeLessThanOrEqual(max);
87
+ });
88
+ it("should throw an error if min is greater than or equal to max", () => {
89
+ expect(() => random(10, 5)).toThrow("min must be less than max");
90
+ expect(() => random(5, 5)).toThrow("min must be less than max");
91
+ });
92
+ it("should throw an error if skew is less than or equal to 0", () => {
93
+ expect(() => random(0, 1, 0)).toThrow("skew must be greater than 0");
94
+ expect(() => random(0, 1, -1)).toThrow("skew must be greater than 0");
95
+ });
96
+ it("should generate a random number within the range with default skew", () => {
97
+ const min = 0;
98
+ const max = 1;
99
+ const value = random(min, max);
100
+ expect(value).toBeGreaterThanOrEqual(min);
101
+ expect(value).toBeLessThanOrEqual(max);
102
+ });
103
+ it("should generate a random number within the range with skew greater than 1", () => {
104
+ const min = 0;
105
+ const max = 1;
106
+ const skew = 3;
107
+ const value = random(min, max, skew);
108
+ expect(value).toBeGreaterThanOrEqual(min);
109
+ expect(value).toBeLessThanOrEqual(max);
110
+ });
111
+ it("should generate a random number within the range with skew less than 1", () => {
112
+ const min = 0;
113
+ const max = 1;
114
+ const skew = 0.5;
115
+ const value = random(min, max, skew);
116
+ expect(value).toBeGreaterThanOrEqual(min);
117
+ expect(value).toBeLessThanOrEqual(max);
118
+ });
@@ -0,0 +1,10 @@
1
+ export default class Event<T> {
2
+ name: string;
3
+ listeners: Set<(arg: T) => void>;
4
+ constructor(name: string);
5
+ fire(arg: T): void;
6
+ on(callback: (arg: T) => void): void;
7
+ off(callback: (arg: T) => void): void;
8
+ destroy(): void;
9
+ }
10
+ //# sourceMappingURL=Event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Event.d.ts","sourceRoot":"","sources":["../src/Event.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,KAAK,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;gBAErB,IAAI,EAAE,MAAM;IAKxB,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAMlB,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI;IAIpC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI;IAIrC,OAAO,IAAI,IAAI;CAGf"}
package/dist/Event.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ export default class Event {
3
+ name;
4
+ listeners;
5
+ constructor(name) {
6
+ this.name = name;
7
+ this.listeners = /* @__PURE__ */ new Set();
8
+ }
9
+ fire(arg) {
10
+ for (const callback of this.listeners) {
11
+ callback(arg);
12
+ }
13
+ }
14
+ on(callback) {
15
+ this.listeners.add(callback);
16
+ }
17
+ off(callback) {
18
+ this.listeners.delete(callback);
19
+ }
20
+ destroy() {
21
+ this.listeners.clear();
22
+ }
23
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ import { describe, it, expect } from "vitest";
3
+ import Event from "./Event";
4
+ describe("listener register", () => {
5
+ const event = new Event("hit");
6
+ event.on(() => {
7
+ });
8
+ event.on(() => {
9
+ });
10
+ it("should register the 2 listeners", () => {
11
+ expect(event.listeners.size).toBe(2);
12
+ });
13
+ });
14
+ describe("listener remove", () => {
15
+ const event = new Event("hit");
16
+ let calledInsideEvent = "banana";
17
+ const handleEvent = () => {
18
+ calledInsideEvent = "apple";
19
+ };
20
+ const handleEventTwo = () => {
21
+ calledInsideEvent = "pineapple";
22
+ };
23
+ event.on(handleEvent);
24
+ event.on(handleEventTwo);
25
+ event.off(handleEventTwo);
26
+ event.fire({ health: 100 });
27
+ it("should remove 1 listener", () => {
28
+ expect(event.listeners.size).toBe(1);
29
+ });
30
+ it("should remove the right listener", () => {
31
+ expect(calledInsideEvent).toBe("apple");
32
+ });
33
+ });
34
+ describe("fire event", () => {
35
+ const event = new Event("hit");
36
+ let count = 0;
37
+ event.on(() => {
38
+ count++;
39
+ });
40
+ event.on(() => {
41
+ count++;
42
+ });
43
+ event.fire({ health: 100 });
44
+ let maxHealth = 0;
45
+ event.on((data) => {
46
+ maxHealth += data.health;
47
+ });
48
+ event.fire({ health: 100 });
49
+ event.fire({ health: 20 });
50
+ event.fire({ health: 30 });
51
+ it("should fire the event two times", () => {
52
+ expect(count).toBe(8);
53
+ });
54
+ it("should fire the event with data", () => {
55
+ expect(maxHealth).toBe(150);
56
+ });
57
+ });
58
+ describe("destroy", () => {
59
+ const event = new Event("hit");
60
+ event.on(() => {
61
+ });
62
+ event.on(() => {
63
+ });
64
+ event.on(() => {
65
+ });
66
+ event.on(() => {
67
+ });
68
+ event.destroy();
69
+ it("should destroy all listeners", () => {
70
+ expect(event.listeners.size).toBe(0);
71
+ });
72
+ });
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Represents a node in a linked list.
3
+ */
4
+ export declare class LinkedNode<T> {
5
+ prev: LinkedNode<T> | null;
6
+ next: LinkedNode<T> | null;
7
+ data: T;
8
+ /**
9
+ * Creates a new LinkedNode.
10
+ * @param data - The data to store in the node.
11
+ */
12
+ constructor(data: T);
13
+ }
14
+ /**
15
+ * Represents a doubly linked list.
16
+ */
17
+ export default class LinkedList<T> {
18
+ head: LinkedNode<T> | null;
19
+ tail: LinkedNode<T> | null;
20
+ length: number;
21
+ /**
22
+ * Adds a new node with the given data to the end of the list.
23
+ * @param data - The data to add to the list.
24
+ */
25
+ push(data: T): void;
26
+ /**
27
+ * Removes and returns the data from the last node in the list.
28
+ * @returns The data from the last node, or null if the list is empty.
29
+ */
30
+ pop(): T | null;
31
+ /**
32
+ * Removes the specified node from the list.
33
+ * @param node - The node to remove.
34
+ * @throws Will throw an error if the node is null or undefined.
35
+ */
36
+ remove(node: LinkedNode<T>): void;
37
+ /**
38
+ * Finds and returns the first node containing the specified data.
39
+ * @param data - The data to find in the list.
40
+ * @returns The node containing the data, or null if no such node exists.
41
+ */
42
+ find(data: T): LinkedNode<T> | null;
43
+ }
44
+ //# sourceMappingURL=LinkedList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkedList.d.ts","sourceRoot":"","sources":["../src/LinkedList.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAU,CAAC,CAAC;IAEvB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAQ;IAElC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAQ;IAElC,IAAI,EAAE,CAAC,CAAC;IAER;;;OAGG;gBACS,IAAI,EAAE,CAAC;CAIpB;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,CAAC;IAE/B,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAQ;IAElC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAQ;IAElC,MAAM,SAAK;IAEX;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAkBnB;;;OAGG;IACH,GAAG,IAAI,CAAC,GAAG,IAAI;IAaf;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI;IAwCjC;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI;CAcpC"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ export class LinkedNode {
3
+ // Previous node in the list
4
+ prev = null;
5
+ // Next node in the list
6
+ next = null;
7
+ // Data stored in the node
8
+ data;
9
+ /**
10
+ * Creates a new LinkedNode.
11
+ * @param data - The data to store in the node.
12
+ */
13
+ constructor(data) {
14
+ this.data = data;
15
+ }
16
+ }
17
+ export default class LinkedList {
18
+ // First node in the list
19
+ head = null;
20
+ // Last node in the list
21
+ tail = null;
22
+ // Number of nodes in the list
23
+ length = 0;
24
+ /**
25
+ * Adds a new node with the given data to the end of the list.
26
+ * @param data - The data to add to the list.
27
+ */
28
+ push(data) {
29
+ const node = new LinkedNode(data);
30
+ if (this.tail) {
31
+ node.prev = this.tail;
32
+ this.tail.next = node;
33
+ this.tail = node;
34
+ } else {
35
+ this.head = this.tail = node;
36
+ }
37
+ this.length++;
38
+ }
39
+ /**
40
+ * Removes and returns the data from the last node in the list.
41
+ * @returns The data from the last node, or null if the list is empty.
42
+ */
43
+ pop() {
44
+ if (!this.tail) {
45
+ return null;
46
+ }
47
+ const data = this.tail.data;
48
+ this.remove(this.tail);
49
+ return data;
50
+ }
51
+ /**
52
+ * Removes the specified node from the list.
53
+ * @param node - The node to remove.
54
+ * @throws Will throw an error if the node is null or undefined.
55
+ */
56
+ remove(node) {
57
+ if (!node) {
58
+ throw new Error("Node to be removed is null or undefined");
59
+ }
60
+ const prev = node.prev;
61
+ const next = node.next;
62
+ if (this.head === node) {
63
+ this.head = next;
64
+ }
65
+ if (this.tail === node) {
66
+ this.tail = prev;
67
+ }
68
+ if (prev) {
69
+ prev.next = next;
70
+ }
71
+ if (next) {
72
+ next.prev = prev;
73
+ }
74
+ if (this.length === 1) {
75
+ this.head = this.tail = null;
76
+ }
77
+ node.prev = node.next = null;
78
+ this.length--;
79
+ }
80
+ /**
81
+ * Finds and returns the first node containing the specified data.
82
+ * @param data - The data to find in the list.
83
+ * @returns The node containing the data, or null if no such node exists.
84
+ */
85
+ find(data) {
86
+ let current = this.head;
87
+ while (current) {
88
+ if (current.data === data) {
89
+ return current;
90
+ }
91
+ current = current.next;
92
+ }
93
+ return null;
94
+ }
95
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=LinkedList.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkedList.test.d.ts","sourceRoot":"","sources":["../src/LinkedList.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ import LinkedList, { LinkedNode } from "./LinkedList";
3
+ describe("LinkedList", () => {
4
+ let list;
5
+ let node1;
6
+ let node2;
7
+ let node3;
8
+ beforeEach(() => {
9
+ list = new LinkedList();
10
+ node1 = new LinkedNode("node1");
11
+ node2 = new LinkedNode("node2");
12
+ node3 = new LinkedNode("node3");
13
+ });
14
+ test("push should add nodes to the list", () => {
15
+ list.push(node1.data);
16
+ expect(list.head?.data).toBe(node1.data);
17
+ expect(list.tail?.data).toBe(node1.data);
18
+ expect(list.length).toBe(1);
19
+ list.push(node2.data);
20
+ expect(list.head?.data).toBe(node1.data);
21
+ expect(list.tail?.data).toBe(node2.data);
22
+ expect(list.length).toBe(2);
23
+ list.push(node3.data);
24
+ expect(list.head?.data).toBe(node1.data);
25
+ expect(list.tail?.data).toBe(node3.data);
26
+ expect(list.length).toBe(3);
27
+ });
28
+ test("pop should remove the last node from the list", () => {
29
+ list.push(node1.data);
30
+ list.push(node2.data);
31
+ list.push(node3.data);
32
+ list.pop();
33
+ expect(list.tail?.data).toBe(node2.data);
34
+ expect(list.length).toBe(2);
35
+ list.pop();
36
+ expect(list.tail?.data).toBe(node1.data);
37
+ expect(list.length).toBe(1);
38
+ list.pop();
39
+ expect(list.tail).toBeNull();
40
+ expect(list.head).toBeNull();
41
+ expect(list.length).toBe(0);
42
+ });
43
+ test("remove should remove a specific node from the list", () => {
44
+ list.push(node1.data);
45
+ list.push(node2.data);
46
+ list.push(node3.data);
47
+ const nodeToRemove = list.find(node2.data);
48
+ if (nodeToRemove) {
49
+ list.remove(nodeToRemove);
50
+ }
51
+ expect(list.head?.data).toBe(node1.data);
52
+ expect(list.tail?.data).toBe(node3.data);
53
+ expect(list.length).toBe(2);
54
+ expect(list.head?.next?.data).toBe(node3.data);
55
+ expect(list.tail?.prev?.data).toBe(node1.data);
56
+ const nodeToRemove2 = list.find(node1.data);
57
+ if (nodeToRemove2) {
58
+ list.remove(nodeToRemove2);
59
+ }
60
+ expect(list.head?.data).toBe(node3.data);
61
+ expect(list.tail?.data).toBe(node3.data);
62
+ expect(list.length).toBe(1);
63
+ const nodeToRemove3 = list.find(node3.data);
64
+ if (nodeToRemove3) {
65
+ list.remove(nodeToRemove3);
66
+ }
67
+ expect(list.head).toBeNull();
68
+ expect(list.tail).toBeNull();
69
+ expect(list.length).toBe(0);
70
+ });
71
+ test("push should handle multiple nodes correctly", () => {
72
+ const nodes = Array.from(
73
+ { length: 1e3 },
74
+ (_, i) => new LinkedNode(`node${i}`)
75
+ );
76
+ nodes.forEach((node) => list.push(node.data));
77
+ expect(list.length).toBe(1e3);
78
+ expect(list.head?.data).toBe(nodes[0].data);
79
+ expect(list.tail?.data).toBe(nodes[999].data);
80
+ });
81
+ test("pop should handle multiple nodes correctly", () => {
82
+ const nodes = Array.from(
83
+ { length: 1e3 },
84
+ (_, i) => new LinkedNode(`node${i}`)
85
+ );
86
+ nodes.forEach((node) => list.push(node.data));
87
+ for (let i = 999; i >= 0; i--) {
88
+ list.pop();
89
+ expect(list.length).toBe(i);
90
+ if (i > 0) {
91
+ expect(list.tail?.data).toBe(nodes[i - 1].data);
92
+ } else {
93
+ expect(list.tail).toBeNull();
94
+ expect(list.head).toBeNull();
95
+ }
96
+ }
97
+ });
98
+ test("remove should handle multiple nodes correctly", () => {
99
+ const nodes = Array.from(
100
+ { length: 1e3 },
101
+ (_, i) => new LinkedNode(`node${i}`)
102
+ );
103
+ nodes.forEach((node) => list.push(node.data));
104
+ nodes.forEach((node, i) => {
105
+ const nodeToRemove = list.find(node.data);
106
+ if (nodeToRemove) {
107
+ list.remove(nodeToRemove);
108
+ }
109
+ expect(list.length).toBe(999 - i);
110
+ if (i < 999) {
111
+ expect(list.head?.data).toBe(nodes[i + 1].data);
112
+ } else {
113
+ expect(list.head).toBeNull();
114
+ expect(list.tail).toBeNull();
115
+ }
116
+ });
117
+ });
118
+ test("remove should handle head and tail correctly", () => {
119
+ list.push(node1.data);
120
+ list.push(node2.data);
121
+ list.push(node3.data);
122
+ const nodeToRemove = list.find(node1.data);
123
+ if (nodeToRemove) {
124
+ list.remove(nodeToRemove);
125
+ }
126
+ expect(list.head?.data).toBe(node2.data);
127
+ expect(list.tail?.data).toBe(node3.data);
128
+ expect(list.length).toBe(2);
129
+ const nodeToRemove2 = list.find(node3.data);
130
+ if (nodeToRemove2) {
131
+ list.remove(nodeToRemove2);
132
+ }
133
+ expect(list.head?.data).toBe(node2.data);
134
+ expect(list.tail?.data).toBe(node2.data);
135
+ expect(list.length).toBe(1);
136
+ const nodeToRemove3 = list.find(node2.data);
137
+ if (nodeToRemove3) {
138
+ list.remove(nodeToRemove3);
139
+ }
140
+ expect(list.head).toBeNull();
141
+ expect(list.tail).toBeNull();
142
+ expect(list.length).toBe(0);
143
+ });
144
+ test("push and pop should handle stress test", () => {
145
+ const nodes = Array.from(
146
+ { length: 1e4 },
147
+ (_, i) => new LinkedNode(`node${i}`)
148
+ );
149
+ nodes.forEach((node) => list.push(node.data));
150
+ expect(list.length).toBe(1e4);
151
+ nodes.forEach(() => list.pop());
152
+ expect(list.length).toBe(0);
153
+ expect(list.head).toBeNull();
154
+ expect(list.tail).toBeNull();
155
+ });
156
+ test("find should return the correct node", () => {
157
+ list.push(node1.data);
158
+ list.push(node2.data);
159
+ list.push(node3.data);
160
+ expect(list.find("node1")?.data).toBe("node1");
161
+ expect(list.find("node2")?.data).toBe("node2");
162
+ expect(list.find("node3")?.data).toBe("node3");
163
+ expect(list.find("nonexistent")).toBeNull();
164
+ });
165
+ test("remove should throw an error if node is null or undefined", () => {
166
+ expect(() => list.remove(null)).toThrow(
167
+ "Node to be removed is null or undefined"
168
+ );
169
+ expect(() => list.remove(void 0)).toThrow(
170
+ "Node to be removed is null or undefined"
171
+ );
172
+ });
173
+ test("pop should return the correct data", () => {
174
+ list.push(node1.data);
175
+ list.push(node2.data);
176
+ list.push(node3.data);
177
+ expect(list.pop()).toBe("node3");
178
+ expect(list.pop()).toBe("node2");
179
+ expect(list.pop()).toBe("node1");
180
+ expect(list.pop()).toBeNull();
181
+ });
182
+ test("find should handle an empty list", () => {
183
+ expect(list.find("node1")).toBeNull();
184
+ });
185
+ test("push should handle a single node", () => {
186
+ list.push(node1.data);
187
+ expect(list.head).toBe(list.tail);
188
+ expect(list.length).toBe(1);
189
+ });
190
+ test("pop should handle a single node", () => {
191
+ list.push(node1.data);
192
+ expect(list.pop()).toBe("node1");
193
+ expect(list.head).toBeNull();
194
+ expect(list.tail).toBeNull();
195
+ expect(list.length).toBe(0);
196
+ });
197
+ });
@@ -0,0 +1,104 @@
1
+ interface IVector3 {
2
+ x: number;
3
+ y: number;
4
+ z: number;
5
+ }
6
+ /**
7
+ * Class representing a 3D vector and operations on it.
8
+ */
9
+ export default class Vector3 {
10
+ private static vectors;
11
+ private static vectorPool;
12
+ /**
13
+ * Creates a new vector and stores it in the map.
14
+ * @param entity - The entity identifier.
15
+ * @param x - The x component of the vector.
16
+ * @param y - The y component of the vector.
17
+ * @param z - The z component of the vector.
18
+ * @returns The unique ID of the created vector.
19
+ */
20
+ static create(entity: string, x: number, y: number, z: number): string;
21
+ /**
22
+ * Retrieves a vector by its entity identifier.
23
+ * @param entity - The entity identifier.
24
+ * @returns The vector associated with the entity, or undefined if not found.
25
+ */
26
+ static get(entity: string): IVector3 | undefined;
27
+ /**
28
+ * Validates if a vector exists.
29
+ * @param vector - The vector to validate.
30
+ * @throws Will throw an error if the vector is not found.
31
+ */
32
+ private static validateVector;
33
+ /**
34
+ * Sets the components of a vector.
35
+ * @param entity - The entity identifier.
36
+ * @param x - The new x component.
37
+ * @param y - The new y component.
38
+ * @param z - The new z component.
39
+ */
40
+ static set(entity: string, x: number, y: number, z: number): void;
41
+ /**
42
+ * Adds values to the components of a vector.
43
+ * @param entity - The entity identifier.
44
+ * @param x - The value to add to the x component.
45
+ * @param y - The value to add to the y component.
46
+ * @param z - The value to add to the z component.
47
+ */
48
+ static add(entity: string, x: number, y: number, z: number): void;
49
+ /**
50
+ * Subtracts values from the components of a vector.
51
+ * @param entity - The entity identifier.
52
+ * @param x - The value to subtract from the x component.
53
+ * @param y - The value to subtract from the y component.
54
+ * @param z - The value to subtract from the z component.
55
+ */
56
+ static subtract(entity: string, x: number, y: number, z: number): void;
57
+ /**
58
+ * Multiplies the components of a vector by given values.
59
+ * @param entity - The entity identifier.
60
+ * @param x - The value to multiply the x component by.
61
+ * @param y - The value to multiply the y component by.
62
+ * @param z - The value to multiply the z component by.
63
+ */
64
+ static multiply(entity: string, x: number, y: number, z: number): void;
65
+ /**
66
+ * Divides the components of a vector by given values.
67
+ * @param entity - The entity identifier.
68
+ * @param x - The value to divide the x component by.
69
+ * @param y - The value to divide the y component by.
70
+ * @param z - The value to divide the z component by.
71
+ * @throws Will throw an error if any of the values are zero.
72
+ */
73
+ static divide(entity: string, x: number, y: number, z: number): void;
74
+ /**
75
+ * Calculates the magnitude (length) of a vector.
76
+ * @param entity - The entity identifier.
77
+ * @returns The magnitude of the vector.
78
+ */
79
+ static magnitude(entity: string): number;
80
+ /**
81
+ * Normalizes the vector to have a magnitude of 1.
82
+ * @param entity - The entity identifier.
83
+ * @throws Will throw an error if the vector is a zero vector.
84
+ */
85
+ static normalize(entity: string): void;
86
+ /**
87
+ * Calculates the dot product of two vectors.
88
+ * @param entity1 - The first entity identifier.
89
+ * @param entity2 - The second entity identifier.
90
+ * @returns The dot product of the two vectors.
91
+ */
92
+ static dotProduct(entity1: string, entity2: string): number;
93
+ /**
94
+ * Removes a vector from the map and returns it to the pool.
95
+ * @param entity - The entity identifier.
96
+ */
97
+ static destroy(entity: string): void;
98
+ /**
99
+ * Clears all vectors from the map and returns them to the pool.
100
+ */
101
+ static clear(): void;
102
+ }
103
+ export {};
104
+ //# sourceMappingURL=Vector3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Vector3.d.ts","sourceRoot":"","sources":["../src/Vector3.ts"],"names":[],"mappings":"AAGA,UAAU,QAAQ;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,OAAO;IAE1B,OAAO,CAAC,MAAM,CAAC,OAAO,CAAgD;IAEtE,OAAO,CAAC,MAAM,CAAC,UAAU,CAA0C;IAEnE;;;;;;;OAOG;WACW,MAAM,CAClB,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,MAAM;IAoBT;;;;OAIG;WACW,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAKvD;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAM7B;;;;;;OAMG;WACW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IASxE;;;;;;OAMG;WACW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IASxE;;;;;;OAMG;WACW,QAAQ,CACpB,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,IAAI;IASP;;;;;;OAMG;WACW,QAAQ,CACpB,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,IAAI;IASP;;;;;;;OAOG;WACW,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAa3E;;;;OAIG;WACW,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAW/C;;;;OAIG;WACW,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAc7C;;;;;OAKG;WACW,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAalE;;;OAGG;WACW,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ3C;;OAEG;WACW,KAAK,IAAI,IAAI;CAM5B"}