@aiready/components 0.14.0 → 0.14.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/components",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "Unified shared components library (UI, charts, hooks, utilities) for AIReady",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -128,7 +128,7 @@
128
128
  "framer-motion": "^12.35.0",
129
129
  "lucide-react": "^0.577.0",
130
130
  "tailwind-merge": "^3.0.0",
131
- "@aiready/core": "0.24.0"
131
+ "@aiready/core": "0.24.3"
132
132
  },
133
133
  "devDependencies": {
134
134
  "@testing-library/jest-dom": "^6.6.5",
@@ -111,7 +111,7 @@ export function useForceSimulation(
111
111
  SimulationNode,
112
112
  SimulationLink
113
113
  > | null>(null);
114
- const stopTimeoutRef = useRef<number | null>(null);
114
+ const stopTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
115
115
 
116
116
  // Create lightweight keys for nodes/links so we only recreate the simulation
117
117
  // when the actual identity/content of inputs change (not when parent passes
@@ -119,9 +119,16 @@ export function useForceSimulation(
119
119
  const nodesKey = initialNodes.map((n) => n.id).join('|');
120
120
  const linksKey = (initialLinks || [])
121
121
  .map((l) => {
122
- const s = typeof l.source === 'string' ? l.source : (l.source as any)?.id;
123
- const t = typeof l.target === 'string' ? l.target : (l.target as any)?.id;
124
- return `${s}->${t}:${(l as any).type || ''}`;
122
+ const sourceId =
123
+ typeof l.source === 'string'
124
+ ? l.source
125
+ : (l.source as SimulationNode)?.id;
126
+ const targetId =
127
+ typeof l.target === 'string'
128
+ ? l.target
129
+ : (l.target as SimulationNode)?.id;
130
+ const linkType = (l as SimulationLink & { type?: string }).type || '';
131
+ return `${sourceId}->${targetId}:${linkType}`;
125
132
  })
126
133
  .join('|');
127
134
 
@@ -143,69 +150,99 @@ export function useForceSimulation(
143
150
  n.x = width / 2 + radius * Math.cos(angle);
144
151
  n.y = height / 2 + radius * Math.sin(angle);
145
152
  // Add very small random velocity to avoid large initial motion
146
- (n as any).vx = (Math.random() - 0.5) * 2;
147
- (n as any).vy = (Math.random() - 0.5) * 2;
153
+ n.vx = (Math.random() - 0.5) * 2;
154
+ n.vy = (Math.random() - 0.5) * 2;
148
155
  });
149
156
  } catch (e) {
150
- void e;
157
+ console.warn('Failed to seed node positions, falling back to random:', e);
151
158
  // If error, fall back to random positions
152
159
  seedRandomPositions(nodesCopy, width, height);
153
160
  }
154
161
 
155
162
  // Create the simulation
156
163
  const simulation = d3.forceSimulation(
157
- nodesCopy as any
158
- ) as unknown as d3.Simulation<SimulationNode, SimulationLink>;
164
+ nodesCopy as SimulationNode[]
165
+ ) as d3.Simulation<SimulationNode, SimulationLink>;
159
166
 
160
167
  // Configure link force separately to avoid using generic type args on d3 helpers
161
168
  try {
162
169
  const linkForce = d3.forceLink(
163
- linksCopy as any
164
- ) as unknown as d3.ForceLink<SimulationNode, SimulationLink>;
170
+ linksCopy as d3.SimulationLinkDatum<SimulationNode>[]
171
+ ) as d3.ForceLink<SimulationNode, d3.SimulationLinkDatum<SimulationNode>>;
165
172
  linkForce
166
- .id((d: any) => d.id)
167
- .distance((d: any) =>
168
- d && d.distance != null ? d.distance : linkDistance
169
- )
173
+ .id((d: SimulationNode) => d.id)
174
+ .distance((d: d3.SimulationLinkDatum<SimulationNode>) => {
175
+ const link = d as SimulationLink & { distance?: number };
176
+ return link && link.distance != null ? link.distance : linkDistance;
177
+ })
170
178
  .strength(linkStrength);
171
- simulation.force('link', linkForce as any);
179
+ simulation.force(
180
+ 'link',
181
+ linkForce as d3.Force<
182
+ SimulationNode,
183
+ d3.SimulationLinkDatum<SimulationNode>
184
+ >
185
+ );
172
186
  } catch (e) {
173
- void e;
187
+ console.warn('Failed to configure link force, using fallback:', e);
174
188
  // fallback: attach a plain link force
175
189
  try {
176
- simulation.force('link', d3.forceLink(linksCopy as any) as any);
177
- } catch (e) {
178
- void e;
190
+ simulation.force(
191
+ 'link',
192
+ d3.forceLink(
193
+ linksCopy as d3.SimulationLinkDatum<SimulationNode>[]
194
+ ) as d3.Force<SimulationNode, d3.SimulationLinkDatum<SimulationNode>>
195
+ );
196
+ } catch (fallbackError) {
197
+ console.warn('Fallback link force also failed:', fallbackError);
179
198
  }
180
199
  }
181
200
  try {
182
201
  simulation.force(
183
202
  'charge',
184
- d3.forceManyBody().strength(chargeStrength) as any
203
+ d3.forceManyBody().strength(chargeStrength) as d3.Force<
204
+ SimulationNode,
205
+ d3.SimulationLinkDatum<SimulationNode>
206
+ >
185
207
  );
186
208
  simulation.force(
187
209
  'center',
188
- d3.forceCenter(width / 2, height / 2).strength(centerStrength) as any
210
+ d3
211
+ .forceCenter(width / 2, height / 2)
212
+ .strength(centerStrength) as d3.Force<
213
+ SimulationNode,
214
+ d3.SimulationLinkDatum<SimulationNode>
215
+ >
189
216
  );
190
217
  const collide = d3
191
218
  .forceCollide()
192
- .radius((d: any) => {
193
- const nodeSize = d && d.size ? d.size : 10;
219
+ .radius((d: d3.SimulationNodeDatum) => {
220
+ const node = d as SimulationNode;
221
+ const nodeSize = node && node.size ? (node.size as number) : 10;
194
222
  return nodeSize + collisionRadius;
195
223
  })
196
- .strength(collisionStrength as any) as any;
224
+ .strength(collisionStrength) as d3.Force<
225
+ SimulationNode,
226
+ d3.SimulationLinkDatum<SimulationNode>
227
+ >;
197
228
  simulation.force('collision', collide);
198
229
  simulation.force(
199
230
  'x',
200
231
  d3
201
232
  .forceX(width / 2)
202
- .strength(Math.max(0.02, centerStrength * 0.5)) as any
233
+ .strength(Math.max(0.02, centerStrength * 0.5)) as d3.Force<
234
+ SimulationNode,
235
+ d3.SimulationLinkDatum<SimulationNode>
236
+ >
203
237
  );
204
238
  simulation.force(
205
239
  'y',
206
240
  d3
207
241
  .forceY(height / 2)
208
- .strength(Math.max(0.02, centerStrength * 0.5)) as any
242
+ .strength(Math.max(0.02, centerStrength * 0.5)) as d3.Force<
243
+ SimulationNode,
244
+ d3.SimulationLinkDatum<SimulationNode>
245
+ >
209
246
  );
210
247
  simulation.alphaDecay(alphaDecay);
211
248
  simulation.velocityDecay(velocityDecay);
@@ -213,15 +250,15 @@ export function useForceSimulation(
213
250
  try {
214
251
  simulation.alphaTarget(alphaTarget);
215
252
  } catch (e) {
216
- void e;
253
+ console.warn('Failed to set alpha target:', e);
217
254
  }
218
255
  try {
219
256
  simulation.alpha(warmAlpha);
220
257
  } catch (e) {
221
- void e;
258
+ console.warn('Failed to set initial alpha:', e);
222
259
  }
223
260
  } catch (e) {
224
- void e;
261
+ console.warn('Failed to configure simulation forces:', e);
225
262
  // ignore force configuration errors
226
263
  }
227
264
 
@@ -230,14 +267,14 @@ export function useForceSimulation(
230
267
  // Force-stop timeout to ensure simulation doesn't run forever.
231
268
  if (stopTimeoutRef.current != null) {
232
269
  try {
233
- (globalThis.clearTimeout as any)(stopTimeoutRef.current);
270
+ globalThis.clearTimeout(stopTimeoutRef.current);
234
271
  } catch (e) {
235
- void e;
272
+ console.warn('Failed to clear simulation timeout:', e);
236
273
  }
237
274
  stopTimeoutRef.current = null;
238
275
  }
239
276
  if (maxSimulationTimeMs && maxSimulationTimeMs > 0) {
240
- stopTimeoutRef.current = (globalThis.setTimeout as any)(() => {
277
+ stopTimeoutRef.current = globalThis.setTimeout(() => {
241
278
  try {
242
279
  if (stabilizeOnStop) {
243
280
  stabilizeNodes(nodesCopy);
@@ -245,12 +282,12 @@ export function useForceSimulation(
245
282
  simulation.alpha(0);
246
283
  simulation.stop();
247
284
  } catch (e) {
248
- void e;
285
+ console.warn('Failed to stop simulation:', e);
249
286
  }
250
287
  setIsRunning(false);
251
288
  setNodes([...nodesCopy]);
252
289
  setLinks([...linksCopy]);
253
- }, maxSimulationTimeMs) as unknown as number;
290
+ }, maxSimulationTimeMs);
254
291
  }
255
292
 
256
293
  // Update state on each tick. Batch updates via requestAnimationFrame to avoid
@@ -262,20 +299,20 @@ export function useForceSimulation(
262
299
  if (typeof onTick === 'function')
263
300
  onTick(nodesCopy, linksCopy, simulation);
264
301
  } catch (e) {
265
- void e;
302
+ console.warn('Tick callback error:', e);
266
303
  }
267
304
 
268
305
  // If simulation alpha has cooled below the configured minimum, stop it to
269
306
  // ensure nodes don't drift indefinitely (acts as a hard-stop safeguard).
270
307
  try {
271
- if (simulation.alpha() <= (alphaMin as number)) {
308
+ if (simulation.alpha() <= alphaMin) {
272
309
  try {
273
310
  if (stabilizeOnStop) {
274
311
  stabilizeNodes(nodesCopy);
275
312
  }
276
313
  simulation.stop();
277
314
  } catch (e) {
278
- void e;
315
+ console.warn('Failed to stop simulation:', e);
279
316
  }
280
317
  setAlpha(simulation.alpha());
281
318
  setIsRunning(false);
@@ -284,11 +321,11 @@ export function useForceSimulation(
284
321
  return;
285
322
  }
286
323
  } catch (e) {
287
- void e;
324
+ console.warn('Error checking simulation alpha:', e);
288
325
  }
289
326
 
290
327
  const now = Date.now();
291
- const shouldUpdate = now - lastUpdate >= (tickThrottleMs as number);
328
+ const shouldUpdate = now - lastUpdate >= tickThrottleMs;
292
329
  if (rafId == null && shouldUpdate) {
293
330
  rafId = (
294
331
  globalThis.requestAnimationFrame ||
@@ -300,7 +337,7 @@ export function useForceSimulation(
300
337
  setLinks([...linksCopy]);
301
338
  setAlpha(simulation.alpha());
302
339
  setIsRunning(simulation.alpha() > simulation.alphaMin());
303
- }) as unknown as number;
340
+ });
304
341
  }
305
342
  };
306
343
 
@@ -313,15 +350,15 @@ export function useForceSimulation(
313
350
  // Cleanup on unmount
314
351
  return () => {
315
352
  try {
316
- simulation.on('tick', null as any);
353
+ simulation.on('tick', null);
317
354
  } catch (e) {
318
- void e;
355
+ console.warn('Failed to clear simulation tick handler:', e);
319
356
  }
320
357
  if (stopTimeoutRef.current != null) {
321
358
  try {
322
- (globalThis.clearTimeout as any)(stopTimeoutRef.current);
359
+ globalThis.clearTimeout(stopTimeoutRef.current);
323
360
  } catch (e) {
324
- void e;
361
+ console.warn('Failed to clear timeout on cleanup:', e);
325
362
  }
326
363
  stopTimeoutRef.current = null;
327
364
  }
@@ -332,7 +369,7 @@ export function useForceSimulation(
332
369
  ((id: number) => clearTimeout(id))
333
370
  )(rafId);
334
371
  } catch (e) {
335
- void e;
372
+ console.warn('Failed to cancel animation frame:', e);
336
373
  }
337
374
  rafId = null;
338
375
  }
@@ -371,22 +408,22 @@ export function useForceSimulation(
371
408
  // Reset safety timeout when simulation is manually restarted
372
409
  if (stopTimeoutRef.current != null) {
373
410
  try {
374
- (globalThis.clearTimeout as any)(stopTimeoutRef.current);
411
+ globalThis.clearTimeout(stopTimeoutRef.current);
375
412
  } catch (e) {
376
- void e;
413
+ console.warn('Failed to clear simulation timeout:', e);
377
414
  }
378
415
  stopTimeoutRef.current = null;
379
416
  }
380
417
  if (maxSimulationTimeMs && maxSimulationTimeMs > 0) {
381
- stopTimeoutRef.current = (globalThis.setTimeout as any)(() => {
418
+ stopTimeoutRef.current = globalThis.setTimeout(() => {
382
419
  try {
383
420
  simulationRef.current?.alpha(0);
384
421
  simulationRef.current?.stop();
385
422
  } catch (e) {
386
- void e;
423
+ console.warn('Failed to stop simulation:', e);
387
424
  }
388
425
  setIsRunning(false);
389
- }, maxSimulationTimeMs) as unknown as number;
426
+ }, maxSimulationTimeMs);
390
427
  }
391
428
  }
392
429
  };
@@ -414,17 +451,22 @@ export function useForceSimulation(
414
451
 
415
452
  try {
416
453
  // Only toggle charge and link forces to avoid collapse; keep collision/centering
417
- const charge: any = sim.force('charge');
454
+ const charge = sim.force(
455
+ 'charge'
456
+ ) as d3.ForceManyBody<SimulationNode> | null;
418
457
  if (charge && typeof charge.strength === 'function') {
419
458
  charge.strength(enabled ? originalForcesRef.current.charge : 0);
420
459
  }
421
460
 
422
- const link: any = sim.force('link');
461
+ const link = sim.force('link') as d3.ForceLink<
462
+ SimulationNode,
463
+ d3.SimulationLinkDatum<SimulationNode>
464
+ > | null;
423
465
  if (link && typeof link.strength === 'function') {
424
466
  link.strength(enabled ? originalForcesRef.current.link : 0);
425
467
  }
426
468
  } catch (e) {
427
- void e;
469
+ console.warn('Failed to toggle simulation forces:', e);
428
470
  }
429
471
  };
430
472