@ue-too/board 0.9.5 → 0.11.0

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 (57) hide show
  1. package/README.md +66 -2
  2. package/boardify/index.d.ts +280 -9
  3. package/camera/base.d.ts +364 -68
  4. package/camera/camera-edge-auto-input.d.ts +105 -0
  5. package/camera/camera-mux/animation-and-lock/animation-and-lock.d.ts +316 -14
  6. package/camera/camera-mux/animation-and-lock/index.d.ts +27 -0
  7. package/camera/camera-mux/animation-and-lock/pan-control-state-machine.d.ts +143 -60
  8. package/camera/camera-mux/animation-and-lock/rotation-control-state-machine.d.ts +143 -55
  9. package/camera/camera-mux/animation-and-lock/zoom-control-state-machine.d.ts +205 -58
  10. package/camera/camera-mux/index.d.ts +26 -0
  11. package/camera/camera-mux/interface.d.ts +161 -5
  12. package/camera/camera-mux/relay.d.ts +79 -16
  13. package/camera/camera-rig/camera-rig.d.ts +536 -94
  14. package/camera/camera-rig/index.d.ts +26 -1
  15. package/camera/camera-rig/pan-handler.d.ts +508 -48
  16. package/camera/camera-rig/rotation-handler.d.ts +353 -31
  17. package/camera/camera-rig/zoom-handler.d.ts +369 -32
  18. package/camera/default-camera.d.ts +173 -26
  19. package/camera/index.d.ts +20 -0
  20. package/camera/interface.d.ts +202 -2
  21. package/camera/update-publisher.d.ts +128 -38
  22. package/camera/utils/coordinate-conversion.d.ts +323 -26
  23. package/camera/utils/index.d.ts +22 -0
  24. package/camera/utils/matrix.d.ts +217 -14
  25. package/camera/utils/position.d.ts +249 -11
  26. package/camera/utils/rotation.d.ts +139 -9
  27. package/camera/utils/zoom.d.ts +72 -4
  28. package/index.d.ts +37 -0
  29. package/index.js +2 -4796
  30. package/index.js.map +39 -38
  31. package/input-interpretation/index.d.ts +29 -0
  32. package/input-interpretation/input-orchestrator.d.ts +197 -0
  33. package/input-interpretation/input-state-machine/index.d.ts +18 -0
  34. package/input-interpretation/input-state-machine/kmt-input-context.d.ts +191 -38
  35. package/input-interpretation/input-state-machine/kmt-input-state-machine.d.ts +201 -85
  36. package/input-interpretation/input-state-machine/touch-input-context.d.ts +76 -10
  37. package/input-interpretation/input-state-machine/touch-input-state-machine.d.ts +138 -17
  38. package/input-interpretation/raw-input-parser/index.d.ts +19 -0
  39. package/input-interpretation/raw-input-parser/vanilla-kmt-event-parser.d.ts +107 -21
  40. package/input-interpretation/raw-input-parser/vanilla-touch-event-parser.d.ts +71 -8
  41. package/input-interpretation/raw-input-publisher/index.d.ts +18 -0
  42. package/input-interpretation/raw-input-publisher/raw-input-publisher.d.ts +133 -37
  43. package/package.json +3 -3
  44. package/utils/canvas-position-dimension.d.ts +282 -1
  45. package/utils/coordinate-conversions/canvas-viewport.d.ts +79 -0
  46. package/utils/coordinate-conversions/viewport-world.d.ts +101 -0
  47. package/utils/coordinate-conversions/window-canvas.d.ts +90 -0
  48. package/utils/coorindate-conversion.d.ts +91 -0
  49. package/utils/drawing.d.ts +151 -3
  50. package/utils/index.d.ts +21 -0
  51. package/utils/observable.d.ts +179 -0
  52. package/utils/ruler.d.ts +36 -0
  53. package/utils/zoomlevel-adjustment.d.ts +144 -8
  54. package/camera/camera-rig/update-batcher/index.d.ts +0 -3
  55. package/camera/camera-rig/update-batcher/position-update-batcher.d.ts +0 -58
  56. package/camera/camera-rig/update-batcher/rotation-update-batcher.d.ts +0 -54
  57. package/camera/camera-rig/update-batcher/zoom-udpate-batcher.d.ts +0 -60
@@ -0,0 +1,101 @@
1
+ import { Point } from "@ue-too/math";
2
+ /**
3
+ * Converts a point from viewport space to world space.
4
+ *
5
+ * @param pointInViewport - The point in viewport coordinates to convert
6
+ * @param cameraPositionInWorldSpace - The camera's center position in world coordinates
7
+ * @param cameraZoomLevel - The camera's zoom level (1.0 = normal, >1 = zoomed in, <1 = zoomed out)
8
+ * @param cameraRotation - The camera's rotation angle in radians
9
+ * @param worldHasFlippedYAxis - Whether world space uses inverted y-axis (default: false)
10
+ * @returns The point in world coordinates
11
+ *
12
+ * @remarks
13
+ * This function applies the inverse of the camera transformation to convert from
14
+ * viewport coordinates to world coordinates. It's essential for translating user
15
+ * interactions (clicks, drags) into world-space positions.
16
+ *
17
+ * The transformation applies these operations in reverse order:
18
+ * 1. Unzoom: Divide by zoom level (world units per viewport pixel)
19
+ * 2. Unrotate: Rotate by positive camera rotation (reverse the camera's rotation)
20
+ * 3. Flip Y (if needed): Negate y if world uses mathematical coordinates
21
+ * 4. Translate: Add camera position to get absolute world position
22
+ *
23
+ * Mathematical formula:
24
+ * ```
25
+ * worldPoint = rotate(pointInViewport / zoom, cameraRotation) + cameraPosition
26
+ * ```
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Click at viewport center with zoomed and rotated camera
31
+ * const viewportPoint = { x: 0, y: 0 }; // Center of viewport
32
+ * const cameraPos = { x: 1000, y: 500 };
33
+ * const zoom = 2.0; // Zoomed in 2x
34
+ * const rotation = Math.PI / 4; // 45 degrees
35
+ *
36
+ * const worldPoint = convertFromViewport2World(
37
+ * viewportPoint,
38
+ * cameraPos,
39
+ * zoom,
40
+ * rotation,
41
+ * false
42
+ * );
43
+ * // Result: { x: 1000, y: 500 } (camera position, since viewport center maps to camera position)
44
+ * ```
45
+ *
46
+ * @category Coordinate Conversion
47
+ * @see {@link convertFromWorld2Viewport} for inverse conversion
48
+ */
49
+ export declare function convertFromViewport2World(pointInViewport: Point, cameraPositionInWorldSpace: Point, cameraZoomLevel: number, cameraRotation: number, worldHasFlippedYAxis?: boolean): Point;
50
+ /**
51
+ * Converts a point from world space to viewport space.
52
+ *
53
+ * @param pointInWorld - The point in world coordinates to convert
54
+ * @param cameraPositionInWorldSpace - The camera's center position in world coordinates
55
+ * @param cameraZoomLevel - The camera's zoom level (1.0 = normal, >1 = zoomed in, <1 = zoomed out)
56
+ * @param cameraRotation - The camera's rotation angle in radians
57
+ * @param worldHasFlippedYAxis - Whether world space uses inverted y-axis (default: false)
58
+ * @returns The point in viewport coordinates
59
+ *
60
+ * @remarks
61
+ * This function applies the camera transformation to convert from world coordinates
62
+ * to viewport coordinates. This is used for rendering world objects onto the viewport.
63
+ *
64
+ * The transformation applies these operations in order:
65
+ * 1. Translate: Subtract camera position (make position relative to camera)
66
+ * 2. Flip Y (if needed): Negate y if world uses mathematical coordinates
67
+ * 3. Zoom: Multiply by zoom level (viewport pixels per world unit)
68
+ * 4. Rotate: Rotate by negative camera rotation (to align with viewport)
69
+ *
70
+ * Mathematical formula:
71
+ * ```
72
+ * viewportPoint = rotate((pointInWorld - cameraPosition) * zoom, -cameraRotation)
73
+ * ```
74
+ *
75
+ * The negative rotation ensures that when the camera rotates clockwise, the world
76
+ * appears to rotate counter-clockwise (from the viewer's perspective), which is
77
+ * the expected behavior.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // World object at (1100, 550) with camera at (1000, 500)
82
+ * const worldPoint = { x: 1100, y: 550 };
83
+ * const cameraPos = { x: 1000, y: 500 };
84
+ * const zoom = 2.0; // Zoomed in 2x
85
+ * const rotation = 0; // No rotation
86
+ *
87
+ * const viewportPoint = convertFromWorld2Viewport(
88
+ * worldPoint,
89
+ * cameraPos,
90
+ * zoom,
91
+ * rotation,
92
+ * false
93
+ * );
94
+ * // Result: { x: 200, y: 100 }
95
+ * // ((1100 - 1000) * 2 = 200, (550 - 500) * 2 = 100)
96
+ * ```
97
+ *
98
+ * @category Coordinate Conversion
99
+ * @see {@link convertFromViewport2World} for inverse conversion
100
+ */
101
+ export declare function convertFromWorld2Viewport(pointInWorld: Point, cameraPositionInWorldSpace: Point, cameraZoomLevel: number, cameraRotation: number, worldHasFlippedYAxis?: boolean): Point;
@@ -0,0 +1,90 @@
1
+ import { Point } from "@ue-too/math";
2
+ import { Canvas } from "../../input-interpretation/input-state-machine/kmt-input-context";
3
+ /**
4
+ * Converts a point from browser window coordinates to canvas coordinates.
5
+ *
6
+ * @param pointInWindow - The point in window coordinates (relative to browser viewport)
7
+ * @param canvas - The canvas object containing position information
8
+ * @returns The point in canvas coordinates (relative to canvas element)
9
+ *
10
+ * @remarks
11
+ * Window coordinates are relative to the browser's viewport (top-left = 0,0).
12
+ * Canvas coordinates are relative to the canvas element's top-left corner.
13
+ *
14
+ * This conversion is essential for processing mouse and touch events, which
15
+ * provide coordinates relative to the window, not the canvas element.
16
+ *
17
+ * The conversion simply subtracts the canvas position from the window position:
18
+ * ```
19
+ * canvasPoint = windowPoint - canvasPosition
20
+ * ```
21
+ *
22
+ * Note: This function expects the canvas object to have a `position` property
23
+ * containing the canvas element's position in window coordinates (typically
24
+ * from getBoundingClientRect()).
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Mouse click at window position (500, 300)
29
+ * const clickPos = { x: 500, y: 300 };
30
+ *
31
+ * // Canvas positioned at (100, 50) in window
32
+ * const canvas = {
33
+ * position: { x: 100, y: 50 },
34
+ * width: 800,
35
+ * height: 600
36
+ * };
37
+ *
38
+ * const canvasPos = convertFromWindow2Canvas(clickPos, canvas);
39
+ * // Result: { x: 400, y: 250 }
40
+ * // (500 - 100 = 400, 300 - 50 = 250)
41
+ * ```
42
+ *
43
+ * @category Coordinate Conversion
44
+ * @see {@link convertFromCanvas2Window} for inverse conversion
45
+ */
46
+ export declare function convertFromWindow2Canvas(pointInWindow: Point, canvas: Canvas): Point;
47
+ /**
48
+ * Converts a point from canvas coordinates to browser window coordinates.
49
+ *
50
+ * @param pointInCanvas - The point in canvas coordinates (relative to canvas element)
51
+ * @param canvas - The canvas object containing position information
52
+ * @returns The point in window coordinates (relative to browser viewport)
53
+ *
54
+ * @remarks
55
+ * This is the inverse of {@link convertFromWindow2Canvas}. It translates canvas-relative
56
+ * coordinates to window-relative coordinates.
57
+ *
58
+ * The conversion adds the canvas position to the canvas-relative point:
59
+ * ```
60
+ * windowPoint = canvasPoint + canvasPosition
61
+ * ```
62
+ *
63
+ * This is useful for positioning DOM elements (like tooltips or menus) at specific
64
+ * canvas coordinates, as DOM elements use window coordinates.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // Point on canvas at (400, 250)
69
+ * const canvasPos = { x: 400, y: 250 };
70
+ *
71
+ * // Canvas positioned at (100, 50) in window
72
+ * const canvas = {
73
+ * position: { x: 100, y: 50 },
74
+ * width: 800,
75
+ * height: 600
76
+ * };
77
+ *
78
+ * const windowPos = convertFromCanvas2Window(canvasPos, canvas);
79
+ * // Result: { x: 500, y: 300 }
80
+ * // (400 + 100 = 500, 250 + 50 = 300)
81
+ *
82
+ * // Use for positioning a tooltip
83
+ * tooltip.style.left = `${windowPos.x}px`;
84
+ * tooltip.style.top = `${windowPos.y}px`;
85
+ * ```
86
+ *
87
+ * @category Coordinate Conversion
88
+ * @see {@link convertFromWindow2Canvas} for inverse conversion
89
+ */
90
+ export declare function convertFromCanvas2Window(pointInCanvas: Point, canvas: Canvas): Point;
@@ -1,5 +1,96 @@
1
1
  import { Point } from "@ue-too/math";
2
+ import { Canvas } from "../input-interpretation/input-state-machine/kmt-input-context";
3
+ /**
4
+ * Converts an isometric 3D point to a flat 2D world point.
5
+ *
6
+ * @param point - The 3D point in isometric space (with optional z coordinate)
7
+ * @returns The 2D point in flat world coordinates
8
+ *
9
+ * @remarks
10
+ * This function performs an isometric projection transformation, converting 3D
11
+ * coordinates to 2D using standard isometric angles (30 degrees).
12
+ *
13
+ * The transformation uses:
14
+ * - cos(30°) ≈ 0.866 for x-axis projection
15
+ * - cos(60°) = 0.5 for y-axis projection
16
+ * - Z-coordinate is added directly to the y-axis (height)
17
+ *
18
+ * Mathematical formulas:
19
+ * ```
20
+ * x_2d = (x_3d * cos30) - (y_3d * cos30)
21
+ * y_2d = (x_3d * cos60) + (y_3d * cos60) + z_3d
22
+ * ```
23
+ *
24
+ * This creates the classic isometric diamond grid appearance where:
25
+ * - Moving along +X goes down-right
26
+ * - Moving along +Y goes down-left
27
+ * - Moving along +Z goes straight up
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Convert a 3D cube corner to 2D isometric projection
32
+ * const point3D = { x: 10, y: 10, z: 5 };
33
+ * const point2D = pointConversion(point3D);
34
+ * // Result: { x: 0, y: 15 }
35
+ * // x: (10 * 0.866) - (10 * 0.866) = 0
36
+ * // y: (10 * 0.5) + (10 * 0.5) + 5 = 15
37
+ *
38
+ * // 2D point without z-coordinate
39
+ * const flatPoint = { x: 20, y: 0 };
40
+ * const projected = pointConversion(flatPoint);
41
+ * // Result: { x: 17.32, y: 10 }
42
+ * ```
43
+ *
44
+ * @category Coordinate Conversion
45
+ */
2
46
  export declare function pointConversion(point: Point): {
3
47
  x: number;
4
48
  y: number;
5
49
  };
50
+ /**
51
+ * Converts a point from window coordinates to viewport coordinates in one step.
52
+ *
53
+ * @param point - The point in window coordinates (browser viewport)
54
+ * @param canvas - The canvas object with position and dimensions
55
+ * @param viewportOriginInCanvasSpace - Viewport origin in canvas space (default: canvas center)
56
+ * @param viewportHasFlippedYAxis - Whether viewport uses mathematical y-axis (default: false)
57
+ * @returns The point in viewport coordinates
58
+ *
59
+ * @remarks
60
+ * This is a convenience function that combines two conversions:
61
+ * 1. Window to Canvas: {@link convertFromWindow2Canvas}
62
+ * 2. Canvas to Viewport: {@link convertFromCanvas2ViewPort}
63
+ *
64
+ * It's particularly useful for processing input events (mouse clicks, touches)
65
+ * that need to be converted directly to viewport space for interaction handling.
66
+ *
67
+ * The default viewport origin is the canvas center, which is common for
68
+ * mathematical/engineering applications where (0,0) should be in the middle.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * // Mouse click event
73
+ * const clickPos = { x: event.clientX, y: event.clientY };
74
+ *
75
+ * const canvas = {
76
+ * position: { x: 100, y: 50 },
77
+ * width: 800,
78
+ * height: 600
79
+ * };
80
+ *
81
+ * // Convert to centered viewport with y-up
82
+ * const viewportPos = convertFromWindow2ViewPortWithCanvasOperator(
83
+ * clickPos,
84
+ * canvas,
85
+ * { x: 400, y: 300 }, // center of canvas
86
+ * true // mathematical coordinates
87
+ * );
88
+ *
89
+ * // viewportPos is now relative to viewport center with y-up
90
+ * ```
91
+ *
92
+ * @category Coordinate Conversion
93
+ * @see {@link convertFromWindow2Canvas} for window to canvas conversion
94
+ * @see {@link convertFromCanvas2ViewPort} for canvas to viewport conversion
95
+ */
96
+ export declare function convertFromWindow2ViewPortWithCanvasOperator(point: Point, canvas: Canvas, viewportOriginInCanvasSpace?: Point, viewportHasFlippedYAxis?: boolean): Point;
@@ -1,20 +1,168 @@
1
1
  import { Point } from "@ue-too/math";
2
+ /**
3
+ * Draws an arrow from start to end point with an arrowhead.
4
+ *
5
+ * @param context - The canvas 2D rendering context
6
+ * @param cameraZoomLevel - Current camera zoom level for scale-independent sizing
7
+ * @param startPoint - Arrow tail position in world coordinates
8
+ * @param endPoint - Arrow head position in world coordinates
9
+ * @param width - Line width in world units (default: 1)
10
+ * @param arrowRatio - Ratio of arrowhead size to total length (default: 0.3, unused in implementation)
11
+ *
12
+ * @remarks
13
+ * The arrow consists of a line segment and a triangular arrowhead. The arrowhead
14
+ * size is adaptive:
15
+ * - Maximum 10 pixels in viewport space
16
+ * - Minimum half the arrow length
17
+ *
18
+ * This ensures arrows look good at all zoom levels and lengths.
19
+ *
20
+ * The arrowhead is constructed perpendicular to the arrow direction, creating
21
+ * a filled triangle at the end point.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const ctx = canvas.getContext('2d');
26
+ * const zoom = 1.5;
27
+ *
28
+ * // Draw a simple arrow
29
+ * ctx.fillStyle = 'blue';
30
+ * ctx.strokeStyle = 'blue';
31
+ * drawArrow(ctx, zoom, { x: 0, y: 0 }, { x: 100, y: 50 });
32
+ *
33
+ * // Draw a thicker arrow
34
+ * ctx.fillStyle = 'red';
35
+ * ctx.strokeStyle = 'red';
36
+ * drawArrow(ctx, zoom, { x: 0, y: 0 }, { x: 100, y: -50 }, 3);
37
+ * ```
38
+ *
39
+ * @category Drawing Utilities
40
+ */
2
41
  export declare function drawArrow(context: CanvasRenderingContext2D, cameraZoomLevel: number, startPoint: Point, endPoint: Point, width?: number, arrowRatio?: number): void;
42
+ /**
43
+ * Length of major tick marks in pixels (viewport space).
44
+ * @category Drawing Utilities
45
+ */
3
46
  export declare const MAJOR_TICK_LENGTH = 30;
47
+ /**
48
+ * Length of minor tick marks in pixels (viewport space).
49
+ * @category Drawing Utilities
50
+ */
4
51
  export declare const MINOR_TICK_LENGTH: number;
52
+ /**
53
+ * Length of half-step tick marks in pixels (viewport space).
54
+ * @category Drawing Utilities
55
+ */
5
56
  export declare const HALF_TICK_LENGTH: number;
57
+ /**
58
+ * Offset for major tick labels in pixels (viewport space).
59
+ * @category Drawing Utilities
60
+ */
6
61
  export declare const TEXT_MAJOR_TICK_OFFSET = 10;
62
+ /**
63
+ * Offset for half-step tick labels in pixels (viewport space).
64
+ * @category Drawing Utilities
65
+ */
7
66
  export declare const TEXT_HALF_TICK_OFFSET = 2.5;
67
+ /**
68
+ * Font size for major tick labels in pixels (viewport space).
69
+ * @category Drawing Utilities
70
+ */
8
71
  export declare const TEXT_MAJOR_TICK_FONT_SIZE = 20;
72
+ /**
73
+ * Font size for half-step tick labels in pixels (viewport space).
74
+ * @category Drawing Utilities
75
+ */
9
76
  export declare const TEXT_HALF_TICK_FONT_SIZE = 10;
10
77
  /**
11
- * @description Draws a ruler on the canvas.
12
- * argument points are in world space
78
+ * Draws calibrated rulers along the edges of the viewport.
79
+ *
80
+ * @param context - The canvas 2D rendering context
81
+ * @param topLeftCorner - Top-left corner of viewport in world coordinates
82
+ * @param topRightCorner - Top-right corner of viewport in world coordinates
83
+ * @param bottomLeftCorner - Bottom-left corner of viewport in world coordinates
84
+ * @param alignCoordinateSystem - Whether coordinates align with canvas (y-down) or are mathematical (y-up)
85
+ * @param cameraZoomLevel - Current camera zoom level
86
+ *
87
+ * @remarks
88
+ * This function draws rulers with three levels of tick marks:
89
+ * - Major ticks: At powers of 10 (1, 10, 100, etc.) with large labels
90
+ * - Half ticks: At half-steps (5, 50, 500, etc.) with small labels
91
+ * - Minor ticks: At 1/10 steps with no labels
92
+ *
93
+ * The ruler automatically adapts to the zoom level by calculating appropriate
94
+ * tick spacing using {@link calculateOrderOfMagnitude} and {@link calculateTickValues}.
95
+ *
96
+ * Rulers are drawn along:
97
+ * - Top edge (horizontal ruler, red)
98
+ * - Left edge (vertical ruler, green)
99
+ *
100
+ * Tick positions are calibrated to align with round numbers in world space,
101
+ * making it easy to read coordinates at any zoom level.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const ctx = canvas.getContext('2d');
106
+ * const zoom = 2.0;
107
+ *
108
+ * // Viewport corners in world space
109
+ * const topLeft = { x: -100, y: 100 };
110
+ * const topRight = { x: 100, y: 100 };
111
+ * const bottomLeft = { x: -100, y: -100 };
13
112
  *
14
- * @category Utils
113
+ * drawRuler(ctx, topLeft, topRight, bottomLeft, false, zoom);
114
+ * // Draws rulers with ticks at -100, -50, 0, 50, 100
115
+ * ```
15
116
  *
117
+ * @category Drawing Utilities
118
+ * @see {@link calculateTickValues} for tick calculation logic
119
+ * @see {@link calculateOrderOfMagnitude} for order of magnitude calculation
16
120
  */
17
121
  export declare function drawRuler(context: CanvasRenderingContext2D, topLeftCorner: Point, topRightCorner: Point, bottomLeftCorner: Point, alignCoordinateSystem: boolean, cameraZoomLevel: number): void;
122
+ /**
123
+ * Calculates tick mark positions and spacing for a ruler.
124
+ *
125
+ * @param minValue - Minimum value on the ruler axis
126
+ * @param maxValue - Maximum value on the ruler axis
127
+ * @param orderOfMagnitude - Optional pre-calculated order of magnitude (for consistency across axes)
128
+ * @returns Object containing tick positions and spacing for major, half, and minor ticks
129
+ *
130
+ * @remarks
131
+ * This function determines where to place tick marks on a ruler to show round
132
+ * numbers at appropriate intervals. It calculates three levels of ticks:
133
+ *
134
+ * 1. Major ticks: At powers of 10 (step = 10^n)
135
+ * 2. Half ticks: At half the major step (step = 5×10^(n-1))
136
+ * 3. Minor ticks: At 1/10 the major step (step = 10^(n-1))
137
+ *
138
+ * The calibration multiplier handles cases where the order of magnitude is very
139
+ * small (< 1), ensuring tick positions are calculated correctly for zoomed-in views.
140
+ *
141
+ * For consistency between x and y axes, you can provide a pre-calculated
142
+ * orderOfMagnitude. Otherwise, it's calculated from the range width.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * // Ruler showing -100 to 100
147
+ * const ticks = calculateTickValues(-100, 100);
148
+ * // Result:
149
+ * // majorTickStep: 100
150
+ * // minMajorTickValue: -100, maxMajorTickValue: 100
151
+ * // halfTickStep: 50
152
+ * // minorTickStep: 10
153
+ * // calibrationMultiplier: 1
154
+ *
155
+ * // Zoomed in view: 0.001 to 0.01
156
+ * const zoomedTicks = calculateTickValues(0.001, 0.01);
157
+ * // Result:
158
+ * // majorTickStep: 10 (calibrated)
159
+ * // calibrationMultiplier: 0.001 (multiply tick values by this)
160
+ * ```
161
+ *
162
+ * @category Drawing Utilities
163
+ * @see {@link calculateOrderOfMagnitude} for order calculation
164
+ * @see {@link drawRuler} for usage in ruler drawing
165
+ */
18
166
  export declare function calculateTickValues(minValue: number, maxValue: number, orderOfMagnitude?: number): {
19
167
  minMajorTickValue: number;
20
168
  maxMajorTickValue: number;
package/utils/index.d.ts CHANGED
@@ -1,3 +1,24 @@
1
+ /**
2
+ * Utility functions module exports.
3
+ *
4
+ * @remarks
5
+ * This module provides helper functions and utilities used throughout the board package.
6
+ * Includes coordinate conversion, drawing helpers, observable patterns, and more.
7
+ *
8
+ * ## Key Utilities
9
+ *
10
+ * - **Coordinate Conversion**: Functions for converting between coordinate systems
11
+ * - **Drawing Utilities**: {@link reverseYAxis} and other canvas drawing helpers
12
+ * - **Observable Pattern**: Simple observer implementation for state updates
13
+ * - **Handler Pipeline**: {@link createHandlerChain} for composing transformation functions
14
+ * - **Canvas Utilities**: Dimension and position helpers for canvas elements
15
+ * - **Zoom Level Adjustment**: Helpers for calculating and adjusting zoom levels
16
+ *
17
+ * @see {@link createHandlerChain} for creating composable function pipelines
18
+ * @see {@link reverseYAxis} for Y-axis coordinate system reversal
19
+ *
20
+ * @module
21
+ */
1
22
  export * from "./coorindate-conversion";
2
23
  export * from "./ruler";
3
24
  export * from "./observable";
@@ -1,18 +1,197 @@
1
+ /**
2
+ * Type definition for an observer callback function.
3
+ *
4
+ * @typeParam T - Tuple type of arguments passed to the observer
5
+ *
6
+ * @remarks
7
+ * Observers are callbacks that get notified when an Observable emits data.
8
+ * The generic type T is a tuple representing the arguments passed to the callback.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Observer that receives a single string
13
+ * const stringObserver: Observer<[string]> = (message) => {
14
+ * console.log(message);
15
+ * };
16
+ *
17
+ * // Observer that receives multiple arguments
18
+ * const multiObserver: Observer<[number, string, boolean]> = (num, str, flag) => {
19
+ * console.log(num, str, flag);
20
+ * };
21
+ * ```
22
+ *
23
+ * @category Observable Pattern
24
+ */
1
25
  export type Observer<T extends any[]> = (...data: T) => void;
26
+ /**
27
+ * Options for subscribing to an Observable.
28
+ *
29
+ * @property signal - Optional AbortSignal for automatic unsubscription
30
+ *
31
+ * @remarks
32
+ * Subscription options allow for automatic cleanup of subscriptions using
33
+ * the AbortController API. When the signal is aborted, the subscription
34
+ * is automatically removed.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const controller = new AbortController();
39
+ *
40
+ * observable.subscribe(
41
+ * (data) => console.log(data),
42
+ * { signal: controller.signal }
43
+ * );
44
+ *
45
+ * // Later, abort to unsubscribe
46
+ * controller.abort();
47
+ * ```
48
+ *
49
+ * @category Observable Pattern
50
+ */
2
51
  export interface SubscriptionOptions {
3
52
  signal?: AbortSignal;
4
53
  }
54
+ /**
55
+ * Interface for the Observable pattern implementation.
56
+ *
57
+ * @typeParam T - Tuple type of data emitted to observers
58
+ *
59
+ * @remarks
60
+ * Observables allow multiple observers to subscribe and receive notifications
61
+ * when data is emitted. This is the pub-sub pattern for event handling.
62
+ *
63
+ * Implementations can be synchronous or asynchronous:
64
+ * - {@link SynchronousObservable}: Notifies observers immediately
65
+ * - {@link AsyncObservable}: Notifies observers via microtasks
66
+ *
67
+ * @category Observable Pattern
68
+ */
5
69
  export interface Observable<T extends any[]> {
6
70
  subscribe(observer: Observer<T>, options?: SubscriptionOptions): () => void;
7
71
  notify(...data: T): void;
8
72
  }
73
+ /**
74
+ * Asynchronous Observable implementation that notifies observers via microtasks.
75
+ *
76
+ * @typeParam T - Tuple type of data emitted to observers
77
+ *
78
+ * @remarks
79
+ * This Observable uses `queueMicrotask` to defer observer notifications,
80
+ * ensuring they execute after the current execution context completes but
81
+ * before the next task. This prevents recursive notification issues and
82
+ * allows the notifier to complete before observers run.
83
+ *
84
+ * Use AsyncObservable when:
85
+ * - You want to prevent recursion issues in notifications
86
+ * - Observer execution should not block the notifier
87
+ * - You need guaranteed async behavior
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const observable = new AsyncObservable<[string]>();
92
+ *
93
+ * observable.subscribe((message) => {
94
+ * console.log('Observer received:', message);
95
+ * });
96
+ *
97
+ * console.log('Before notify');
98
+ * observable.notify('Hello');
99
+ * console.log('After notify');
100
+ *
101
+ * // Output:
102
+ * // Before notify
103
+ * // After notify
104
+ * // Observer received: Hello
105
+ * ```
106
+ *
107
+ * @category Observable Pattern
108
+ * @see {@link SynchronousObservable} for synchronous notifications
109
+ */
9
110
  export declare class AsyncObservable<T extends any[]> implements Observable<T> {
10
111
  private observers;
112
+ /**
113
+ * Subscribes an observer to receive notifications.
114
+ *
115
+ * @param observer - The callback function to be notified
116
+ * @param options - Optional subscription options including AbortSignal
117
+ * @returns Unsubscribe function to remove this observer
118
+ *
119
+ * @remarks
120
+ * If an AbortSignal is provided and is already aborted, the observer
121
+ * is not added and the returned unsubscribe function is a no-op.
122
+ */
11
123
  subscribe(observer: Observer<T>, options?: SubscriptionOptions): () => void;
124
+ /**
125
+ * Notifies all observers with the provided data asynchronously.
126
+ *
127
+ * @param data - The data to pass to all observers
128
+ *
129
+ * @remarks
130
+ * Each observer is called via `queueMicrotask`, ensuring async execution.
131
+ * This method returns immediately; observers run later in the event loop.
132
+ */
12
133
  notify(...data: T): void;
13
134
  }
135
+ /**
136
+ * Synchronous Observable implementation that notifies observers immediately.
137
+ *
138
+ * @typeParam T - Tuple type of data emitted to observers
139
+ *
140
+ * @remarks
141
+ * This Observable calls all observers synchronously and immediately when
142
+ * `notify()` is called. The notify method doesn't return until all observers
143
+ * have executed.
144
+ *
145
+ * Use SynchronousObservable when:
146
+ * - You need immediate, guaranteed execution of observers
147
+ * - Observer execution order matters and must be predictable
148
+ * - You're in a performance-critical path (no async overhead)
149
+ *
150
+ * Caution: Can lead to recursion issues if observers trigger notifications.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const observable = new SynchronousObservable<[string]>();
155
+ *
156
+ * observable.subscribe((message) => {
157
+ * console.log('Observer received:', message);
158
+ * });
159
+ *
160
+ * console.log('Before notify');
161
+ * observable.notify('Hello');
162
+ * console.log('After notify');
163
+ *
164
+ * // Output:
165
+ * // Before notify
166
+ * // Observer received: Hello
167
+ * // After notify
168
+ * ```
169
+ *
170
+ * @category Observable Pattern
171
+ * @see {@link AsyncObservable} for asynchronous notifications
172
+ */
14
173
  export declare class SynchronousObservable<T extends any[]> implements Observable<T> {
15
174
  private observers;
175
+ /**
176
+ * Subscribes an observer to receive notifications.
177
+ *
178
+ * @param observer - The callback function to be notified
179
+ * @param options - Optional subscription options including AbortSignal
180
+ * @returns Unsubscribe function to remove this observer
181
+ *
182
+ * @remarks
183
+ * If an AbortSignal is provided and is already aborted, the observer
184
+ * is not added and the returned unsubscribe function is a no-op.
185
+ */
16
186
  subscribe(observer: Observer<T>, options?: SubscriptionOptions): () => void;
187
+ /**
188
+ * Notifies all observers with the provided data synchronously.
189
+ *
190
+ * @param data - The data to pass to all observers
191
+ *
192
+ * @remarks
193
+ * Each observer is called immediately in order. This method blocks until
194
+ * all observers have completed execution.
195
+ */
17
196
  notify(...data: T): void;
18
197
  }