pixi-watchface-engine 0.1.11 → 0.2.1

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/API.md CHANGED
@@ -9,6 +9,7 @@
9
9
  5. [Plugins](#plugins)
10
10
  6. [Events](#events)
11
11
  7. [Types](#types)
12
+ 8. [Display Geometry](#display-geometry)
12
13
 
13
14
  ---
14
15
 
@@ -734,6 +735,34 @@ interface Bounds {
734
735
 
735
736
  ---
736
737
 
738
+ ## Display Geometry
739
+
740
+ Display geometry describes the face's logical shape and dimensions separately
741
+ from the editor's pixel dimensions. The geometry helpers are device-independent;
742
+ they accept circular and rectangular profiles without inferring a shape.
743
+
744
+ ```typescript
745
+ const geometry = { shape: 'rectangle', width: 448, height: 486 } as const;
746
+ const fitted = fitDisplayGeometry(geometry, {
747
+ x: 0, y: 0, width: 600, height: 600, // editor bounds, not logical face size
748
+ });
749
+ const editorPoint = displayToViewportPoint(
750
+ { x: 224, y: 243 }, geometry, fitted,
751
+ );
752
+ const hit = isPointInDisplay({ x: 0, y: 0 }, geometry); // true for rectangles
753
+ ```
754
+
755
+ `fitDisplayGeometry` centers the logical display in editor bounds and uses one
756
+ uniform scale. `displayToViewportPoint` and `viewportToDisplayPoint` convert
757
+ coordinates while preserving either the default `top-left` or `center` origin.
758
+ `isPointInDisplay` uses rectangular bounds or the circular visible boundary.
759
+ `createDisplayMask` creates a Pixi `Graphics` mask for the same shape;
760
+ `applyDisplayMask` attaches one to a container and returns it for cleanup.
761
+ Circular profiles must have equal positive width and height. Invalid dimensions
762
+ and unknown shapes throw instead of silently selecting a default.
763
+
764
+ ---
765
+
737
766
  ## Complete Example
738
767
 
739
768
  ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"TextElement.d.ts","sourceRoot":"","sources":["../../src/elements/TextElement.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TextElement.d.ts","sourceRoot":"","sources":["../../src/elements/TextElement.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { Container, Graphics } from 'pixi.js';
2
+ import type { Bounds, CoordinateOrigin } from '../types.ts';
3
+ /** Display shape supported by watch-face geometry. */
4
+ export type DisplayShape = 'circle' | 'rectangle';
5
+ /** Logical display dimensions, independent of an editor's pixel dimensions. */
6
+ export interface DisplayGeometry {
7
+ shape: DisplayShape;
8
+ width: number;
9
+ height: number;
10
+ }
11
+ export interface DisplayPoint {
12
+ x: number;
13
+ y: number;
14
+ }
15
+ /** A display's fitted rectangle in the editor, plus its uniform scale. */
16
+ export interface DisplayViewport extends Bounds {
17
+ scale: number;
18
+ }
19
+ /**
20
+ * Check and narrow geometry received from saved data or device integrations.
21
+ * Circular displays use a square logical coordinate space.
22
+ */
23
+ export declare function validateDisplayGeometry(value: unknown): asserts value is DisplayGeometry;
24
+ /** Return logical display bounds for the requested coordinate origin. */
25
+ export declare function getDisplayBounds(geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): Bounds;
26
+ /**
27
+ * Fit a logical display inside an editor-space rectangle without distortion.
28
+ * The returned bounds are centered in the editor rectangle; the editor
29
+ * rectangle is never interpreted as the face's logical dimensions.
30
+ */
31
+ export declare function fitDisplayGeometry(geometry: DisplayGeometry, editorBounds: Bounds): DisplayViewport;
32
+ /** Convert a logical face coordinate to the fitted editor viewport. */
33
+ export declare function displayToViewportPoint(point: DisplayPoint, geometry: DisplayGeometry, viewport: DisplayViewport, coordinateOrigin?: CoordinateOrigin): DisplayPoint;
34
+ /** Convert a fitted editor-space point to logical face coordinates. */
35
+ export declare function viewportToDisplayPoint(point: DisplayPoint, geometry: DisplayGeometry, viewport: DisplayViewport, coordinateOrigin?: CoordinateOrigin): DisplayPoint;
36
+ /** Test whether a logical coordinate falls inside the visible display shape. */
37
+ export declare function isPointInDisplay(point: DisplayPoint, geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): boolean;
38
+ /**
39
+ * Create a Pixi mask matching the visible display shape. Add the returned
40
+ * Graphics to the masked container (or a sibling in the same coordinate
41
+ * space) and assign it as that container's mask.
42
+ */
43
+ export declare function createDisplayMask(geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): Graphics;
44
+ /** Attach a shape-aware Pixi mask and return it for later removal/destruction. */
45
+ export declare function applyDisplayMask(target: Container, geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): Graphics;
46
+ //# sourceMappingURL=DisplayGeometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DisplayGeometry.d.ts","sourceRoot":"","sources":["../../src/geometry/DisplayGeometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5D,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAElD,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,0EAA0E;AAC1E,MAAM,WAAW,eAAgB,SAAQ,MAAM;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,eAAe,CAkBxF;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,MAAM,CASR;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,MAAM,GACnB,eAAe,CAcjB;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,YAAY,CASd;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,YAAY,CASd;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,OAAO,CAcT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,QAAQ,CAUV;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,QAAQ,CAKV"}
package/dist/index.d.ts CHANGED
@@ -25,6 +25,8 @@ export { ZOrderManager } from "./managers/ZOrderManager.ts";
25
25
  export { SelectionManager } from "./selection/SelectionManager.ts";
26
26
  export { SerializationManager } from "./managers/SerializationManager.ts";
27
27
  export type { FillDirection, ShapeType, LineCap, ArcPath, ElementType, CoordinateOrigin, SerializedElement, WatchfaceState, UndoableAction, HandleConfig, Bounds, } from "./types.ts";
28
+ export { applyDisplayMask, createDisplayMask, displayToViewportPoint, fitDisplayGeometry, getDisplayBounds, isPointInDisplay, validateDisplayGeometry, viewportToDisplayPoint, } from "./geometry/DisplayGeometry.ts";
29
+ export type { DisplayGeometry, DisplayPoint, DisplayShape, DisplayViewport, } from "./geometry/DisplayGeometry.ts";
28
30
  export { EventBus } from "./EventBus.ts";
29
31
  export type { EngineEventMap } from "./EventBus.ts";
30
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1E,YAAY,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1E,YAAY,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -31266,6 +31266,7 @@ class TextElement extends BaseElement {
31266
31266
  s2.wordWrap = value != null;
31267
31267
  s2.wordWrapWidth = value ?? 100;
31268
31268
  });
31269
+ this.redraw();
31269
31270
  this.emitChange("boxWidth", old, value);
31270
31271
  }
31271
31272
  get breakWords() {
@@ -34796,7 +34797,131 @@ class AlignmentGuidesPlugin {
34796
34797
  this.graphics.destroy();
34797
34798
  }
34798
34799
  }
34800
+ // src/geometry/DisplayGeometry.ts
34801
+ function validateDisplayGeometry(value) {
34802
+ if (typeof value !== "object" || value === null) {
34803
+ throw new TypeError("Display geometry must be an object.");
34804
+ }
34805
+ const geometry = value;
34806
+ if (geometry.shape !== "circle" && geometry.shape !== "rectangle") {
34807
+ throw new TypeError(`Unsupported display shape: ${String(geometry.shape)}.`);
34808
+ }
34809
+ if (typeof geometry.width !== "number" || !Number.isFinite(geometry.width) || geometry.width <= 0) {
34810
+ throw new RangeError("Display geometry width must be a positive finite number.");
34811
+ }
34812
+ if (typeof geometry.height !== "number" || !Number.isFinite(geometry.height) || geometry.height <= 0) {
34813
+ throw new RangeError("Display geometry height must be a positive finite number.");
34814
+ }
34815
+ if (geometry.shape === "circle" && geometry.width !== geometry.height) {
34816
+ throw new RangeError("Circular display geometry must have equal width and height.");
34817
+ }
34818
+ }
34819
+ function getDisplayBounds(geometry, coordinateOrigin = "top-left") {
34820
+ validateDisplayGeometry(geometry);
34821
+ validateCoordinateOrigin(coordinateOrigin);
34822
+ return {
34823
+ x: coordinateOrigin === "center" ? -geometry.width / 2 : 0,
34824
+ y: coordinateOrigin === "center" ? -geometry.height / 2 : 0,
34825
+ width: geometry.width,
34826
+ height: geometry.height
34827
+ };
34828
+ }
34829
+ function fitDisplayGeometry(geometry, editorBounds) {
34830
+ validateDisplayGeometry(geometry);
34831
+ validateBounds(editorBounds, "Editor bounds");
34832
+ const scale = Math.min(editorBounds.width / geometry.width, editorBounds.height / geometry.height);
34833
+ const width = geometry.width * scale;
34834
+ const height = geometry.height * scale;
34835
+ return {
34836
+ x: editorBounds.x + (editorBounds.width - width) / 2,
34837
+ y: editorBounds.y + (editorBounds.height - height) / 2,
34838
+ width,
34839
+ height,
34840
+ scale
34841
+ };
34842
+ }
34843
+ function displayToViewportPoint(point, geometry, viewport, coordinateOrigin = "top-left") {
34844
+ validateDisplayGeometry(geometry);
34845
+ validateViewport(viewport);
34846
+ validatePoint(point, "Display point");
34847
+ const bounds = getDisplayBounds(geometry, coordinateOrigin);
34848
+ return {
34849
+ x: viewport.x + (point.x - bounds.x) * viewport.scale,
34850
+ y: viewport.y + (point.y - bounds.y) * viewport.scale
34851
+ };
34852
+ }
34853
+ function viewportToDisplayPoint(point, geometry, viewport, coordinateOrigin = "top-left") {
34854
+ validateDisplayGeometry(geometry);
34855
+ validateViewport(viewport);
34856
+ validatePoint(point, "Viewport point");
34857
+ const bounds = getDisplayBounds(geometry, coordinateOrigin);
34858
+ return {
34859
+ x: bounds.x + (point.x - viewport.x) / viewport.scale,
34860
+ y: bounds.y + (point.y - viewport.y) / viewport.scale
34861
+ };
34862
+ }
34863
+ function isPointInDisplay(point, geometry, coordinateOrigin = "top-left") {
34864
+ validateDisplayGeometry(geometry);
34865
+ validatePoint(point, "Display point");
34866
+ const bounds = getDisplayBounds(geometry, coordinateOrigin);
34867
+ if (geometry.shape === "rectangle") {
34868
+ return point.x >= bounds.x && point.x <= bounds.x + bounds.width && point.y >= bounds.y && point.y <= bounds.y + bounds.height;
34869
+ }
34870
+ const centerX = bounds.x + bounds.width / 2;
34871
+ const centerY = bounds.y + bounds.height / 2;
34872
+ const radius = geometry.width / 2;
34873
+ return (point.x - centerX) ** 2 + (point.y - centerY) ** 2 <= radius ** 2;
34874
+ }
34875
+ function createDisplayMask(geometry, coordinateOrigin = "top-left") {
34876
+ const bounds = getDisplayBounds(geometry, coordinateOrigin);
34877
+ const mask = new Graphics;
34878
+ if (geometry.shape === "circle") {
34879
+ mask.circle(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, bounds.width / 2);
34880
+ } else {
34881
+ mask.rect(bounds.x, bounds.y, bounds.width, bounds.height);
34882
+ }
34883
+ mask.fill({ color: 16777215 });
34884
+ return mask;
34885
+ }
34886
+ function applyDisplayMask(target, geometry, coordinateOrigin = "top-left") {
34887
+ const mask = createDisplayMask(geometry, coordinateOrigin);
34888
+ target.addChild(mask);
34889
+ target.mask = mask;
34890
+ return mask;
34891
+ }
34892
+ function validateCoordinateOrigin(value) {
34893
+ if (value !== "top-left" && value !== "center") {
34894
+ throw new TypeError(`Unsupported coordinate origin: ${String(value)}.`);
34895
+ }
34896
+ }
34897
+ function validatePoint(point, label) {
34898
+ if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) {
34899
+ throw new RangeError(`${label} coordinates must be finite numbers.`);
34900
+ }
34901
+ }
34902
+ function validateBounds(bounds, label) {
34903
+ if (!Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) {
34904
+ throw new RangeError(`${label} position must use finite numbers.`);
34905
+ }
34906
+ if (!Number.isFinite(bounds.width) || bounds.width <= 0 || !Number.isFinite(bounds.height) || bounds.height <= 0) {
34907
+ throw new RangeError(`${label} width and height must be positive finite numbers.`);
34908
+ }
34909
+ }
34910
+ function validateViewport(viewport) {
34911
+ validateBounds(viewport, "Viewport bounds");
34912
+ if (!Number.isFinite(viewport.scale) || viewport.scale <= 0) {
34913
+ throw new RangeError("Viewport scale must be a positive finite number.");
34914
+ }
34915
+ }
34799
34916
  export {
34917
+ viewportToDisplayPoint,
34918
+ validateDisplayGeometry,
34919
+ isPointInDisplay,
34920
+ getDisplayBounds,
34921
+ fitDisplayGeometry,
34922
+ displayToViewportPoint,
34923
+ createDisplayMask,
34924
+ applyDisplayMask,
34800
34925
  ZOrderManager,
34801
34926
  WatchfaceEngine,
34802
34927
  ViewportPlugin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-watchface-engine",
3
- "version": "0.1.11",
3
+ "version": "0.2.1",
4
4
  "description": "A PixiJS v8 watchface editor engine with visual editor, plugin system, and intuitive API",
5
5
  "author": "Eric Schmar (ericschmar@gmail.com)",
6
6
  "type": "module",
@@ -20,6 +20,7 @@
20
20
  "LICENSE"
21
21
  ],
22
22
  "scripts": {
23
+ "test": "bun test",
23
24
  "typecheck": "tsc --noEmit",
24
25
  "build": "bun build src/index.ts --outdir dist --target browser && tsc --emitDeclarationOnly --declaration",
25
26
  "prepublishOnly": "bun run typecheck && bun run build"