@tscircuit/schematic-viewer 2.0.55 → 2.0.57

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 (68) hide show
  1. package/dist/index.js +7 -3
  2. package/dist/index.js.map +1 -1
  3. package/package.json +4 -1
  4. package/.github/workflows/bun-formatcheck.yml +0 -26
  5. package/.github/workflows/bun-pver-release.yml +0 -59
  6. package/.github/workflows/bun-typecheck.yml +0 -26
  7. package/.github/workflows/on-merge-inform-release-tracker.yml +0 -24
  8. package/CLAUDE.md +0 -1
  9. package/biome.json +0 -56
  10. package/bun.lockb +0 -0
  11. package/cosmos.config.json +0 -3
  12. package/cosmos.decorator.tsx +0 -3
  13. package/docs/circuit-to-svg-metadata.md +0 -151
  14. package/docs/dragndrop-spec.md +0 -39
  15. package/examples/example1-resistor-and-capacitor.fixture.tsx +0 -16
  16. package/examples/example10-groups-view-schematic-groups.fixture.tsx +0 -76
  17. package/examples/example11-automatic-grouping-view-schematic-groups.fixture.tsx +0 -109
  18. package/examples/example12-spice-boost-converter.fixture.tsx +0 -78
  19. package/examples/example13-disablegroups.fixture.tsx +0 -30
  20. package/examples/example14-schematic-component-click.fixture.tsx +0 -46
  21. package/examples/example15-analog-simulation-viewer.fixture.tsx +0 -145
  22. package/examples/example16-no-analog-simulation.fixture.tsx +0 -13
  23. package/examples/example17-schematic-ports.fixture.tsx +0 -49
  24. package/examples/example2-small-circuit.fixture.tsx +0 -48
  25. package/examples/example3-small-circuit-without-debug-grid.fixture.tsx +0 -44
  26. package/examples/example4-reset-edit-events.fixture.tsx +0 -57
  27. package/examples/example5-circuit-json-rerender.fixture.tsx +0 -110
  28. package/examples/example6-click-to-interact.fixture.tsx +0 -36
  29. package/examples/example7-schematic-viewer-fix-snapping.fixture.tsx +0 -123
  30. package/examples/example8-color-overrides.fixture.tsx +0 -52
  31. package/examples/example9-spice-rc-charging-voltage-divider.fixture.tsx +0 -77
  32. package/index.html +0 -12
  33. package/lib/components/AnalogSimulationViewer.tsx +0 -300
  34. package/lib/components/ControlledSchematicViewer.tsx +0 -40
  35. package/lib/components/EditIcon.tsx +0 -46
  36. package/lib/components/GridIcon.tsx +0 -45
  37. package/lib/components/MouseTracker.tsx +0 -257
  38. package/lib/components/SchematicComponentMouseTarget.tsx +0 -189
  39. package/lib/components/SchematicPortMouseTarget.tsx +0 -224
  40. package/lib/components/SchematicViewer.tsx +0 -582
  41. package/lib/components/SpiceIcon.tsx +0 -14
  42. package/lib/components/SpicePlot.tsx +0 -221
  43. package/lib/components/SpiceSimulationIcon.tsx +0 -32
  44. package/lib/components/SpiceSimulationOverlay.tsx +0 -250
  45. package/lib/components/ViewMenu.tsx +0 -218
  46. package/lib/components/ViewMenuIcon.tsx +0 -47
  47. package/lib/dev/render-to-circuit-json.ts +0 -8
  48. package/lib/hooks/use-resize-handling.ts +0 -35
  49. package/lib/hooks/useChangeSchematicComponentLocationsInSvg.ts +0 -117
  50. package/lib/hooks/useChangeSchematicTracesForMovedComponents.ts +0 -121
  51. package/lib/hooks/useComponentDragging.ts +0 -251
  52. package/lib/hooks/useLocalStorage.ts +0 -63
  53. package/lib/hooks/useMouseEventsOverBoundingBox.ts +0 -74
  54. package/lib/hooks/useSchematicGroupsOverlay.ts +0 -364
  55. package/lib/hooks/useSpiceSimulation.ts +0 -149
  56. package/lib/index.ts +0 -4
  57. package/lib/types/edit-events.ts +0 -16
  58. package/lib/types/eecircuit-engine.d.ts +0 -147
  59. package/lib/utils/debug.ts +0 -9
  60. package/lib/utils/get-component-offset-due-to-events.ts +0 -43
  61. package/lib/utils/spice-utils.ts +0 -128
  62. package/lib/utils/z-index-map.ts +0 -11
  63. package/lib/workers/spice-simulation.worker.ts +0 -51
  64. package/scripts/build-worker-blob-url.ts +0 -55
  65. package/src/main.tsx +0 -21
  66. package/tsconfig.json +0 -33
  67. package/tsup-webworker.config.ts +0 -13
  68. package/vite.config.js +0 -15
@@ -1,74 +0,0 @@
1
- import {
2
- useContext,
3
- useEffect,
4
- useId,
5
- useMemo,
6
- useRef,
7
- useSyncExternalStore,
8
- } from "react"
9
- import {
10
- MouseTrackerContext,
11
- type BoundingBoxBounds,
12
- } from "../components/MouseTracker"
13
-
14
- interface UseMouseEventsOverBoundingBoxOptions {
15
- bounds: BoundingBoxBounds | null
16
- onClick?: (event: MouseEvent) => void
17
- }
18
-
19
- export const useMouseEventsOverBoundingBox = (
20
- options: UseMouseEventsOverBoundingBoxOptions,
21
- ) => {
22
- const context = useContext(MouseTrackerContext)
23
-
24
- if (!context) {
25
- throw new Error(
26
- "useMouseEventsOverBoundingBox must be used within a MouseTracker",
27
- )
28
- }
29
-
30
- const id = useId()
31
- const latestOptionsRef = useRef(options)
32
- latestOptionsRef.current = options
33
-
34
- const handleClick = useMemo(
35
- () => (event: MouseEvent) => {
36
- latestOptionsRef.current.onClick?.(event)
37
- },
38
- [],
39
- )
40
-
41
- useEffect(() => {
42
- context.registerBoundingBox(id, {
43
- bounds: latestOptionsRef.current.bounds,
44
- onClick: latestOptionsRef.current.onClick ? handleClick : undefined,
45
- })
46
- return () => {
47
- context.unregisterBoundingBox(id)
48
- }
49
- }, [context, handleClick, id])
50
-
51
- useEffect(() => {
52
- context.updateBoundingBox(id, {
53
- bounds: latestOptionsRef.current.bounds,
54
- onClick: latestOptionsRef.current.onClick ? handleClick : undefined,
55
- })
56
- }, [
57
- context,
58
- handleClick,
59
- id,
60
- options.bounds?.minX,
61
- options.bounds?.maxX,
62
- options.bounds?.minY,
63
- options.bounds?.maxY,
64
- options.onClick,
65
- ])
66
-
67
- const hovering = useSyncExternalStore(
68
- context.subscribe,
69
- () => context.isHovering(id),
70
- () => false,
71
- )
72
-
73
- return { hovering }
74
- }
@@ -1,364 +0,0 @@
1
- import { useEffect } from "react"
2
- import { su } from "@tscircuit/soup-util"
3
- import type { CircuitJson } from "circuit-json"
4
-
5
- interface UseSchematicGroupsOverlayOptions {
6
- svgDivRef: React.RefObject<HTMLDivElement | null>
7
- circuitJson: CircuitJson
8
- circuitJsonKey: string
9
- showGroups: boolean
10
- }
11
-
12
- const GROUP_COLORS = [
13
- "#8B0000", // Dark Red
14
- "#2F4F4F", // Dark Slate Gray
15
- "#191970", // Midnight Blue
16
- "#006400", // Dark Green
17
- "#FF4500", // Dark Orange
18
- "#800080", // Purple
19
- "#2E8B57", // Sea Green
20
- "#B8860B", // Dark Goldenrod
21
- "#C71585", // Medium Violet Red
22
- "#008B8B", // Dark Cyan
23
- ]
24
-
25
- export const useSchematicGroupsOverlay = (
26
- options: UseSchematicGroupsOverlayOptions,
27
- ) => {
28
- const { svgDivRef, circuitJson, circuitJsonKey, showGroups } = options
29
-
30
- useEffect(() => {
31
- // Always clean up existing overlays first
32
- if (svgDivRef.current) {
33
- const existingOverlays = svgDivRef.current.querySelectorAll(
34
- ".schematic-group-overlay",
35
- )
36
- existingOverlays.forEach((overlay) => overlay.remove())
37
- }
38
-
39
- if (
40
- !svgDivRef.current ||
41
- !showGroups ||
42
- !circuitJson ||
43
- circuitJson.length === 0
44
- ) {
45
- return
46
- }
47
-
48
- // Small delay to ensure SVG is rendered when groups are enabled from localStorage
49
- const timeoutId = setTimeout(() => {
50
- if (!svgDivRef.current) return
51
-
52
- const svg = svgDivRef.current.querySelector("svg")
53
- if (!svg) {
54
- return
55
- }
56
-
57
- const existingOverlays = svg.querySelectorAll(".schematic-group-overlay")
58
- existingOverlays.forEach((overlay) => overlay.remove())
59
-
60
- try {
61
- const sourceGroups =
62
- su(circuitJson)
63
- .source_group?.list()
64
- .filter((x) => !!!x.is_subcircuit) || []
65
- const schematicComponents =
66
- su(circuitJson).schematic_component?.list() || []
67
-
68
- const sourceGroupHierarchy = new Map<string, string[]>()
69
- sourceGroups.forEach((group) => {
70
- const groupWithParent = group as any
71
- if (groupWithParent.parent_source_group_id) {
72
- const children =
73
- sourceGroupHierarchy.get(
74
- groupWithParent.parent_source_group_id,
75
- ) || []
76
- children.push(group.source_group_id)
77
- sourceGroupHierarchy.set(
78
- groupWithParent.parent_source_group_id,
79
- children,
80
- )
81
- }
82
- })
83
-
84
- const getAllDescendantSourceGroups = (
85
- sourceGroupId: string,
86
- ): string[] => {
87
- const descendants: string[] = []
88
- const children = sourceGroupHierarchy.get(sourceGroupId) || []
89
- for (const child of children) {
90
- descendants.push(child)
91
- descendants.push(...getAllDescendantSourceGroups(child))
92
- }
93
- return descendants
94
- }
95
-
96
- const getGroupDepthLevel = (sourceGroupId: string): number => {
97
- const groupWithParent = sourceGroups.find(
98
- (g) => g.source_group_id === sourceGroupId,
99
- ) as any
100
- if (!groupWithParent?.parent_source_group_id) {
101
- return 0
102
- }
103
- return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id)
104
- }
105
-
106
- const hasMeaningfulGroups =
107
- sourceGroups.length > 0 &&
108
- sourceGroups.some((group) => group.name && group.name.trim() !== "")
109
-
110
- let groupsToRender: Array<{
111
- id: string
112
- name: string
113
- components: any[]
114
- color: string
115
- depthLevel: number
116
- hasChildren: boolean
117
- sourceGroupId?: string
118
- }> = []
119
-
120
- if (hasMeaningfulGroups) {
121
- const groupMap = new Map<string, any[]>()
122
-
123
- for (const comp of schematicComponents) {
124
- const sourceComp = su(circuitJson).source_component.get(
125
- comp.source_component_id!,
126
- )
127
- if (sourceComp?.source_group_id) {
128
- if (!groupMap.has(sourceComp.source_group_id)) {
129
- groupMap.set(sourceComp.source_group_id, [])
130
- }
131
- groupMap.get(sourceComp.source_group_id)!.push(comp)
132
- }
133
- }
134
-
135
- sourceGroups.forEach((group, index) => {
136
- let groupComponents = groupMap.get(group.source_group_id) || []
137
-
138
- const descendantGroups = getAllDescendantSourceGroups(
139
- group.source_group_id,
140
- )
141
- for (const descendantGroupId of descendantGroups) {
142
- const descendantComponents = groupMap.get(descendantGroupId) || []
143
- groupComponents = [...groupComponents, ...descendantComponents]
144
- }
145
-
146
- if (groupComponents.length > 0) {
147
- const depthLevel = getGroupDepthLevel(group.source_group_id)
148
- const hasChildren =
149
- getAllDescendantSourceGroups(group.source_group_id).length > 0
150
-
151
- if (group.name?.startsWith("unnamed_board")) return
152
- groupsToRender.push({
153
- id: group.source_group_id,
154
- name: group.name || `Group ${index + 1}`,
155
- components: groupComponents,
156
- color: GROUP_COLORS[index % GROUP_COLORS.length],
157
- depthLevel,
158
- hasChildren,
159
- sourceGroupId: group.source_group_id,
160
- })
161
- }
162
- })
163
- }
164
- // else {
165
- // const componentTypeGroups = new Map<string, any[]>()
166
-
167
- // for (const comp of schematicComponents) {
168
- // const sourceComp = su(circuitJson).source_component.get(comp.source_component_id)
169
- // if (sourceComp) {
170
- // const componentType = sourceComp.ftype || "other"
171
- // if (!componentTypeGroups.has(componentType)) {
172
- // componentTypeGroups.set(componentType, [])
173
- // }
174
- // componentTypeGroups.get(componentType)!.push(comp)
175
- // }
176
- // }
177
- // // groupsToRender = Array.from(componentTypeGroups.entries()).map(
178
- // // ([type, components], index) => ({
179
- // // id: `type_${type}`,
180
- // // name: `${type.charAt(0).toUpperCase() + type.slice(1)}s`,
181
- // // components,
182
- // // color: GROUP_COLORS[index % GROUP_COLORS.length],
183
- // // depthLevel: 0,
184
- // // hasChildren: false,
185
- // // }),
186
- // // )
187
- // }
188
-
189
- const viewBox = svg.viewBox.baseVal
190
- const svgRect = svg.getBoundingClientRect()
191
- const scale =
192
- Math.min(
193
- svgRect.width / viewBox.width,
194
- svgRect.height / viewBox.height,
195
- ) || 1
196
-
197
- groupsToRender.sort((a, b) => a.depthLevel - b.depthLevel)
198
-
199
- groupsToRender.forEach((group) => {
200
- if (group.components.length === 0) return
201
-
202
- const groupBounds = calculateGroupBounds(group.components, svg)
203
- if (!groupBounds) return
204
-
205
- const basePadding = Math.max(
206
- 8,
207
- Math.min(25, 15 / Math.max(scale, 0.3)),
208
- )
209
- const hierarchyPadding = group.hasChildren ? basePadding * 0.6 : 0
210
- const totalPadding = basePadding + hierarchyPadding
211
-
212
- const baseStrokeWidth = Math.max(1, 2 / Math.max(scale, 0.5))
213
- const strokeWidth =
214
- group.depthLevel === 0 ? baseStrokeWidth : baseStrokeWidth * 0.7
215
-
216
- const baseDashSize = Math.max(4, 8 / Math.max(scale, 0.5))
217
- const dashMultiplier = group.hasChildren ? 1.3 : 1
218
- const dashSize = baseDashSize * dashMultiplier
219
- const gapSize = dashSize * 0.5
220
-
221
- const groupOverlay = document.createElementNS(
222
- "http://www.w3.org/2000/svg",
223
- "rect",
224
- )
225
- groupOverlay.setAttribute("class", "schematic-group-overlay")
226
- groupOverlay.setAttribute(
227
- "x",
228
- (groupBounds.minX - totalPadding).toString(),
229
- )
230
- groupOverlay.setAttribute(
231
- "y",
232
- (groupBounds.minY - totalPadding).toString(),
233
- )
234
- groupOverlay.setAttribute(
235
- "width",
236
- (groupBounds.maxX - groupBounds.minX + totalPadding * 2).toString(),
237
- )
238
- groupOverlay.setAttribute(
239
- "height",
240
- (groupBounds.maxY - groupBounds.minY + totalPadding * 2).toString(),
241
- )
242
- groupOverlay.setAttribute("fill", "none")
243
- groupOverlay.setAttribute("stroke", group.color)
244
- groupOverlay.setAttribute("stroke-width", strokeWidth.toString())
245
- groupOverlay.setAttribute(
246
- "stroke-dasharray",
247
- `${dashSize},${gapSize}`,
248
- )
249
- groupOverlay.setAttribute("opacity", "0.8")
250
- groupOverlay.setAttribute("rx", "0")
251
- groupOverlay.setAttribute("ry", "0")
252
-
253
- const baseFontSize = Math.max(
254
- 6,
255
- Math.min(20, 14 / Math.max(scale, 0.2)),
256
- )
257
- const fontSizeReduction =
258
- group.depthLevel === 0 || group.depthLevel === 1
259
- ? 0
260
- : group.depthLevel * 0.2
261
- const fontSize = baseFontSize * (1 - fontSizeReduction)
262
-
263
- const labelPadding = Math.max(1, fontSize * 0.2)
264
- const labelText = group.name
265
-
266
- const tempText = document.createElementNS(
267
- "http://www.w3.org/2000/svg",
268
- "text",
269
- )
270
- tempText.setAttribute("font-size", fontSize.toString())
271
- tempText.setAttribute("font-family", "Arial, sans-serif")
272
- tempText.textContent = labelText
273
- svg.appendChild(tempText)
274
- const textBBox = tempText.getBBox()
275
- svg.removeChild(tempText)
276
-
277
- const labelWidth = textBBox.width + labelPadding * 2
278
- const labelHeight = fontSize + labelPadding * 2
279
- const labelX = groupBounds.minX - totalPadding
280
- const labelY = groupBounds.minY - totalPadding - labelHeight
281
-
282
- const labelBg = document.createElementNS(
283
- "http://www.w3.org/2000/svg",
284
- "rect",
285
- )
286
- labelBg.setAttribute("class", "schematic-group-overlay")
287
- labelBg.setAttribute("x", labelX.toString())
288
- labelBg.setAttribute("y", (labelY - labelHeight).toString())
289
- labelBg.setAttribute("width", labelWidth.toString())
290
- labelBg.setAttribute("height", labelHeight.toString())
291
- labelBg.setAttribute("fill", "transparent")
292
- labelBg.setAttribute("rx", "0")
293
- labelBg.setAttribute("ry", "0")
294
-
295
- const groupLabel = document.createElementNS(
296
- "http://www.w3.org/2000/svg",
297
- "text",
298
- )
299
- groupLabel.setAttribute("class", "schematic-group-overlay")
300
- groupLabel.setAttribute("x", (labelX + labelPadding).toString())
301
- groupLabel.setAttribute(
302
- "y",
303
- (labelY + labelHeight - labelPadding).toString(),
304
- )
305
- groupLabel.setAttribute("fill", group.color)
306
- groupLabel.setAttribute("font-size", fontSize.toString())
307
- groupLabel.setAttribute("font-family", "Arial, sans-serif")
308
- groupLabel.setAttribute(
309
- "font-weight",
310
- group.depthLevel === 0 ? "600" : "500",
311
- )
312
- groupLabel.setAttribute("stroke", group.color)
313
- groupLabel.setAttribute(
314
- "stroke-width",
315
- Math.max(0.2, fontSize * 0.02).toString(),
316
- )
317
- groupLabel.textContent = labelText
318
-
319
- svg.appendChild(groupOverlay)
320
- svg.appendChild(labelBg)
321
- svg.appendChild(groupLabel)
322
- })
323
- } catch (error) {
324
- console.error("Error creating group overlays:", error)
325
- }
326
- }, 10) // Small delay to ensure SVG is ready
327
-
328
- return () => clearTimeout(timeoutId)
329
- }, [svgDivRef, circuitJsonKey, showGroups])
330
- }
331
-
332
- function calculateGroupBounds(components: any[], svg: SVGElement) {
333
- let minX = Infinity,
334
- minY = Infinity,
335
- maxX = -Infinity,
336
- maxY = -Infinity
337
-
338
- for (const component of components) {
339
- let componentElement = svg.querySelector(
340
- `g[data-schematic-component-id="${component.schematic_component_id}"]`,
341
- )
342
-
343
- if (!componentElement) {
344
- componentElement = svg.querySelector(
345
- `[data-schematic-component-id="${component.schematic_component_id}"]`,
346
- )
347
- }
348
-
349
- if (componentElement) {
350
- const bbox = (componentElement as SVGGraphicsElement).getBBox()
351
- minX = Math.min(minX, bbox.x)
352
- minY = Math.min(minY, bbox.y)
353
- maxX = Math.max(maxX, bbox.x + bbox.width)
354
- maxY = Math.max(maxY, bbox.y + bbox.height)
355
- }
356
- }
357
-
358
- if (minX === Infinity) {
359
- return null
360
- }
361
-
362
- const bounds = { minX, minY, maxX, maxY }
363
- return bounds
364
- }
@@ -1,149 +0,0 @@
1
- import { useState, useEffect } from "react"
2
- import type * as EecircuitEngine from "../types/eecircuit-engine"
3
- // @ts-ignore
4
- import { getSpiceSimulationWorkerBlobUrl } from "../workers/spice-simulation.worker.blob.js"
5
-
6
- // Types from eecircuit-engine interface
7
- type RealDataType = {
8
- name: string
9
- type: string
10
- values: number[]
11
- }
12
- type ComplexNumber = {
13
- real: number
14
- img: number
15
- }
16
- type ComplexDataType = {
17
- name: string
18
- type: string
19
- values: ComplexNumber[]
20
- }
21
- type EecEngineResult =
22
- | {
23
- header: string
24
- numVariables: number
25
- variableNames: string[]
26
- numPoints: number
27
- dataType: "real"
28
- data: RealDataType[]
29
- }
30
- | {
31
- header: string
32
- numVariables: number
33
- variableNames: string[]
34
- numPoints: number
35
- dataType: "complex"
36
- data: ComplexDataType[]
37
- }
38
-
39
- export interface PlotPoint {
40
- name: string // time or sweep variable
41
- [key: string]: number | string
42
- }
43
-
44
- const parseEecEngineOutput = (
45
- result: EecEngineResult,
46
- ): { plotData: PlotPoint[]; nodes: string[] } => {
47
- const columnData: Record<string, number[]> = {}
48
-
49
- if (result.dataType === "real") {
50
- result.data.forEach((col) => {
51
- columnData[col.name] = col.values
52
- })
53
- } else if (result.dataType === "complex") {
54
- result.data.forEach((col) => {
55
- // For now, plot the real part of complex numbers
56
- columnData[col.name] = col.values.map((v) => v.real)
57
- })
58
- } else {
59
- throw new Error("Unsupported data type in simulation result")
60
- }
61
-
62
- const timeKey = Object.keys(columnData).find(
63
- (k) => k.toLowerCase() === "time" || k.toLowerCase() === "frequency",
64
- )
65
- if (!timeKey) {
66
- throw new Error("No time or frequency data in simulation result")
67
- }
68
- const timeValues = columnData[timeKey]
69
- const probedVariables = Object.keys(columnData).filter((k) => k !== timeKey)
70
- const plotableNodes = probedVariables
71
-
72
- const plotData: PlotPoint[] = timeValues.map((t: number, i: number) => {
73
- const point: PlotPoint = { name: t.toExponential(2) }
74
- probedVariables.forEach((variable) => {
75
- point[variable] = columnData[variable][i]
76
- })
77
- return point
78
- })
79
-
80
- return { plotData, nodes: plotableNodes }
81
- }
82
-
83
- type WorkerMessage =
84
- | {
85
- type: "result"
86
- result: EecEngineResult
87
- }
88
- | { type: "error"; error: string }
89
-
90
- export const useSpiceSimulation = (spiceString: string | null) => {
91
- const [plotData, setPlotData] = useState<PlotPoint[]>([])
92
- const [nodes, setNodes] = useState<string[]>([])
93
- const [isLoading, setIsLoading] = useState(true)
94
- const [error, setError] = useState<string | null>(null)
95
-
96
- useEffect(() => {
97
- if (!spiceString) {
98
- setIsLoading(false)
99
- setPlotData([])
100
- setNodes([])
101
- setError(null)
102
- return
103
- }
104
- setIsLoading(true)
105
- setError(null)
106
- setPlotData([])
107
- setNodes([])
108
-
109
- const workerUrl = getSpiceSimulationWorkerBlobUrl()
110
-
111
- if (!workerUrl) {
112
- setError("Could not create SPICE simulation worker.")
113
- setIsLoading(false)
114
- return
115
- }
116
-
117
- const worker = new Worker(workerUrl, { type: "module" })
118
-
119
- worker.onmessage = (event: MessageEvent<WorkerMessage>) => {
120
- if (event.data.type === "result") {
121
- try {
122
- const { plotData: parsedData, nodes: parsedNodes } =
123
- parseEecEngineOutput(event.data.result)
124
- setPlotData(parsedData)
125
- setNodes(parsedNodes)
126
- } catch (e: any) {
127
- setError(e.message || "Failed to parse simulation result")
128
- console.error(e)
129
- }
130
- } else if (event.data.type === "error") {
131
- setError(event.data.error)
132
- }
133
- setIsLoading(false)
134
- }
135
-
136
- worker.onerror = (err) => {
137
- setError(err.message)
138
- setIsLoading(false)
139
- }
140
-
141
- worker.postMessage({ spiceString })
142
-
143
- return () => {
144
- worker.terminate()
145
- }
146
- }, [spiceString])
147
-
148
- return { plotData, nodes, isLoading, error }
149
- }
package/lib/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export { SchematicViewer } from "./components/SchematicViewer"
2
- export { MouseTracker } from "./components/MouseTracker"
3
- export { useMouseEventsOverBoundingBox } from "./hooks/useMouseEventsOverBoundingBox"
4
- export { AnalogSimulationViewer } from "./components/AnalogSimulationViewer"
@@ -1,16 +0,0 @@
1
- import type {
2
- BaseManualEditEvent,
3
- EditSchematicComponentLocationEvent,
4
- ManualEditEvent,
5
- } from "@tscircuit/props"
6
-
7
- export type EditSchematicComponentLocationEventWithElement =
8
- EditSchematicComponentLocationEvent & {
9
- _element: SVGElement
10
- }
11
-
12
- export type {
13
- BaseManualEditEvent,
14
- EditSchematicComponentLocationEvent,
15
- ManualEditEvent,
16
- }