@tscircuit/core 0.0.2151 → 0.0.2153

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 (2) hide show
  1. package/dist/index.js +281 -101
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -7179,50 +7179,248 @@ function getSavedTraceViaContactWidths(route, viaIndex, fallbackWidth) {
7179
7179
  };
7180
7180
  }
7181
7181
 
7182
- // lib/components/primitive-components/Trace/Trace_doInitialPcbTraceTeardropRender.ts
7183
- var generatedRoutes = /* @__PURE__ */ new WeakMap();
7184
- function hasSameGeneratedGeometry(current, generated) {
7185
- if (current === generated) return true;
7186
- if (current.length !== generated.length) return false;
7187
- const geometry = (point6) => {
7188
- const { is_inside_copper_pour, copper_pour_id, ...rest } = point6;
7189
- return JSON.stringify(rest);
7190
- };
7191
- return current.every(
7192
- (point6, index2) => geometry(point6) === geometry(generated[index2])
7182
+ // lib/components/primitive-components/Trace/update-pcb-trace-teardrop-contacts.ts
7183
+ var pcbTraceTeardropRenderStateByRoot = /* @__PURE__ */ new WeakMap();
7184
+ function getRoutePointGeometryJson(routePoint) {
7185
+ const { is_inside_copper_pour, copper_pour_id, ...rest } = routePoint;
7186
+ return JSON.stringify(rest);
7187
+ }
7188
+ function hasSameGeneratedGeometry(currentRoute, generatedRoute) {
7189
+ if (currentRoute === generatedRoute) return true;
7190
+ if (currentRoute.length !== generatedRoute.length) return false;
7191
+ return currentRoute.every(
7192
+ (routePoint, routePointIndex) => getRoutePointGeometryJson(routePoint) === getRoutePointGeometryJson(generatedRoute[routePointIndex])
7193
+ );
7194
+ }
7195
+ function getPcbTraceTeardropRenderStateByPcbTraceId(root) {
7196
+ const existingState = pcbTraceTeardropRenderStateByRoot.get(root);
7197
+ if (existingState) return existingState;
7198
+ const createdState = /* @__PURE__ */ new Map();
7199
+ pcbTraceTeardropRenderStateByRoot.set(root, createdState);
7200
+ return createdState;
7201
+ }
7202
+ function refreshPcbTraceTeardropBaseline({
7203
+ pcbTrace,
7204
+ pcbTraceTeardropRenderState
7205
+ }) {
7206
+ if (hasSameGeneratedGeometry(
7207
+ pcbTrace.route,
7208
+ pcbTraceTeardropRenderState.generatedRoute
7209
+ )) {
7210
+ return false;
7211
+ }
7212
+ pcbTraceTeardropRenderState.originalRoute = pcbTrace.route;
7213
+ pcbTraceTeardropRenderState.generatedRoute = pcbTrace.route;
7214
+ return true;
7215
+ }
7216
+ function getRouteWithExplicitViaContacts({
7217
+ route,
7218
+ contacts
7219
+ }) {
7220
+ return route.flatMap((routePoint, routePointIndex) => {
7221
+ if (routePoint.route_type !== "via" || !contacts.some(
7222
+ (contact) => Math.hypot(contact.x - routePoint.x, contact.y - routePoint.y) < 1e-6
7223
+ )) {
7224
+ return [routePoint];
7225
+ }
7226
+ const { fromWidth, toWidth } = getSavedTraceViaContactWidths(
7227
+ route,
7228
+ routePointIndex,
7229
+ 0
7230
+ );
7231
+ if (!fromWidth || !toWidth) return [routePoint];
7232
+ const previousRoutePoint = route[routePointIndex - 1];
7233
+ const nextRoutePoint = route[routePointIndex + 1];
7234
+ const explicitViaContactRoute = [];
7235
+ if (!(previousRoutePoint?.route_type === "wire" && previousRoutePoint.x === routePoint.x && previousRoutePoint.y === routePoint.y && previousRoutePoint.layer === routePoint.from_layer)) {
7236
+ explicitViaContactRoute.push({
7237
+ route_type: "wire",
7238
+ x: routePoint.x,
7239
+ y: routePoint.y,
7240
+ width: fromWidth,
7241
+ layer: routePoint.from_layer
7242
+ });
7243
+ }
7244
+ explicitViaContactRoute.push(routePoint);
7245
+ if (!(nextRoutePoint?.route_type === "wire" && nextRoutePoint.x === routePoint.x && nextRoutePoint.y === routePoint.y && nextRoutePoint.layer === routePoint.to_layer)) {
7246
+ explicitViaContactRoute.push({
7247
+ route_type: "wire",
7248
+ x: routePoint.x,
7249
+ y: routePoint.y,
7250
+ width: toWidth,
7251
+ layer: routePoint.to_layer
7252
+ });
7253
+ }
7254
+ return explicitViaContactRoute;
7255
+ });
7256
+ }
7257
+ function renderPcbTraceTeardrops({
7258
+ root,
7259
+ pcbTraceId,
7260
+ pcbTraceTeardropRenderStateByPcbTraceId
7261
+ }) {
7262
+ const pcbTraceTeardropRenderState = pcbTraceTeardropRenderStateByPcbTraceId.get(pcbTraceId);
7263
+ if (!pcbTraceTeardropRenderState) return;
7264
+ const pcbTrace = root.db.pcb_trace.get(pcbTraceId);
7265
+ if (!pcbTrace) {
7266
+ pcbTraceTeardropRenderStateByPcbTraceId.delete(pcbTraceId);
7267
+ return;
7268
+ }
7269
+ refreshPcbTraceTeardropBaseline({
7270
+ pcbTrace,
7271
+ pcbTraceTeardropRenderState
7272
+ });
7273
+ const contacts = [
7274
+ ...pcbTraceTeardropRenderState.contactsBySourceTraceId.values()
7275
+ ].flat();
7276
+ const routeWithExplicitViaContacts = getRouteWithExplicitViaContacts({
7277
+ route: pcbTraceTeardropRenderState.originalRoute,
7278
+ contacts
7279
+ });
7280
+ const generatedRoute = addTraceTeardrops(
7281
+ routeWithExplicitViaContacts,
7282
+ contacts
7193
7283
  );
7284
+ root.db.pcb_trace.update(pcbTraceId, { route: generatedRoute });
7285
+ if (contacts.length === 0) {
7286
+ pcbTraceTeardropRenderStateByPcbTraceId.delete(pcbTraceId);
7287
+ return;
7288
+ }
7289
+ pcbTraceTeardropRenderState.generatedRoute = generatedRoute;
7194
7290
  }
7291
+ function updatePcbTraceTeardropContacts({
7292
+ root,
7293
+ sourceTraceId,
7294
+ contactsByPcbTraceId
7295
+ }) {
7296
+ const pcbTraceTeardropRenderStateByPcbTraceId = getPcbTraceTeardropRenderStateByPcbTraceId(root);
7297
+ const affectedPcbTraceIds = /* @__PURE__ */ new Set();
7298
+ for (const [
7299
+ pcbTraceId,
7300
+ pcbTraceTeardropRenderState
7301
+ ] of pcbTraceTeardropRenderStateByPcbTraceId) {
7302
+ const pcbTrace = root.db.pcb_trace.get(pcbTraceId);
7303
+ if (!pcbTrace) {
7304
+ pcbTraceTeardropRenderStateByPcbTraceId.delete(pcbTraceId);
7305
+ continue;
7306
+ }
7307
+ if (refreshPcbTraceTeardropBaseline({
7308
+ pcbTrace,
7309
+ pcbTraceTeardropRenderState
7310
+ })) {
7311
+ affectedPcbTraceIds.add(pcbTraceId);
7312
+ }
7313
+ if (pcbTraceTeardropRenderState.contactsBySourceTraceId.delete(sourceTraceId)) {
7314
+ affectedPcbTraceIds.add(pcbTraceId);
7315
+ }
7316
+ }
7317
+ for (const [pcbTraceId, contacts] of contactsByPcbTraceId) {
7318
+ const pcbTrace = root.db.pcb_trace.get(pcbTraceId);
7319
+ if (!pcbTrace || contacts.length === 0) continue;
7320
+ let pcbTraceTeardropRenderState = pcbTraceTeardropRenderStateByPcbTraceId.get(pcbTraceId);
7321
+ if (!pcbTraceTeardropRenderState) {
7322
+ pcbTraceTeardropRenderState = {
7323
+ originalRoute: pcbTrace.route,
7324
+ generatedRoute: pcbTrace.route,
7325
+ contactsBySourceTraceId: /* @__PURE__ */ new Map()
7326
+ };
7327
+ pcbTraceTeardropRenderStateByPcbTraceId.set(
7328
+ pcbTraceId,
7329
+ pcbTraceTeardropRenderState
7330
+ );
7331
+ } else {
7332
+ refreshPcbTraceTeardropBaseline({
7333
+ pcbTrace,
7334
+ pcbTraceTeardropRenderState
7335
+ });
7336
+ }
7337
+ pcbTraceTeardropRenderState.contactsBySourceTraceId.set(
7338
+ sourceTraceId,
7339
+ contacts
7340
+ );
7341
+ affectedPcbTraceIds.add(pcbTraceId);
7342
+ }
7343
+ for (const pcbTraceId of affectedPcbTraceIds) {
7344
+ renderPcbTraceTeardrops({
7345
+ root,
7346
+ pcbTraceId,
7347
+ pcbTraceTeardropRenderStateByPcbTraceId
7348
+ });
7349
+ }
7350
+ }
7351
+
7352
+ // lib/components/primitive-components/Trace/Trace_doInitialPcbTraceTeardropRender.ts
7195
7353
  function getPadDiameter(pad) {
7196
7354
  if (pad.shape === "polygon") return 0;
7197
7355
  if (pad.shape === "circle") return pad.radius * 2;
7198
7356
  return Math.min(pad.width, pad.height);
7199
7357
  }
7200
- function Trace_doInitialPcbTraceTeardropRender(trace) {
7201
- if (!trace.root || trace.root.pcbDisabled || !trace.source_trace_id) return;
7202
- const { db: db2 } = trace.root;
7203
- const props = trace._parsedProps;
7204
- const previous = generatedRoutes.get(trace);
7205
- for (const [id, routes] of previous ?? []) {
7206
- const current = db2.pcb_trace.get(id);
7207
- if (current && hasSameGeneratedGeometry(current.route, routes.generated))
7208
- db2.pcb_trace.update(id, { route: routes.original });
7209
- }
7210
- generatedRoutes.delete(trace);
7211
- if (!props.pcbTeardrops && !props.pcbTeardropStart && !props.pcbTeardropEnd)
7212
- return;
7213
- const connected = trace._findConnectedPorts();
7214
- if (!connected.allPortsFound) return;
7215
- const selectors = trace._getTracePortOrNetSelectorListFromProps();
7216
- const enabledPorts = connected.portsWithSelectors.map(
7217
- ({ port, selector }) => ({
7218
- port,
7219
- enabled: selector === selectors[0] ? props.pcbTeardropStart ?? props.pcbTeardrops ?? false : selector === selectors.at(-1) ? props.pcbTeardropEnd ?? props.pcbTeardrops ?? false : props.pcbTeardrops ?? false
7220
- })
7221
- );
7358
+ function getConnectedPcbTraces({
7359
+ root,
7360
+ sourceTraceId
7361
+ }) {
7362
+ const sourceTrace = root.db.source_trace.get(sourceTraceId);
7363
+ const connectivityMapKey = sourceTrace?.subcircuit_connectivity_map_key;
7364
+ if (!connectivityMapKey) {
7365
+ return root.db.pcb_trace.list({ source_trace_id: sourceTraceId });
7366
+ }
7367
+ return root.db.pcb_trace.list().filter((pcbTrace) => {
7368
+ if (pcbTrace.source_trace_id === sourceTraceId) return true;
7369
+ if (!pcbTrace.source_trace_id) return false;
7370
+ const routedSourceTrace = root.db.source_trace.get(pcbTrace.source_trace_id);
7371
+ return routedSourceTrace?.subcircuit_connectivity_map_key === connectivityMapKey;
7372
+ });
7373
+ }
7374
+ function getTeardropContacts({
7375
+ root,
7376
+ pcbTrace,
7377
+ enabledPorts,
7378
+ padContacts,
7379
+ enableUnmatchedVias
7380
+ }) {
7381
+ const contacts = [...padContacts];
7382
+ for (const via of root.db.pcb_via.list({
7383
+ pcb_trace_id: pcbTrace.pcb_trace_id
7384
+ })) {
7385
+ const endpoint = enabledPorts.find(({ port }) => {
7386
+ const position = port._getGlobalPcbPositionAfterLayout();
7387
+ return Math.hypot(position.x - via.x, position.y - via.y) < 1e-6;
7388
+ });
7389
+ if (!(endpoint ? endpoint.enabled : enableUnmatchedVias)) continue;
7390
+ for (const layer of via.layers) {
7391
+ contacts.push({
7392
+ x: via.x,
7393
+ y: via.y,
7394
+ layer,
7395
+ diameter: via.outer_diameter
7396
+ });
7397
+ }
7398
+ }
7399
+ return contacts;
7400
+ }
7401
+ function isTeardropEnabledForSelector({
7402
+ selector,
7403
+ selectors,
7404
+ props
7405
+ }) {
7406
+ if (selector === selectors[0]) {
7407
+ return props.pcbTeardropStart ?? props.pcbTeardrops ?? false;
7408
+ }
7409
+ if (selector === selectors.at(-1)) {
7410
+ return props.pcbTeardropEnd ?? props.pcbTeardrops ?? false;
7411
+ }
7412
+ return props.pcbTeardrops ?? false;
7413
+ }
7414
+ function getPadContacts({
7415
+ root,
7416
+ enabledPorts
7417
+ }) {
7222
7418
  const padContacts = [];
7223
7419
  for (const { port, enabled } of enabledPorts) {
7224
7420
  if (!enabled || !port.pcb_port_id) continue;
7225
- for (const pad of db2.pcb_smtpad.list({ pcb_port_id: port.pcb_port_id })) {
7421
+ for (const pad of root.db.pcb_smtpad.list({
7422
+ pcb_port_id: port.pcb_port_id
7423
+ })) {
7226
7424
  if (pad.shape === "polygon") continue;
7227
7425
  padContacts.push({
7228
7426
  x: pad.x,
@@ -7231,84 +7429,66 @@ function Trace_doInitialPcbTraceTeardropRender(trace) {
7231
7429
  diameter: getPadDiameter(pad)
7232
7430
  });
7233
7431
  }
7234
- for (const hole of db2.pcb_plated_hole.list({
7432
+ for (const hole of root.db.pcb_plated_hole.list({
7235
7433
  pcb_port_id: port.pcb_port_id
7236
7434
  })) {
7237
7435
  if (hole.shape !== "circle") continue;
7238
- for (const layer of hole.layers)
7436
+ for (const layer of hole.layers) {
7239
7437
  padContacts.push({
7240
7438
  x: hole.x,
7241
7439
  y: hole.y,
7242
7440
  layer,
7243
7441
  diameter: hole.outer_diameter
7244
7442
  });
7443
+ }
7245
7444
  }
7246
7445
  }
7247
- const outputs = /* @__PURE__ */ new Map();
7248
- for (const pcbTrace of db2.pcb_trace.list({
7249
- source_trace_id: trace.source_trace_id
7250
- })) {
7251
- const contacts = [...padContacts];
7252
- for (const via of db2.pcb_via.list({
7253
- pcb_trace_id: pcbTrace.pcb_trace_id
7446
+ return padContacts;
7447
+ }
7448
+ function Trace_doInitialPcbTraceTeardropRender(trace) {
7449
+ if (!trace.root || trace.root.pcbDisabled || !trace.source_trace_id) return;
7450
+ const root = trace.root;
7451
+ const sourceTraceId = trace.source_trace_id;
7452
+ const props = trace._parsedProps;
7453
+ const contactsByPcbTraceId = /* @__PURE__ */ new Map();
7454
+ const anyTeardropsEnabled = Boolean(
7455
+ props.pcbTeardrops || props.pcbTeardropStart || props.pcbTeardropEnd
7456
+ );
7457
+ const connected = anyTeardropsEnabled ? trace._findConnectedPorts() : void 0;
7458
+ if (connected?.allPortsFound) {
7459
+ const selectors = trace._getTracePortOrNetSelectorListFromProps();
7460
+ const enabledPorts = connected.portsWithSelectors.map(
7461
+ ({ port, selector }) => ({
7462
+ port,
7463
+ enabled: isTeardropEnabledForSelector({
7464
+ selector,
7465
+ selectors,
7466
+ props
7467
+ })
7468
+ })
7469
+ );
7470
+ const padContacts = getPadContacts({ root, enabledPorts });
7471
+ for (const pcbTrace of getConnectedPcbTraces({
7472
+ root,
7473
+ sourceTraceId
7254
7474
  })) {
7255
- const endpoint = enabledPorts.find(({ port }) => {
7256
- const position = port._getGlobalPcbPositionAfterLayout();
7257
- return Math.hypot(position.x - via.x, position.y - via.y) < 1e-6;
7258
- });
7259
- if (!(endpoint ? endpoint.enabled : props.pcbTeardrops)) continue;
7260
- for (const layer of via.layers)
7261
- contacts.push({
7262
- x: via.x,
7263
- y: via.y,
7264
- layer,
7265
- diameter: via.outer_diameter
7266
- });
7475
+ contactsByPcbTraceId.set(
7476
+ pcbTrace.pcb_trace_id,
7477
+ getTeardropContacts({
7478
+ root,
7479
+ pcbTrace,
7480
+ enabledPorts,
7481
+ padContacts,
7482
+ enableUnmatchedVias: props.pcbTeardrops ?? false
7483
+ })
7484
+ );
7267
7485
  }
7268
- const wireContacts = pcbTrace.route.flatMap(
7269
- (point6, index2) => {
7270
- if (point6.route_type !== "via" || !contacts.some(
7271
- (contact) => Math.hypot(contact.x - point6.x, contact.y - point6.y) < 1e-6
7272
- ))
7273
- return [point6];
7274
- const { fromWidth, toWidth } = getSavedTraceViaContactWidths(
7275
- pcbTrace.route,
7276
- index2,
7277
- 0
7278
- );
7279
- if (!fromWidth || !toWidth) return [point6];
7280
- const before = pcbTrace.route[index2 - 1];
7281
- const after = pcbTrace.route[index2 + 1];
7282
- const result = [];
7283
- if (!(before?.route_type === "wire" && before.x === point6.x && before.y === point6.y && before.layer === point6.from_layer))
7284
- result.push({
7285
- route_type: "wire",
7286
- x: point6.x,
7287
- y: point6.y,
7288
- width: fromWidth,
7289
- layer: point6.from_layer
7290
- });
7291
- result.push(point6);
7292
- if (!(after?.route_type === "wire" && after.x === point6.x && after.y === point6.y && after.layer === point6.to_layer))
7293
- result.push({
7294
- route_type: "wire",
7295
- x: point6.x,
7296
- y: point6.y,
7297
- width: toWidth,
7298
- layer: point6.to_layer
7299
- });
7300
- return result;
7301
- }
7302
- );
7303
- const route = addTraceTeardrops(wireContacts, contacts);
7304
- if (route.length === pcbTrace.route.length) continue;
7305
- outputs.set(pcbTrace.pcb_trace_id, {
7306
- original: pcbTrace.route,
7307
- generated: route
7308
- });
7309
- db2.pcb_trace.update(pcbTrace.pcb_trace_id, { route });
7310
7486
  }
7311
- generatedRoutes.set(trace, outputs);
7487
+ updatePcbTraceTeardropContacts({
7488
+ root,
7489
+ sourceTraceId,
7490
+ contactsByPcbTraceId
7491
+ });
7312
7492
  }
7313
7493
 
7314
7494
  // lib/components/primitive-components/Trace/Trace_doInitialPcbTraceRender.ts
@@ -118982,7 +119162,7 @@ var RoutingPhasePreparationError = class extends Error {
118982
119162
  var package_default = {
118983
119163
  name: "@tscircuit/core",
118984
119164
  type: "module",
118985
- version: "0.0.2150",
119165
+ version: "0.0.2152",
118986
119166
  types: "dist/index.d.ts",
118987
119167
  main: "dist/index.js",
118988
119168
  module: "dist/index.js",
@@ -119057,7 +119237,7 @@ var package_default = {
119057
119237
  "bun-match-svg": "0.0.12",
119058
119238
  "calculate-elbow": "^0.0.12",
119059
119239
  "chokidar-cli": "^3.0.0",
119060
- "circuit-json": "^0.0.525",
119240
+ "circuit-json": "^0.0.528",
119061
119241
  "circuit-json-to-bpc": "^0.0.13",
119062
119242
  "circuit-json-to-connectivity-map": "^0.0.33",
119063
119243
  "circuit-json-to-gltf": "^0.0.151",
@@ -119126,7 +119306,7 @@ var package_default = {
119126
119306
  overrides: {
119127
119307
  "@tscircuit/circuit-json-util": "^0.0.122",
119128
119308
  "@tscircuit/props": "^0.0.701",
119129
- "circuit-json": "^0.0.525",
119309
+ "circuit-json": "^0.0.528",
119130
119310
  "@tscircuit/cableprinter": "^0.0.6"
119131
119311
  }
119132
119312
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.2151",
4
+ "version": "0.0.2153",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -76,7 +76,7 @@
76
76
  "bun-match-svg": "0.0.12",
77
77
  "calculate-elbow": "^0.0.12",
78
78
  "chokidar-cli": "^3.0.0",
79
- "circuit-json": "^0.0.525",
79
+ "circuit-json": "^0.0.528",
80
80
  "circuit-json-to-bpc": "^0.0.13",
81
81
  "circuit-json-to-connectivity-map": "^0.0.33",
82
82
  "circuit-json-to-gltf": "^0.0.151",
@@ -145,7 +145,7 @@
145
145
  "overrides": {
146
146
  "@tscircuit/circuit-json-util": "^0.0.122",
147
147
  "@tscircuit/props": "^0.0.701",
148
- "circuit-json": "^0.0.525",
148
+ "circuit-json": "^0.0.528",
149
149
  "@tscircuit/cableprinter": "^0.0.6"
150
150
  }
151
151
  }