@tscircuit/ngspice-spice-engine 0.0.10 → 0.0.12

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
@@ -1,5 +1,5 @@
1
1
  import { SpiceEngine } from '@tscircuit/props';
2
- import { ResultType } from 'eecircuit-engine';
2
+ import { ResultType } from '@tscircuit/eecircuit-engine';
3
3
 
4
4
  interface TranParams {
5
5
  tstep?: number;
@@ -15,10 +15,7 @@ interface VoltageGraph {
15
15
  time: number[];
16
16
  voltage: number[];
17
17
  }
18
- interface NgspiceSpiceEngineOptions {
19
- pspiceCompatibility?: boolean;
20
- }
21
18
  declare const eecircuitResultToVGraphs: (result: ResultType, spiceString: string) => VoltageGraph[];
22
- declare const createNgspiceSpiceEngine: (options?: NgspiceSpiceEngineOptions) => Promise<SpiceEngine>;
19
+ declare const createNgspiceSpiceEngine: () => Promise<SpiceEngine>;
23
20
 
24
- export { type NgspiceSpiceEngineOptions, type TranParams, createNgspiceSpiceEngine, createNgspiceSpiceEngine as default, eecircuitResultToVGraphs, parseTranParams };
21
+ export { type TranParams, createNgspiceSpiceEngine, createNgspiceSpiceEngine as default, eecircuitResultToVGraphs, parseTranParams };
package/dist/index.js CHANGED
@@ -110,8 +110,8 @@ var parseTranParams = (spiceString) => {
110
110
 
111
111
  // lib/index.ts
112
112
  var ensureSimulation = async () => {
113
- const { Simulation: SimulationCtor } = await import("eecircuit-engine");
114
- const instance = new SimulationCtor();
113
+ const { Simulation: SimulationCtor } = await import("@tscircuit/eecircuit-engine");
114
+ const instance = new SimulationCtor({ ngBehavior: "psa" });
115
115
  await instance.start();
116
116
  return instance;
117
117
  };
@@ -127,7 +127,7 @@ var getSimulation = async () => {
127
127
  };
128
128
  var extractRequestedPlots = (spiceString) => {
129
129
  const match = spiceString.match(/\.print\s+tran\s+(.*)/i);
130
- if (!match?.[1]) {
130
+ if (!match || !match[1]) {
131
131
  return null;
132
132
  }
133
133
  const tokens = match[1].match(/[VI]\s*\([^)]+\)/gi);
@@ -155,7 +155,7 @@ var getNetName = (rawName) => {
155
155
  return match[1] ?? rawName;
156
156
  };
157
157
  var eecircuitResultToVGraphs = (result, spiceString) => {
158
- if (!result?.data || result.dataType !== "real") {
158
+ if (!result || !result.data || result.dataType !== "real") {
159
159
  return [];
160
160
  }
161
161
  const timeData = result.data.find((item) => item.type === "time");
@@ -240,100 +240,9 @@ var voltageGraphsToCircuitJson = (graphs, spiceString) => {
240
240
  end_time_ms: (tranParams?.tstop ?? 0) * 1e3
241
241
  }));
242
242
  };
243
- var splitFunctionArguments = (input) => {
244
- const args = [];
245
- let startIndex = 0;
246
- let parenDepth = 0;
247
- let braceDepth = 0;
248
- for (let index = 0; index < input.length; index++) {
249
- const char = input[index];
250
- if (char === "(") parenDepth++;
251
- else if (char === ")") parenDepth--;
252
- else if (char === "{") braceDepth++;
253
- else if (char === "}") braceDepth--;
254
- else if (char === "," && parenDepth === 0 && braceDepth === 0) {
255
- args.push(input.slice(startIndex, index));
256
- startIndex = index + 1;
257
- }
258
- }
259
- args.push(input.slice(startIndex));
260
- return args;
261
- };
262
- var convertPspiceIfFunctions = (input) => {
263
- let output = "";
264
- let index = 0;
265
- while (index < input.length) {
266
- const ifMatch = input.slice(index).match(/^if\s*\(/i);
267
- if (!ifMatch) {
268
- output += input[index];
269
- index++;
270
- continue;
271
- }
272
- const openParenIndex = index + ifMatch[0].length - 1;
273
- let depth = 0;
274
- let closeParenIndex = -1;
275
- for (let scanIndex = openParenIndex; scanIndex < input.length; scanIndex++) {
276
- const char = input[scanIndex];
277
- if (char === "(") depth++;
278
- else if (char === ")") {
279
- depth--;
280
- if (depth === 0) {
281
- closeParenIndex = scanIndex;
282
- break;
283
- }
284
- }
285
- }
286
- if (closeParenIndex === -1) {
287
- output += input.slice(index);
288
- break;
289
- }
290
- const innerExpression = convertPspiceIfFunctions(
291
- input.slice(openParenIndex + 1, closeParenIndex)
292
- );
293
- const args = splitFunctionArguments(innerExpression);
294
- if (args.length !== 3) {
295
- output += input.slice(index, closeParenIndex + 1);
296
- } else {
297
- output += `((${args[0].trim()}) ? (${args[1].trim()}) : (${args[2].trim()}))`;
298
- }
299
- index = closeParenIndex + 1;
300
- }
301
- return output;
302
- };
303
- var preprocessPspiceForEmbeddedNgspice = (spiceString) => {
304
- let processed = spiceString.replace(/\bif\s*\r?\n\+\s*\(/gi, "if(").replace(/\.MODEL(\s+\S+\s+)VSWITCH\b/gi, ".MODEL$1SW").replace(/\b(VON|VOFF)\s*=\s*[^\s)]+/gi, "").replace(
305
- /\b(RON|ROFF)\s*=\s*([^\s)]+)/gi,
306
- (_match, key, value) => `${key}=${value.replace(/V$/i, "")}`
307
- ).replace(/\bTC\s*=\s*([^\s,]+)\s*,\s*([^\s)]+)/gi, "TC1=$1 TC2=$2");
308
- processed = convertPspiceIfFunctions(processed);
309
- return processed.replace(/\s&\s/g, " && ").replace(/\s\|\s/g, " || ").replace(/\s\^\s/g, " != ");
310
- };
311
- var configureNgBehavior = (simulation, pspiceCompatibility) => {
312
- const simulationWithCommandList = simulation;
313
- const commandList = simulationWithCommandList.commandList;
314
- if (!Array.isArray(commandList)) {
315
- if (pspiceCompatibility) {
316
- throw new Error(
317
- "Unable to enable PSPICE compatibility: eecircuit-engine commandList is not accessible"
318
- );
319
- }
320
- return;
321
- }
322
- const ngBehaviorCommand = pspiceCompatibility ? "set ngbehavior=psa" : "unset ngbehavior";
323
- const sourceCommandIndex = commandList.findIndex(
324
- (command) => /^\s*source\s+test\.cir\s*$/i.test(command)
325
- );
326
- if (sourceCommandIndex === -1) {
327
- commandList.unshift(ngBehaviorCommand);
328
- return;
329
- }
330
- commandList.splice(sourceCommandIndex, 0, ngBehaviorCommand);
331
- };
332
- var simulate = async (spiceString, options) => {
333
- const simulationSpiceString = options.pspiceCompatibility ? preprocessPspiceForEmbeddedNgspice(spiceString) : spiceString;
243
+ var simulate = async (spiceString) => {
334
244
  const simulation = await getSimulation();
335
- simulation.setNetList(simulationSpiceString);
336
- configureNgBehavior(simulation, false);
245
+ simulation.setNetList(spiceString);
337
246
  let result;
338
247
  try {
339
248
  result = await simulation.runSim();
@@ -352,12 +261,9 @@ var simulate = async (spiceString, options) => {
352
261
  )
353
262
  };
354
263
  };
355
- var createNgspiceSpiceEngine = async (options = {}) => {
356
- const resolvedOptions = {
357
- pspiceCompatibility: options.pspiceCompatibility ?? false
358
- };
264
+ var createNgspiceSpiceEngine = async () => {
359
265
  return {
360
- simulate: (spiceString) => simulate(spiceString, resolvedOptions)
266
+ simulate: (spiceString) => simulate(spiceString)
361
267
  };
362
268
  };
363
269
  var index_default = createNgspiceSpiceEngine;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/ngspice-spice-engine",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "A tscircuit-compatible SPICE engine using ngspice.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "typecheck": "tsc --noEmit"
18
18
  },
19
19
  "dependencies": {
20
- "eecircuit-engine": "^1.7.0"
20
+ "@tscircuit/eecircuit-engine": "https://jscdn.tscircuit.com/@tscircuit/eecircuit-engine/1.7.2.tgz"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@tscircuit/props": "^0.0.374",