@argila/matter 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.
- package/LICENSE +21 -0
- package/dist/Matter.d.ts +17 -0
- package/dist/Matter.d.ts.map +1 -0
- package/dist/Matter.js +61 -0
- package/dist/Matter.test.d.ts +2 -0
- package/dist/Matter.test.d.ts.map +1 -0
- package/dist/Matter.test.js +32 -0
- package/dist/Render.d.ts +19 -0
- package/dist/Render.d.ts.map +1 -0
- package/dist/Render.js +99 -0
- package/dist/Render.test.d.ts +2 -0
- package/dist/Render.test.d.ts.map +1 -0
- package/dist/Render.test.js +29 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 Eduardo Lopes
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/Matter.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { System } from "@argila/core";
|
|
2
|
+
import * as MatterJS from "matter-js";
|
|
3
|
+
interface MatterConfig {
|
|
4
|
+
engine: MatterJS.Engine;
|
|
5
|
+
entities?: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
export default class Matter extends System {
|
|
8
|
+
static id: string;
|
|
9
|
+
static list: Map<string, MatterConfig>;
|
|
10
|
+
static loopType: "single" | "entity";
|
|
11
|
+
static create(world: string): MatterJS.Engine;
|
|
12
|
+
static add(world: string, entity: string, options?: MatterJS.Composites): MatterJS.Body[];
|
|
13
|
+
static tick(dt: number): void;
|
|
14
|
+
static clear(): void;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=Matter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Matter.d.ts","sourceRoot":"","sources":["../src/Matter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAC;AAEtC,UAAU,YAAY;IACpB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,MAAM;IACxC,OAAc,EAAE,SAAmB;IAEnC,OAAc,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAa;IAC1D,OAAc,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAY;WAEzC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM;WAWtC,GAAG,CACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,QAAQ,CAAC,UAAU,GAC5B,QAAQ,CAAC,IAAI,EAAE;WA0CJ,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;WAQtB,KAAK,IAAI,IAAI;CAQ5B"}
|
package/dist/Matter.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { Entity, Shape, System } from "@argila/core";
|
|
3
|
+
import * as MatterJS from "matter-js";
|
|
4
|
+
export default class Matter extends System {
|
|
5
|
+
static id = "matter-render";
|
|
6
|
+
static list = /* @__PURE__ */ new Map();
|
|
7
|
+
static loopType = "single";
|
|
8
|
+
static create(world) {
|
|
9
|
+
const engine = MatterJS.Engine.create();
|
|
10
|
+
Matter.list.set(world, { engine, entities: /* @__PURE__ */ new Set() });
|
|
11
|
+
engine.gravity.x = 0;
|
|
12
|
+
engine.gravity.y = 1;
|
|
13
|
+
return engine;
|
|
14
|
+
}
|
|
15
|
+
static add(world, entity, options) {
|
|
16
|
+
const config = Matter.list.get(world);
|
|
17
|
+
const e = Entity.get(entity);
|
|
18
|
+
const bodies = [];
|
|
19
|
+
if (!config) {
|
|
20
|
+
return bodies;
|
|
21
|
+
}
|
|
22
|
+
if (e) {
|
|
23
|
+
config?.entities?.add(e.id);
|
|
24
|
+
const shapes = Shape.get(e.id);
|
|
25
|
+
shapes?.forEach((shape) => {
|
|
26
|
+
let body = null;
|
|
27
|
+
if (Shape.isCircle(shape)) {
|
|
28
|
+
body = MatterJS.Bodies.circle(0, 0, shape.radius, options);
|
|
29
|
+
}
|
|
30
|
+
if (Shape.isRectangle(shape)) {
|
|
31
|
+
body = MatterJS.Bodies.rectangle(
|
|
32
|
+
0,
|
|
33
|
+
0,
|
|
34
|
+
shape.width,
|
|
35
|
+
shape.height,
|
|
36
|
+
options
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (body) {
|
|
40
|
+
body.label = e.id;
|
|
41
|
+
MatterJS.World.addBody(config.engine.world, body);
|
|
42
|
+
bodies.push(body);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return bodies;
|
|
47
|
+
}
|
|
48
|
+
static tick(dt) {
|
|
49
|
+
const delta = Math.min(dt * 1e3, 1e3 / 60);
|
|
50
|
+
this.list.forEach((config) => {
|
|
51
|
+
MatterJS.Engine.update(config.engine, delta);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
static clear() {
|
|
55
|
+
Matter.list.forEach((item) => {
|
|
56
|
+
MatterJS.World.clear(item.engine.world, false);
|
|
57
|
+
MatterJS.Engine.clear(item.engine);
|
|
58
|
+
});
|
|
59
|
+
Matter.list.clear();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Matter.test.d.ts","sourceRoot":"","sources":["../src/Matter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
3
|
+
import Matter from "./Matter";
|
|
4
|
+
import * as MatterJS from "matter-js";
|
|
5
|
+
describe("Matter", () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
Matter.clear();
|
|
8
|
+
});
|
|
9
|
+
it("should create a new Matter engine", () => {
|
|
10
|
+
const engine = Matter.create("world1");
|
|
11
|
+
expect(engine).toBeDefined();
|
|
12
|
+
expect(Matter.list.has("world1")).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it("should update the Matter engine", () => {
|
|
15
|
+
const engine = Matter.create("world1");
|
|
16
|
+
vi.spyOn(MatterJS.Engine, "update").mockImplementation(vi.fn());
|
|
17
|
+
Matter.tick(0.016);
|
|
18
|
+
expect(MatterJS.Engine.update).toHaveBeenCalledWith(
|
|
19
|
+
engine,
|
|
20
|
+
expect.any(Number)
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
it("should clear all Matter engines and worlds", () => {
|
|
24
|
+
const engine = Matter.create("world1");
|
|
25
|
+
vi.spyOn(MatterJS.World, "clear").mockImplementation(vi.fn());
|
|
26
|
+
vi.spyOn(MatterJS.Engine, "clear").mockImplementation(vi.fn());
|
|
27
|
+
Matter.clear();
|
|
28
|
+
expect(MatterJS.World.clear).toHaveBeenCalledWith(engine.world, false);
|
|
29
|
+
expect(MatterJS.Engine.clear).toHaveBeenCalledWith(engine);
|
|
30
|
+
expect(Matter.list.size).toBe(0);
|
|
31
|
+
});
|
|
32
|
+
});
|
package/dist/Render.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { System } from "@argila/core";
|
|
2
|
+
interface RenderConfig {
|
|
3
|
+
canvasID: string;
|
|
4
|
+
}
|
|
5
|
+
export default class Render implements System {
|
|
6
|
+
static id: string;
|
|
7
|
+
static loopType: "single" | "entity";
|
|
8
|
+
static list: Map<string, RenderConfig>;
|
|
9
|
+
static create(entity: string, canvasID: string): void;
|
|
10
|
+
static tick(): void;
|
|
11
|
+
static has(entity: string): boolean;
|
|
12
|
+
static set(entity: string, canvasID?: string): void;
|
|
13
|
+
static setCanvas(entity: string, canvasID?: string): void;
|
|
14
|
+
static get(config: string): RenderConfig | undefined;
|
|
15
|
+
static destroy(config: string): void;
|
|
16
|
+
static clear(): void;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=Render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Render.d.ts","sourceRoot":"","sources":["../src/Render.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAGP,MAAM,cAAc,CAAC;AAItB,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,CAAC,OAAO,OAAO,MAAO,YAAW,MAAM;IAC3C,MAAM,CAAC,EAAE,SAAY;IACrB,OAAc,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAY;IAEvD,OAAc,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAa;WAE5C,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;WAM9C,IAAI,IAAI,IAAI;WAoDZ,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;WAQ5B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;WAY5C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;WAYlD,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;WAI7C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;WAI7B,KAAK,IAAI,IAAI;CAM5B"}
|
package/dist/Render.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
Canvas,
|
|
4
|
+
Shape,
|
|
5
|
+
Render as ArgilaRender,
|
|
6
|
+
Entity
|
|
7
|
+
} from "@argila/core";
|
|
8
|
+
import * as MatterJS from "matter-js";
|
|
9
|
+
import Matter from "./Matter";
|
|
10
|
+
export default class Render {
|
|
11
|
+
static id = "render";
|
|
12
|
+
static loopType = "single";
|
|
13
|
+
static list = /* @__PURE__ */ new Map();
|
|
14
|
+
static create(entity, canvasID) {
|
|
15
|
+
Render.list.set(entity, {
|
|
16
|
+
canvasID
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
static tick() {
|
|
20
|
+
Matter.list.forEach((config) => {
|
|
21
|
+
const bodies = MatterJS.Composite.allBodies(config.engine.world);
|
|
22
|
+
const ctx = Canvas.get("main")?.ctx;
|
|
23
|
+
if (ctx) {
|
|
24
|
+
ctx.save();
|
|
25
|
+
bodies.forEach((body) => {
|
|
26
|
+
const entity = Entity.get(body.label);
|
|
27
|
+
if (!entity)
|
|
28
|
+
return;
|
|
29
|
+
const shapes = Shape.get(entity.id);
|
|
30
|
+
if (!shapes)
|
|
31
|
+
return;
|
|
32
|
+
shapes.forEach((shape) => {
|
|
33
|
+
if (body.circleRadius && shape && Shape.isCircle(shape)) {
|
|
34
|
+
ArgilaRender.drawCircle(
|
|
35
|
+
ctx,
|
|
36
|
+
shape,
|
|
37
|
+
body.position.x,
|
|
38
|
+
body.position.y
|
|
39
|
+
);
|
|
40
|
+
} else if (shape && (Shape.isRectangle(shape) || Shape.isPolygon(shape))) {
|
|
41
|
+
ctx.beginPath();
|
|
42
|
+
const vertices = body.vertices;
|
|
43
|
+
ctx.moveTo(vertices[0].x, vertices[0].y);
|
|
44
|
+
for (let j = 1; j < vertices.length; j += 1) {
|
|
45
|
+
ctx.lineTo(vertices[j].x, vertices[j].y);
|
|
46
|
+
}
|
|
47
|
+
ctx.lineTo(vertices[0].x, vertices[0].y);
|
|
48
|
+
ctx.closePath();
|
|
49
|
+
}
|
|
50
|
+
ctx.fillStyle = shape?.fillColor ?? "#000";
|
|
51
|
+
ctx.fill();
|
|
52
|
+
ctx.lineWidth = shape?.strokeWidth ?? 1;
|
|
53
|
+
if (shape?.strokeColor) {
|
|
54
|
+
ctx.strokeStyle = shape?.strokeColor;
|
|
55
|
+
ctx.stroke();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
ctx.restore();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
static has(entity) {
|
|
64
|
+
if (!this.list) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return this.list.has(entity);
|
|
68
|
+
}
|
|
69
|
+
static set(entity, canvasID) {
|
|
70
|
+
const config = Render.list.get(entity);
|
|
71
|
+
if (!config) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (canvasID) {
|
|
75
|
+
config.canvasID = canvasID;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
static setCanvas(entity, canvasID) {
|
|
79
|
+
const config = Render.list.get(entity);
|
|
80
|
+
if (!config) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (canvasID) {
|
|
84
|
+
config.canvasID = canvasID;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
static get(config) {
|
|
88
|
+
return Render.list.get(config);
|
|
89
|
+
}
|
|
90
|
+
static destroy(config) {
|
|
91
|
+
Render.list.delete(config);
|
|
92
|
+
}
|
|
93
|
+
static clear() {
|
|
94
|
+
Render.list.clear();
|
|
95
|
+
Render.list.forEach((_, key) => {
|
|
96
|
+
Render.destroy(key);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Render.test.d.ts","sourceRoot":"","sources":["../src/Render.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
3
|
+
import Render from "./Render";
|
|
4
|
+
describe("Render", () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
Render.clear();
|
|
7
|
+
});
|
|
8
|
+
it("should create a new render config", () => {
|
|
9
|
+
Render.create("entity1", "canvas1");
|
|
10
|
+
expect(Render.has("entity1")).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
it("should set a canvas ID", () => {
|
|
13
|
+
Render.create("entity1", "canvas1");
|
|
14
|
+
Render.set("entity1", "canvas2");
|
|
15
|
+
expect(Render.get("entity1")?.canvasID).toBe("canvas2");
|
|
16
|
+
});
|
|
17
|
+
it("should delete a render config", () => {
|
|
18
|
+
Render.create("entity1", "canvas1");
|
|
19
|
+
Render.destroy("entity1");
|
|
20
|
+
expect(Render.has("entity1")).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
it("should clear all render configs", () => {
|
|
23
|
+
Render.create("entity1", "canvas1");
|
|
24
|
+
Render.create("entity2", "canvas2");
|
|
25
|
+
Render.clear();
|
|
26
|
+
expect(Render.has("entity1")).toBe(false);
|
|
27
|
+
expect(Render.has("entity2")).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,OAAO,EACN,MAAM,EACN,MAAM,EACN,CAAC"}
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@argila/matter",
|
|
3
|
+
"version": "0.0.0-alpha-20250607064138",
|
|
4
|
+
"description": "Matterjs implementation to be used with argila",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist",
|
|
7
|
+
"LICENSE",
|
|
8
|
+
"README.md",
|
|
9
|
+
"package.json"
|
|
10
|
+
],
|
|
11
|
+
"typesVersions": {
|
|
12
|
+
"*": {
|
|
13
|
+
"*": [
|
|
14
|
+
"./dist/*",
|
|
15
|
+
"./dist/index.d.ts"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./dist/index.js",
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"lint-staged": {
|
|
26
|
+
"*.{ts}": [
|
|
27
|
+
"npx rome check"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/EduardoLopes/argila.git"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"game",
|
|
36
|
+
"engine"
|
|
37
|
+
],
|
|
38
|
+
"author": "Eduardo <EduardoLopesDS@gmail.com> (http://eduardolopes.dev.br)",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/EduardoLopes/argila/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/EduardoLopes/argila#readme",
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/matter-js": "^0.19.6",
|
|
46
|
+
"@types/uuid": "^9.0.8",
|
|
47
|
+
"@vitest/ui": "^1.5.2",
|
|
48
|
+
"del-cli": "^5.1.0",
|
|
49
|
+
"esbuild": "^0.20.2",
|
|
50
|
+
"glob": "^10.3.12",
|
|
51
|
+
"lint-staged": "^15.2.2",
|
|
52
|
+
"matter-js": "^0.19.0",
|
|
53
|
+
"nodemon": "^3.1.0",
|
|
54
|
+
"rome": "^12.1.3",
|
|
55
|
+
"type-fest": "^4.17.0",
|
|
56
|
+
"typedoc": "^0.25.13",
|
|
57
|
+
"typedoc-plugin-missing-exports": "^2.2.0",
|
|
58
|
+
"typescript": "^5.4.5",
|
|
59
|
+
"vitest": "^1.5.2",
|
|
60
|
+
"@argila/core": "^0.0.0-alpha-20250607064138"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"@argila/core": "0.0.0-alpha-20250607064138",
|
|
64
|
+
"matter-js": "^0.18.0"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"uuid": "^9.0.1"
|
|
68
|
+
},
|
|
69
|
+
"directories": {
|
|
70
|
+
"doc": "docs",
|
|
71
|
+
"test": "tests"
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"dev": "concurrently \"tsc -w\" \"nodemon esbuild.config.js\"",
|
|
75
|
+
"build": "node esbuild.config.js && tsc",
|
|
76
|
+
"watch:types": "tsc -w",
|
|
77
|
+
"clean": "rm -rf dist",
|
|
78
|
+
"test": "vitest --coverage",
|
|
79
|
+
"test:watch": "vitest",
|
|
80
|
+
"docs:build": "typedoc src/index.ts --excludeInternal",
|
|
81
|
+
"docs:serve": "python3 -m http.server -d ./docs"
|
|
82
|
+
}
|
|
83
|
+
}
|