@tscircuit/core 0.0.694 → 0.0.696

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/dist/index.d.ts CHANGED
@@ -54,6 +54,7 @@ declare abstract class Renderable implements IRenderable {
54
54
  protected _emitRenderLifecycleEvent(phase: RenderPhase, startOrEnd: "start" | "end"): void;
55
55
  getString(): string;
56
56
  _hasIncompleteAsyncEffects(): boolean;
57
+ private _hasIncompleteAsyncEffectsInSubtreeForPhase;
57
58
  getCurrentRenderPhase(): RenderPhase | null;
58
59
  getRenderGraph(): Record<string, any>;
59
60
  runRenderCycle(): void;
@@ -965,6 +966,7 @@ declare class Port extends PrimitiveComponent<typeof portProps> {
965
966
  doInitialSourceRender(): void;
966
967
  doInitialSourceParentAttachment(): void;
967
968
  doInitialPcbPortRender(): void;
969
+ updatePcbPortRender(): void;
968
970
  doInitialSchematicPortRender(): void;
969
971
  _getSubcircuitConnectivityKey(): string | undefined;
970
972
  _setPositionFromLayout(newCenter: {
package/dist/index.js CHANGED
@@ -126,6 +126,9 @@ var orderedRenderPhases = [
126
126
  "CadModelRender",
127
127
  "PartsEngineRender"
128
128
  ];
129
+ var asyncPhaseDependencies = {
130
+ PcbTraceRender: ["PcbFootprintStringRender"]
131
+ };
129
132
  var globalRenderCounter = 0;
130
133
  var Renderable = class {
131
134
  renderPhaseStates;
@@ -227,6 +230,17 @@ ${error.stack}`
227
230
  _hasIncompleteAsyncEffects() {
228
231
  return this._asyncEffects.some((effect) => !effect.complete);
229
232
  }
233
+ _hasIncompleteAsyncEffectsInSubtreeForPhase(phase) {
234
+ for (const e of this._asyncEffects) {
235
+ if (!e.complete && e.phase === phase) return true;
236
+ }
237
+ for (const child of this.children) {
238
+ const renderableChild = child;
239
+ if (renderableChild._hasIncompleteAsyncEffectsInSubtreeForPhase(phase))
240
+ return true;
241
+ }
242
+ return false;
243
+ }
230
244
  getCurrentRenderPhase() {
231
245
  return this._currentRenderPhase;
232
246
  }
@@ -274,6 +288,10 @@ ${error.stack}`
274
288
  const hasIncompleteEffects = this._asyncEffects.filter((e) => e.phase === prevPhase).some((e) => !e.complete);
275
289
  if (hasIncompleteEffects) return;
276
290
  }
291
+ const deps = asyncPhaseDependencies[phase] || [];
292
+ for (const depPhase of deps) {
293
+ if (this._hasIncompleteAsyncEffectsInSubtreeForPhase(depPhase)) return;
294
+ }
277
295
  this._emitRenderLifecycleEvent(phase, "start");
278
296
  if (isInitialized) {
279
297
  if (isDirty) {
@@ -3280,6 +3298,36 @@ var Port = class extends PrimitiveComponent2 {
3280
3298
  );
3281
3299
  }
3282
3300
  }
3301
+ updatePcbPortRender() {
3302
+ if (this.root?.pcbDisabled) return;
3303
+ const { db } = this.root;
3304
+ if (this.pcb_port_id) return;
3305
+ const pcbMatches = this.matchedComponents.filter((c) => c.isPcbPrimitive);
3306
+ if (pcbMatches.length === 0) return;
3307
+ let matchCenter = null;
3308
+ if (pcbMatches.length === 1) {
3309
+ matchCenter = pcbMatches[0]._getPcbCircuitJsonBounds().center;
3310
+ }
3311
+ if (pcbMatches.length > 1) {
3312
+ try {
3313
+ if (areAllPcbPrimitivesOverlapping(pcbMatches)) {
3314
+ matchCenter = getCenterOfPcbPrimitives(pcbMatches);
3315
+ }
3316
+ } catch {
3317
+ }
3318
+ }
3319
+ if (!matchCenter) return;
3320
+ const subcircuit = this.getSubcircuit();
3321
+ const pcb_port = db.pcb_port.insert({
3322
+ pcb_component_id: this.parent?.pcb_component_id,
3323
+ layers: this.getAvailablePcbLayers(),
3324
+ subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
3325
+ pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
3326
+ ...matchCenter,
3327
+ source_port_id: this.source_port_id
3328
+ });
3329
+ this.pcb_port_id = pcb_port.pcb_port_id;
3330
+ }
3283
3331
  doInitialSchematicPortRender() {
3284
3332
  const { db } = this.root;
3285
3333
  const { _parsedProps: props } = this;
@@ -6339,11 +6387,69 @@ var shouldCheckPortForMissingTrace = (component, port) => {
6339
6387
  return true;
6340
6388
  };
6341
6389
 
6342
- // lib/components/base-components/NormalComponent/NormalComponent_doInitialSilkscreenOverlapAdjustment.ts
6343
- import { getBoundingBox } from "@tscircuit/math-utils";
6344
- function doBoundsIntersect(bounds1, bounds2) {
6345
- return !(bounds1.maxX <= bounds2.minX || bounds2.maxX <= bounds1.minX || bounds1.maxY <= bounds2.minY || bounds2.maxY <= bounds1.minY);
6390
+ // lib/components/base-components/NormalComponent/utils/getPcbTextBounds.ts
6391
+ function getPcbTextBounds(text) {
6392
+ const fontSize = text.font_size;
6393
+ const textWidth = text.text.length * fontSize * 0.6;
6394
+ const textHeight = fontSize;
6395
+ const anchorAlignment = text.anchor_alignment || "center";
6396
+ let centerX = text.anchor_position.x;
6397
+ let centerY = text.anchor_position.y;
6398
+ switch (anchorAlignment) {
6399
+ case "top_left":
6400
+ centerX = text.anchor_position.x + textWidth / 2;
6401
+ centerY = text.anchor_position.y + textHeight / 2;
6402
+ break;
6403
+ case "top_center":
6404
+ centerX = text.anchor_position.x;
6405
+ centerY = text.anchor_position.y + textHeight / 2;
6406
+ break;
6407
+ case "top_right":
6408
+ centerX = text.anchor_position.x - textWidth / 2;
6409
+ centerY = text.anchor_position.y + textHeight / 2;
6410
+ break;
6411
+ case "center_left":
6412
+ centerX = text.anchor_position.x + textWidth / 2;
6413
+ centerY = text.anchor_position.y;
6414
+ break;
6415
+ case "center":
6416
+ centerX = text.anchor_position.x;
6417
+ centerY = text.anchor_position.y;
6418
+ break;
6419
+ case "center_right":
6420
+ centerX = text.anchor_position.x - textWidth / 2;
6421
+ centerY = text.anchor_position.y;
6422
+ break;
6423
+ case "bottom_left":
6424
+ centerX = text.anchor_position.x + textWidth / 2;
6425
+ centerY = text.anchor_position.y - textHeight / 2;
6426
+ break;
6427
+ case "bottom_center":
6428
+ centerX = text.anchor_position.x;
6429
+ centerY = text.anchor_position.y - textHeight / 2;
6430
+ break;
6431
+ case "bottom_right":
6432
+ centerX = text.anchor_position.x - textWidth / 2;
6433
+ centerY = text.anchor_position.y - textHeight / 2;
6434
+ break;
6435
+ default:
6436
+ centerX = text.anchor_position.x;
6437
+ centerY = text.anchor_position.y;
6438
+ break;
6439
+ }
6440
+ return {
6441
+ x: centerX - textWidth / 2,
6442
+ y: centerY - textHeight / 2,
6443
+ width: textWidth,
6444
+ height: textHeight
6445
+ };
6346
6446
  }
6447
+
6448
+ // lib/components/base-components/NormalComponent/NormalComponent_doInitialSilkscreenOverlapAdjustment.ts
6449
+ import {
6450
+ getBoundingBox,
6451
+ doBoundsOverlap
6452
+ } from "@tscircuit/math-utils";
6347
6453
  function NormalComponent_doInitialSilkscreenOverlapAdjustment(component) {
6348
6454
  if (!component._adjustSilkscreenTextAutomatically) {
6349
6455
  return;
@@ -6373,33 +6479,34 @@ function NormalComponent_doInitialSilkscreenOverlapAdjustment(component) {
6373
6479
  });
6374
6480
  for (const silkscreenText of silkscreenTexts) {
6375
6481
  const currentPosition = silkscreenText.anchor_position;
6376
- const fontSize = silkscreenText.font_size;
6377
- const textWidth = silkscreenText.text.length * fontSize * 0.6;
6378
- const textHeight = fontSize;
6482
+ const textBounds = getPcbTextBounds(silkscreenText);
6379
6483
  const textBox = {
6380
- center: currentPosition,
6381
- width: textWidth,
6382
- height: textHeight
6484
+ center: {
6485
+ x: textBounds.x + textBounds.width / 2,
6486
+ y: textBounds.y + textBounds.height / 2
6487
+ },
6488
+ width: textBounds.width,
6489
+ height: textBounds.height
6383
6490
  };
6384
- const textBounds = getBoundingBox(textBox);
6385
- const hasIntersection = obstacleBounds.some(
6386
- (obstacle) => doBoundsIntersect(textBounds, obstacle)
6491
+ const textBoundsBox = getBoundingBox(textBox);
6492
+ const hasOverlap = obstacleBounds.some(
6493
+ (obstacle) => doBoundsOverlap(textBoundsBox, obstacle)
6387
6494
  );
6388
- if (!hasIntersection) {
6495
+ if (!hasOverlap) {
6389
6496
  continue;
6390
6497
  }
6391
6498
  const flippedX = 2 * componentCenter.x - currentPosition.x;
6392
6499
  const flippedY = 2 * componentCenter.y - currentPosition.y;
6393
6500
  const flippedTextBox = {
6394
6501
  center: { x: flippedX, y: flippedY },
6395
- width: textWidth,
6396
- height: textHeight
6502
+ width: textBounds.width,
6503
+ height: textBounds.height
6397
6504
  };
6398
6505
  const flippedTextBounds = getBoundingBox(flippedTextBox);
6399
- const flippedHasIntersection = obstacleBounds.some(
6400
- (obstacle) => doBoundsIntersect(flippedTextBounds, obstacle)
6506
+ const flippedHasOverlap = obstacleBounds.some(
6507
+ (obstacle) => doBoundsOverlap(flippedTextBounds, obstacle)
6401
6508
  );
6402
- if (!flippedHasIntersection) {
6509
+ if (!flippedHasOverlap) {
6403
6510
  db.pcb_silkscreen_text.update(silkscreenText.pcb_silkscreen_text_id, {
6404
6511
  anchor_position: {
6405
6512
  x: flippedX,
@@ -6527,6 +6634,11 @@ function NormalComponent_doInitialPcbFootprintStringRender(component, queueAsync
6527
6634
  circuitJson
6528
6635
  );
6529
6636
  component.addAll(fpComponents);
6637
+ for (const child of component.children) {
6638
+ if (child.componentName === "Port") {
6639
+ child._markDirty?.("PcbPortRender");
6640
+ }
6641
+ }
6530
6642
  component._markDirty("InitializePortsFromChildren");
6531
6643
  });
6532
6644
  return;
@@ -14184,7 +14296,7 @@ import { identity as identity6 } from "transformation-matrix";
14184
14296
  var package_default = {
14185
14297
  name: "@tscircuit/core",
14186
14298
  type: "module",
14187
- version: "0.0.693",
14299
+ version: "0.0.695",
14188
14300
  types: "dist/index.d.ts",
14189
14301
  main: "dist/index.js",
14190
14302
  module: "dist/index.js",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.694",
4
+ "version": "0.0.696",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",