@rxflow/manhattan 0.0.2-alpha.8 → 0.0.3

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 (116) hide show
  1. package/README.md +214 -10
  2. package/cjs/getManHattanPath.d.ts.map +1 -1
  3. package/cjs/getManHattanPath.js +77 -46
  4. package/cjs/obstacle/ObstacleMap.d.ts +41 -9
  5. package/cjs/obstacle/ObstacleMap.d.ts.map +1 -1
  6. package/cjs/obstacle/ObstacleMap.js +201 -96
  7. package/cjs/obstacle/QuadTree.d.ts +119 -0
  8. package/cjs/obstacle/QuadTree.d.ts.map +1 -0
  9. package/cjs/obstacle/QuadTree.js +334 -0
  10. package/cjs/options/defaults.d.ts +1 -1
  11. package/cjs/options/defaults.d.ts.map +1 -1
  12. package/cjs/options/resolver.d.ts.map +1 -1
  13. package/cjs/options/resolver.js +145 -17
  14. package/cjs/options/types.d.ts +41 -0
  15. package/cjs/options/types.d.ts.map +1 -1
  16. package/cjs/pathfinder/PathCache.d.ts +92 -0
  17. package/cjs/pathfinder/PathCache.d.ts.map +1 -0
  18. package/cjs/pathfinder/PathCache.js +249 -0
  19. package/cjs/pathfinder/findRoute.d.ts.map +1 -1
  20. package/cjs/pathfinder/findRoute.js +96 -31
  21. package/cjs/pathfinder/index.d.ts +1 -0
  22. package/cjs/pathfinder/index.d.ts.map +1 -1
  23. package/cjs/pathfinder/index.js +26 -1
  24. package/cjs/svg/pathConverter.d.ts +13 -0
  25. package/cjs/svg/pathConverter.d.ts.map +1 -1
  26. package/cjs/svg/pathConverter.js +170 -1
  27. package/cjs/utils/AdaptiveStepCalculator.d.ts +90 -0
  28. package/cjs/utils/AdaptiveStepCalculator.d.ts.map +1 -0
  29. package/cjs/utils/AdaptiveStepCalculator.js +224 -0
  30. package/cjs/utils/ErrorRecovery.d.ts +182 -0
  31. package/cjs/utils/ErrorRecovery.d.ts.map +1 -0
  32. package/cjs/utils/ErrorRecovery.js +413 -0
  33. package/cjs/utils/GlobalGrid.d.ts +99 -0
  34. package/cjs/utils/GlobalGrid.d.ts.map +1 -0
  35. package/cjs/utils/GlobalGrid.js +224 -0
  36. package/cjs/utils/PerformanceMonitor.d.ts +139 -0
  37. package/cjs/utils/PerformanceMonitor.d.ts.map +1 -0
  38. package/cjs/utils/PerformanceMonitor.js +305 -0
  39. package/cjs/utils/getAnchorPoints.d.ts.map +1 -1
  40. package/cjs/utils/getAnchorPoints.js +0 -4
  41. package/cjs/utils/grid.d.ts +15 -0
  42. package/cjs/utils/grid.d.ts.map +1 -1
  43. package/cjs/utils/grid.js +19 -12
  44. package/cjs/utils/heuristics.d.ts +61 -0
  45. package/cjs/utils/heuristics.d.ts.map +1 -0
  46. package/cjs/utils/heuristics.js +141 -0
  47. package/cjs/utils/index.d.ts +6 -0
  48. package/cjs/utils/index.d.ts.map +1 -1
  49. package/cjs/utils/index.js +66 -0
  50. package/cjs/utils/pathProcessing.d.ts +45 -0
  51. package/cjs/utils/pathProcessing.d.ts.map +1 -0
  52. package/cjs/utils/pathProcessing.js +270 -0
  53. package/cjs/utils/pathValidation.d.ts.map +1 -1
  54. package/cjs/utils/pathValidation.js +0 -1
  55. package/cjs/utils/rect.d.ts.map +1 -1
  56. package/cjs/utils/rect.js +7 -0
  57. package/cjs/utils/route.d.ts.map +1 -1
  58. package/cjs/utils/route.js +18 -2
  59. package/esm/getManHattanPath.d.ts.map +1 -1
  60. package/esm/getManHattanPath.js +92 -69
  61. package/esm/obstacle/ObstacleMap.d.ts +41 -9
  62. package/esm/obstacle/ObstacleMap.d.ts.map +1 -1
  63. package/esm/obstacle/ObstacleMap.js +218 -99
  64. package/esm/obstacle/QuadTree.d.ts +119 -0
  65. package/esm/obstacle/QuadTree.d.ts.map +1 -0
  66. package/esm/obstacle/QuadTree.js +488 -0
  67. package/esm/options/defaults.d.ts +1 -1
  68. package/esm/options/defaults.d.ts.map +1 -1
  69. package/esm/options/resolver.d.ts.map +1 -1
  70. package/esm/options/resolver.js +147 -18
  71. package/esm/options/types.d.ts +41 -0
  72. package/esm/options/types.d.ts.map +1 -1
  73. package/esm/pathfinder/PathCache.d.ts +92 -0
  74. package/esm/pathfinder/PathCache.d.ts.map +1 -0
  75. package/esm/pathfinder/PathCache.js +278 -0
  76. package/esm/pathfinder/findRoute.d.ts.map +1 -1
  77. package/esm/pathfinder/findRoute.js +98 -44
  78. package/esm/pathfinder/index.d.ts +1 -0
  79. package/esm/pathfinder/index.d.ts.map +1 -1
  80. package/esm/pathfinder/index.js +2 -1
  81. package/esm/svg/pathConverter.d.ts +13 -0
  82. package/esm/svg/pathConverter.d.ts.map +1 -1
  83. package/esm/svg/pathConverter.js +170 -1
  84. package/esm/utils/AdaptiveStepCalculator.d.ts +90 -0
  85. package/esm/utils/AdaptiveStepCalculator.d.ts.map +1 -0
  86. package/esm/utils/AdaptiveStepCalculator.js +252 -0
  87. package/esm/utils/ErrorRecovery.d.ts +182 -0
  88. package/esm/utils/ErrorRecovery.d.ts.map +1 -0
  89. package/esm/utils/ErrorRecovery.js +499 -0
  90. package/esm/utils/GlobalGrid.d.ts +99 -0
  91. package/esm/utils/GlobalGrid.d.ts.map +1 -0
  92. package/esm/utils/GlobalGrid.js +259 -0
  93. package/esm/utils/PerformanceMonitor.d.ts +139 -0
  94. package/esm/utils/PerformanceMonitor.d.ts.map +1 -0
  95. package/esm/utils/PerformanceMonitor.js +360 -0
  96. package/esm/utils/getAnchorPoints.d.ts.map +1 -1
  97. package/esm/utils/getAnchorPoints.js +0 -4
  98. package/esm/utils/grid.d.ts +15 -0
  99. package/esm/utils/grid.d.ts.map +1 -1
  100. package/esm/utils/grid.js +18 -13
  101. package/esm/utils/heuristics.d.ts +61 -0
  102. package/esm/utils/heuristics.d.ts.map +1 -0
  103. package/esm/utils/heuristics.js +144 -0
  104. package/esm/utils/index.d.ts +6 -0
  105. package/esm/utils/index.d.ts.map +1 -1
  106. package/esm/utils/index.js +7 -1
  107. package/esm/utils/pathProcessing.d.ts +45 -0
  108. package/esm/utils/pathProcessing.d.ts.map +1 -0
  109. package/esm/utils/pathProcessing.js +270 -0
  110. package/esm/utils/pathValidation.d.ts.map +1 -1
  111. package/esm/utils/pathValidation.js +0 -1
  112. package/esm/utils/rect.d.ts.map +1 -1
  113. package/esm/utils/rect.js +11 -4
  114. package/esm/utils/route.d.ts.map +1 -1
  115. package/esm/utils/route.js +18 -2
  116. package/package.json +10 -2
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.QuadTree = void 0;
7
+ exports.createQuadTreeFromRects = createQuadTreeFromRects;
8
+ var _geometry = require("../geometry");
9
+ /**
10
+ * QuadTree implementation for efficient spatial queries
11
+ * Feature: manhattan-optimization
12
+ *
13
+ * A QuadTree is a tree data structure that recursively subdivides 2D space
14
+ * into four quadrants. This enables O(log n) spatial queries instead of O(n).
15
+ */
16
+
17
+ /**
18
+ * Item stored in the QuadTree
19
+ */
20
+
21
+ /**
22
+ * QuadTree configuration
23
+ */
24
+
25
+ /**
26
+ * Default QuadTree configuration
27
+ */
28
+ const DEFAULT_CONFIG = {
29
+ maxItems: 8,
30
+ maxDepth: 8,
31
+ minSize: 10
32
+ };
33
+
34
+ /**
35
+ * QuadTree node for spatial partitioning
36
+ */
37
+ class QuadTree {
38
+ bounds;
39
+ items;
40
+ children;
41
+ depth;
42
+ config;
43
+ constructor(bounds, config = {}, depth = 0) {
44
+ this.bounds = bounds;
45
+ this.items = [];
46
+ this.children = null;
47
+ this.depth = depth;
48
+ this.config = {
49
+ ...DEFAULT_CONFIG,
50
+ ...config
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Insert an item into the QuadTree
56
+ */
57
+ insert(item) {
58
+ // Check if item intersects this node's bounds
59
+ if (!this.intersects(item.bounds)) {
60
+ return false;
61
+ }
62
+
63
+ // If we have children, try to insert into them
64
+ if (this.children !== null) {
65
+ return this.insertIntoChildren(item);
66
+ }
67
+
68
+ // Add to this node
69
+ this.items.push(item);
70
+
71
+ // Check if we need to split
72
+ if (this.shouldSplit()) {
73
+ this.split();
74
+ }
75
+ return true;
76
+ }
77
+
78
+ /**
79
+ * Insert an item with just bounds and data
80
+ */
81
+ insertRect(bounds, data) {
82
+ return this.insert({
83
+ bounds,
84
+ data
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Query all items that intersect with the given bounds
90
+ */
91
+ query(bounds) {
92
+ const results = [];
93
+ this.queryInternal(bounds, results);
94
+ return results;
95
+ }
96
+
97
+ /**
98
+ * Query all items that contain the given point
99
+ */
100
+ queryPoint(point) {
101
+ const results = [];
102
+ this.queryPointInternal(point, results);
103
+ return results;
104
+ }
105
+
106
+ /**
107
+ * Get all items in the tree
108
+ */
109
+ getAllItems() {
110
+ const results = [...this.items];
111
+ if (this.children !== null) {
112
+ for (const child of this.children) {
113
+ results.push(...child.getAllItems());
114
+ }
115
+ }
116
+ return results;
117
+ }
118
+
119
+ /**
120
+ * Clear all items from the tree
121
+ */
122
+ clear() {
123
+ this.items = [];
124
+ this.children = null;
125
+ }
126
+
127
+ /**
128
+ * Get the total number of items in the tree
129
+ */
130
+ get size() {
131
+ let count = this.items.length;
132
+ if (this.children !== null) {
133
+ for (const child of this.children) {
134
+ count += child.size;
135
+ }
136
+ }
137
+ return count;
138
+ }
139
+
140
+ /**
141
+ * Get the depth of the tree
142
+ */
143
+ getMaxDepth() {
144
+ if (this.children === null) {
145
+ return this.depth;
146
+ }
147
+ let maxChildDepth = this.depth;
148
+ for (const child of this.children) {
149
+ maxChildDepth = Math.max(maxChildDepth, child.getMaxDepth());
150
+ }
151
+ return maxChildDepth;
152
+ }
153
+
154
+ /**
155
+ * Internal query implementation
156
+ */
157
+ queryInternal(bounds, results) {
158
+ // Check if query bounds intersects this node
159
+ if (!this.intersects(bounds)) {
160
+ return;
161
+ }
162
+
163
+ // Check items in this node
164
+ for (const item of this.items) {
165
+ if (this.rectanglesIntersect(item.bounds, bounds)) {
166
+ results.push(item);
167
+ }
168
+ }
169
+
170
+ // Query children
171
+ if (this.children !== null) {
172
+ for (const child of this.children) {
173
+ child.queryInternal(bounds, results);
174
+ }
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Internal point query implementation
180
+ */
181
+ queryPointInternal(point, results) {
182
+ // Check if point is within this node's bounds
183
+ if (!this.containsPoint(point)) {
184
+ return;
185
+ }
186
+
187
+ // Check items in this node
188
+ for (const item of this.items) {
189
+ if (item.bounds.containsPoint(point)) {
190
+ results.push(item);
191
+ }
192
+ }
193
+
194
+ // Query children
195
+ if (this.children !== null) {
196
+ for (const child of this.children) {
197
+ child.queryPointInternal(point, results);
198
+ }
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Check if this node should split
204
+ */
205
+ shouldSplit() {
206
+ return this.items.length > this.config.maxItems && this.depth < this.config.maxDepth && this.bounds.width > this.config.minSize * 2 && this.bounds.height > this.config.minSize * 2;
207
+ }
208
+
209
+ /**
210
+ * Split this node into four children
211
+ */
212
+ split() {
213
+ const halfWidth = this.bounds.width / 2;
214
+ const halfHeight = this.bounds.height / 2;
215
+ const x = this.bounds.x;
216
+ const y = this.bounds.y;
217
+ const nextDepth = this.depth + 1;
218
+ this.children = [
219
+ // Top-left
220
+ new QuadTree(new _geometry.Rectangle(x, y, halfWidth, halfHeight), this.config, nextDepth),
221
+ // Top-right
222
+ new QuadTree(new _geometry.Rectangle(x + halfWidth, y, halfWidth, halfHeight), this.config, nextDepth),
223
+ // Bottom-left
224
+ new QuadTree(new _geometry.Rectangle(x, y + halfHeight, halfWidth, halfHeight), this.config, nextDepth),
225
+ // Bottom-right
226
+ new QuadTree(new _geometry.Rectangle(x + halfWidth, y + halfHeight, halfWidth, halfHeight), this.config, nextDepth)];
227
+
228
+ // Redistribute items to children
229
+ const itemsToRedistribute = this.items;
230
+ this.items = [];
231
+ for (const item of itemsToRedistribute) {
232
+ this.insertIntoChildren(item);
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Insert item into appropriate children
238
+ */
239
+ insertIntoChildren(item) {
240
+ if (this.children === null) {
241
+ return false;
242
+ }
243
+ let inserted = false;
244
+ for (const child of this.children) {
245
+ if (child.insert(item)) {
246
+ inserted = true;
247
+ }
248
+ }
249
+
250
+ // If item doesn't fit in any child (spans multiple), keep in this node
251
+ if (!inserted) {
252
+ this.items.push(item);
253
+ inserted = true;
254
+ }
255
+ return inserted;
256
+ }
257
+
258
+ /**
259
+ * Check if a rectangle intersects this node's bounds
260
+ */
261
+ intersects(rect) {
262
+ return this.rectanglesIntersect(this.bounds, rect);
263
+ }
264
+
265
+ /**
266
+ * Check if two rectangles intersect
267
+ */
268
+ rectanglesIntersect(a, b) {
269
+ return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y);
270
+ }
271
+
272
+ /**
273
+ * Check if this node's bounds contain a point
274
+ */
275
+ containsPoint(point) {
276
+ return point.x >= this.bounds.x && point.x <= this.bounds.x + this.bounds.width && point.y >= this.bounds.y && point.y <= this.bounds.y + this.bounds.height;
277
+ }
278
+
279
+ /**
280
+ * Get statistics about the tree
281
+ */
282
+ getStats() {
283
+ const stats = {
284
+ totalItems: 0,
285
+ maxDepth: 0,
286
+ nodeCount: 0,
287
+ itemsPerNode: 0
288
+ };
289
+ this.collectStats(stats);
290
+ stats.itemsPerNode = stats.nodeCount > 0 ? stats.totalItems / stats.nodeCount : 0;
291
+ return stats;
292
+ }
293
+ collectStats(stats) {
294
+ stats.totalItems += this.items.length;
295
+ stats.maxDepth = Math.max(stats.maxDepth, this.depth);
296
+ stats.nodeCount++;
297
+ if (this.children !== null) {
298
+ for (const child of this.children) {
299
+ child.collectStats(stats);
300
+ }
301
+ }
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Create a QuadTree with bounds that cover all given rectangles
307
+ */
308
+ exports.QuadTree = QuadTree;
309
+ function createQuadTreeFromRects(items, config) {
310
+ if (items.length === 0) {
311
+ return new QuadTree(new _geometry.Rectangle(0, 0, 1000, 1000), config);
312
+ }
313
+
314
+ // Calculate bounding box of all items
315
+ let minX = Infinity;
316
+ let minY = Infinity;
317
+ let maxX = -Infinity;
318
+ let maxY = -Infinity;
319
+ for (const item of items) {
320
+ minX = Math.min(minX, item.bounds.x);
321
+ minY = Math.min(minY, item.bounds.y);
322
+ maxX = Math.max(maxX, item.bounds.x + item.bounds.width);
323
+ maxY = Math.max(maxY, item.bounds.y + item.bounds.height);
324
+ }
325
+
326
+ // Add some padding
327
+ const padding = 100;
328
+ const bounds = new _geometry.Rectangle(minX - padding, minY - padding, maxX - minX + padding * 2, maxY - minY + padding * 2);
329
+ const tree = new QuadTree(bounds, config);
330
+ for (const item of items) {
331
+ tree.insert(item);
332
+ }
333
+ return tree;
334
+ }
@@ -3,7 +3,7 @@ import type { ManhattanRouterOptions } from './types';
3
3
  /**
4
4
  * Default configuration for Manhattan router
5
5
  */
6
- export declare const defaults: Required<Omit<ManhattanRouterOptions, 'fallbackRoute' | 'sourcePosition' | 'targetPosition'>>;
6
+ export declare const defaults: Required<Omit<ManhattanRouterOptions, 'fallbackRoute' | 'sourcePosition' | 'targetPosition' | 'performance' | 'adaptiveStep' | 'debug'>>;
7
7
  /**
8
8
  * Direction map - maps direction names to unit vectors
9
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/options/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAa,MAAM,SAAS,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,CAkBlH,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;CAKxB,CAAA"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/options/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAa,MAAM,SAAS,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,CAAC,CAkB7J,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;CAKxB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/options/resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAetE;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAiEpF"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/options/resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAkC,MAAM,SAAS,CAAA;AAmCtG;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAgGD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CA4EpF"}
@@ -7,6 +7,26 @@ exports.normalizeAngle = normalizeAngle;
7
7
  exports.resolveOptions = resolveOptions;
8
8
  var _geometry = require("../geometry");
9
9
  var _defaults = require("./defaults");
10
+ var _AdaptiveStepCalculator = require("../utils/AdaptiveStepCalculator");
11
+ /**
12
+ * Default performance configuration
13
+ */
14
+ const DEFAULT_PERFORMANCE_CONFIG = {
15
+ enableCache: true,
16
+ cacheSize: 100,
17
+ enableQuadTree: true,
18
+ earlyTermination: false
19
+ };
20
+
21
+ /**
22
+ * Default debug configuration
23
+ */
24
+ const DEFAULT_DEBUG_CONFIG = {
25
+ enableLogging: false,
26
+ enableMetrics: false,
27
+ logLevel: 'info'
28
+ };
29
+
10
30
  /**
11
31
  * Normalize padding value to box format
12
32
  */
@@ -35,26 +55,126 @@ function normalizeAngle(angle) {
35
55
  return angle;
36
56
  }
37
57
 
58
+ /**
59
+ * Validate and fix configuration options
60
+ */
61
+ function validateAndFixOptions(options) {
62
+ const fixed = {
63
+ ...options
64
+ };
65
+
66
+ // Validate step
67
+ if (fixed.step !== undefined && fixed.step <= 0) {
68
+ console.warn('[ManhattanRouter] Invalid step value, using default');
69
+ fixed.step = _defaults.defaults.step;
70
+ }
71
+
72
+ // Validate maxLoopCount
73
+ if (fixed.maxLoopCount !== undefined && fixed.maxLoopCount <= 0) {
74
+ console.warn('[ManhattanRouter] Invalid maxLoopCount, using default');
75
+ fixed.maxLoopCount = _defaults.defaults.maxLoopCount;
76
+ }
77
+
78
+ // Validate borderRadius
79
+ if (fixed.borderRadius !== undefined && fixed.borderRadius < 0) {
80
+ console.warn('[ManhattanRouter] Invalid borderRadius, using default');
81
+ fixed.borderRadius = _defaults.defaults.borderRadius;
82
+ }
83
+
84
+ // Validate extensionDistance
85
+ if (fixed.extensionDistance !== undefined && fixed.extensionDistance < 0) {
86
+ console.warn('[ManhattanRouter] Invalid extensionDistance, using default');
87
+ fixed.extensionDistance = _defaults.defaults.extensionDistance;
88
+ }
89
+
90
+ // Validate precision
91
+ if (fixed.precision !== undefined && (fixed.precision < 0 || fixed.precision > 10)) {
92
+ console.warn('[ManhattanRouter] Invalid precision, using default');
93
+ fixed.precision = _defaults.defaults.precision;
94
+ }
95
+ return fixed;
96
+ }
97
+
98
+ /**
99
+ * Resolve adaptive step configuration
100
+ */
101
+ function resolveAdaptiveStepConfig(config) {
102
+ if (!config) {
103
+ return {
104
+ ..._AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG
105
+ };
106
+ }
107
+ return {
108
+ enabled: config.enabled ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.enabled,
109
+ minStep: config.minStep ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.minStep,
110
+ maxStep: config.maxStep ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.maxStep,
111
+ densityBased: {
112
+ enabled: config.densityBased?.enabled ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.densityBased.enabled,
113
+ threshold: config.densityBased?.threshold ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.densityBased.threshold
114
+ },
115
+ distanceBased: {
116
+ enabled: config.distanceBased?.enabled ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.distanceBased.enabled,
117
+ shortPathThreshold: config.distanceBased?.shortPathThreshold ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.distanceBased.shortPathThreshold,
118
+ longPathThreshold: config.distanceBased?.longPathThreshold ?? _AdaptiveStepCalculator.DEFAULT_ADAPTIVE_STEP_CONFIG.distanceBased.longPathThreshold
119
+ }
120
+ };
121
+ }
122
+
123
+ /**
124
+ * Resolve performance configuration
125
+ */
126
+ function resolvePerformanceConfig(config) {
127
+ if (!config) {
128
+ return {
129
+ ...DEFAULT_PERFORMANCE_CONFIG
130
+ };
131
+ }
132
+ return {
133
+ enableCache: config.enableCache ?? DEFAULT_PERFORMANCE_CONFIG.enableCache,
134
+ cacheSize: config.cacheSize ?? DEFAULT_PERFORMANCE_CONFIG.cacheSize,
135
+ enableQuadTree: config.enableQuadTree ?? DEFAULT_PERFORMANCE_CONFIG.enableQuadTree,
136
+ earlyTermination: config.earlyTermination ?? DEFAULT_PERFORMANCE_CONFIG.earlyTermination
137
+ };
138
+ }
139
+
140
+ /**
141
+ * Resolve debug configuration
142
+ */
143
+ function resolveDebugConfig(config) {
144
+ if (!config) {
145
+ return {
146
+ ...DEFAULT_DEBUG_CONFIG
147
+ };
148
+ }
149
+ return {
150
+ enableLogging: config.enableLogging ?? DEFAULT_DEBUG_CONFIG.enableLogging,
151
+ enableMetrics: config.enableMetrics ?? DEFAULT_DEBUG_CONFIG.enableMetrics,
152
+ logLevel: config.logLevel ?? DEFAULT_DEBUG_CONFIG.logLevel
153
+ };
154
+ }
155
+
38
156
  /**
39
157
  * Resolve options by merging user options with defaults
40
158
  */
41
159
  function resolveOptions(options = {}) {
42
- const step = options.step ?? _defaults.defaults.step;
43
- const maxLoopCount = options.maxLoopCount ?? _defaults.defaults.maxLoopCount;
44
- const precision = options.precision ?? _defaults.defaults.precision;
45
- const maxDirectionChange = options.maxDirectionChange ?? _defaults.defaults.maxDirectionChange;
46
- const startDirections = options.startDirections ?? _defaults.defaults.startDirections;
47
- const endDirections = options.endDirections ?? _defaults.defaults.endDirections;
48
- const excludeNodes = options.excludeNodes ?? _defaults.defaults.excludeNodes;
49
- const excludeShapes = options.excludeShapes ?? _defaults.defaults.excludeShapes;
50
- const excludeTerminals = options.excludeTerminals ?? _defaults.defaults.excludeTerminals;
51
- const borderRadius = options.borderRadius ?? _defaults.defaults.borderRadius;
52
- const extensionDistance = options.extensionDistance ?? _defaults.defaults.extensionDistance;
53
- const penalties = options.penalties ?? _defaults.defaults.penalties;
54
- const fallbackRoute = options.fallbackRoute;
160
+ // Validate and fix options first
161
+ const validatedOptions = validateAndFixOptions(options);
162
+ const step = validatedOptions.step ?? _defaults.defaults.step;
163
+ const maxLoopCount = validatedOptions.maxLoopCount ?? _defaults.defaults.maxLoopCount;
164
+ const precision = validatedOptions.precision ?? _defaults.defaults.precision;
165
+ const maxDirectionChange = validatedOptions.maxDirectionChange ?? _defaults.defaults.maxDirectionChange;
166
+ const startDirections = validatedOptions.startDirections ?? _defaults.defaults.startDirections;
167
+ const endDirections = validatedOptions.endDirections ?? _defaults.defaults.endDirections;
168
+ const excludeNodes = validatedOptions.excludeNodes ?? _defaults.defaults.excludeNodes;
169
+ const excludeShapes = validatedOptions.excludeShapes ?? _defaults.defaults.excludeShapes;
170
+ const excludeTerminals = validatedOptions.excludeTerminals ?? _defaults.defaults.excludeTerminals;
171
+ const borderRadius = validatedOptions.borderRadius ?? _defaults.defaults.borderRadius;
172
+ const extensionDistance = validatedOptions.extensionDistance ?? _defaults.defaults.extensionDistance;
173
+ const penalties = validatedOptions.penalties ?? _defaults.defaults.penalties;
174
+ const fallbackRoute = validatedOptions.fallbackRoute;
55
175
 
56
176
  // Convert padding to paddingBox
57
- const padding = options.padding ?? _defaults.defaults.padding;
177
+ const padding = validatedOptions.padding ?? _defaults.defaults.padding;
58
178
  const sides = normalizePadding(padding);
59
179
  const paddingBox = {
60
180
  x: -sides.left,
@@ -95,6 +215,11 @@ function resolveOptions(options = {}) {
95
215
  const point2 = new _geometry.Point(direction.offsetX, direction.offsetY);
96
216
  direction.angle = normalizeAngle(point1.theta(point2));
97
217
  });
218
+
219
+ // Resolve new configuration sections
220
+ const adaptiveStep = resolveAdaptiveStepConfig(validatedOptions.adaptiveStep);
221
+ const performance = resolvePerformanceConfig(validatedOptions.performance);
222
+ const debug = resolveDebugConfig(validatedOptions.debug);
98
223
  return {
99
224
  step,
100
225
  maxLoopCount,
@@ -108,13 +233,16 @@ function resolveOptions(options = {}) {
108
233
  paddingBox,
109
234
  borderRadius,
110
235
  extensionDistance,
111
- sourcePosition: options.sourcePosition,
112
- targetPosition: options.targetPosition,
236
+ sourcePosition: validatedOptions.sourcePosition,
237
+ targetPosition: validatedOptions.targetPosition,
113
238
  directionMap: _defaults.directionMap,
114
239
  directions,
115
240
  penalties,
116
241
  cost,
117
242
  fallbackRoute,
118
- previousDirectionAngle: undefined
243
+ previousDirectionAngle: undefined,
244
+ adaptiveStep,
245
+ performance,
246
+ debug
119
247
  };
120
248
  }
@@ -1,4 +1,5 @@
1
1
  import { Point } from '../geometry';
2
+ import type { AdaptiveStepConfig } from '../utils/AdaptiveStepCalculator';
2
3
  /**
3
4
  * Direction type for routing
4
5
  */
@@ -34,6 +35,30 @@ export interface InternalNode {
34
35
  * Node lookup map type (ReactFlow's internal structure)
35
36
  */
36
37
  export type NodeLookup = Map<string, InternalNode>;
38
+ /**
39
+ * Performance optimization configuration
40
+ */
41
+ export interface PerformanceConfig {
42
+ /** Enable path caching */
43
+ enableCache?: boolean;
44
+ /** Maximum cache size */
45
+ cacheSize?: number;
46
+ /** Enable QuadTree for obstacle queries */
47
+ enableQuadTree?: boolean;
48
+ /** Enable early termination when good path found */
49
+ earlyTermination?: boolean;
50
+ }
51
+ /**
52
+ * Debug configuration
53
+ */
54
+ export interface DebugConfig {
55
+ /** Enable logging */
56
+ enableLogging?: boolean;
57
+ /** Enable performance metrics collection */
58
+ enableMetrics?: boolean;
59
+ /** Log level */
60
+ logLevel?: 'error' | 'warn' | 'info' | 'debug';
61
+ }
37
62
  /**
38
63
  * Manhattan router configuration options
39
64
  */
@@ -121,6 +146,19 @@ export interface ManhattanRouterOptions {
121
146
  * Fallback route function when pathfinding fails
122
147
  */
123
148
  fallbackRoute?: (from: Point, to: Point) => Point[];
149
+ /**
150
+ * Adaptive step configuration
151
+ * Automatically adjusts step size based on node density and path distance
152
+ */
153
+ adaptiveStep?: Partial<AdaptiveStepConfig>;
154
+ /**
155
+ * Performance optimization configuration
156
+ */
157
+ performance?: PerformanceConfig;
158
+ /**
159
+ * Debug configuration
160
+ */
161
+ debug?: DebugConfig;
124
162
  }
125
163
  /**
126
164
  * Resolved options with all defaults applied
@@ -165,5 +203,8 @@ export interface ResolvedOptions {
165
203
  cost: number;
166
204
  fallbackRoute?: (from: Point, to: Point) => Point[];
167
205
  previousDirectionAngle?: number | null;
206
+ adaptiveStep: AdaptiveStepConfig;
207
+ performance: Required<PerformanceConfig>;
208
+ debug: Required<DebugConfig>;
168
209
  }
169
210
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/options/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAEnC;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE3D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClC,SAAS,EAAE;QACT,gBAAgB,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAC3C,CAAA;IACD,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B;;;OAGG;IACH,eAAe,CAAC,EAAE,SAAS,EAAE,CAAA;IAE7B;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,EAAE,CAAA;IAE3B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IAExB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAA;IAE1C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAE/E;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAEvC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,KAAK,KAAK,EAAE,CAAA;CACpD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,eAAe,EAAE,SAAS,EAAE,CAAA;IAC5B,aAAa,EAAE,SAAS,EAAE,CAAA;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,gBAAgB,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAA;IACzC,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE;QACZ,GAAG,EAAE,KAAK,CAAA;QACV,KAAK,EAAE,KAAK,CAAA;QACZ,MAAM,EAAE,KAAK,CAAA;QACb,IAAI,EAAE,KAAK,CAAA;KACZ,CAAA;IACD,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAC,CAAA;IACF,SAAS,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,KAAK,KAAK,EAAE,CAAA;IACnD,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACvC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/options/types.ts"],"names":[],"mappings":"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"}