Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
258 changes: 53 additions & 205 deletions src/simulator/src/app.js
Original file line number Diff line number Diff line change
@@ -1,210 +1,58 @@
import { setup } from './setup'
import { setup } from './setup';
import Array from './arrayHelpers';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Overriding the native Array constructor on window is risky and should be avoided

Importing Array from ./arrayHelpers (Line 2) and then doing window.Array = Array; (Line 57) replaces the built‑in window.Array with your custom implementation. This:

  • Conflicts with Biome’s noShadowRestrictedNames warning.
  • Can subtly break any code (including libraries) that relies on native Array semantics, instanceof Array, Array.isArray, or static methods added by the JS engine.

A safer pattern is to avoid shadowing the global and expose the helper under a distinct name:

-import Array from './arrayHelpers';
+import ArrayHelpers from './arrayHelpers';
@@
-    // Make array helpers globally available
-    window.Array = Array;
+    // Make array helpers globally available without overriding native Array
+    window.ArrayHelpers = ArrayHelpers;

If existing simulator code expects a global helper, align on a non‑conflicting name (window.SimulatorArray, window.ArrayHelpers, etc.) rather than reusing Array.

Also applies to: 56-57

🧰 Tools
🪛 Biome (2.1.2)

[error] 2-2: Do not shadow the global "Array" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🤖 Prompt for AI Agents
In src/simulator/src/app.js around lines 2 and 56-57, the file imports a module
as "Array" and assigns it to window.Array which overrides the native global
Array; change the import or the global export so you do NOT shadow the built-in
(for example import as ArrayHelpers or SimulatorArray and assign
window.SimulatorArray = ArrayHelpers), then update any local references that
expect the helper to use the new name (or update code that relied on
window.Array to use window.SimulatorArray/ArrayHelpers) and remove the
assignment to window.Array to avoid breaking native Array semantics.

import { initSentry } from './sentry';

// Initialize Sentry first
initSentry();

document.addEventListener('DOMContentLoaded', () => {
setup()
var js = {
devices: {
dev0: {
type: 'Input',
net: 'clk',
order: 0,
bits: 1,
},
dev1: {
type: 'Input',
net: 'addr',
order: 1,
bits: 4,
},
dev2: {
type: 'Output',
net: 'data',
order: 2,
bits: 5,
},
dev3: {
type: 'Input',
net: 'addr2',
order: 3,
bits: 4,
},
dev4: {
type: 'Output',
net: 'data2',
order: 4,
bits: 5,
},
dev5: {
type: 'Input',
net: 'wraddr',
order: 5,
bits: 4,
},
dev6: {
type: 'Input',
net: 'wrdata',
order: 6,
bits: 5,
},
dev7: {
type: 'Input',
net: 'wraddr2',
order: 7,
bits: 4,
},
dev8: {
type: 'Input',
net: 'wrdata2',
order: 8,
bits: 5,
},
dev9: {
label: 'mem',
type: 'Memory',
bits: 5,
abits: 4,
words: 16,
offset: 0,
rdports: [
{},
{
clock_polarity: true,
},
],
wrports: [
{
clock_polarity: true,
},
{
clock_polarity: true,
},
setup();

// Demo simulation JSON
const js = {
"devices": {
"dev0": { "type": "Input", "net": "clk", "order": 0, "bits": 1 },
"dev1": { "type": "Input", "net": "addr", "order": 1, "bits": 4 },
"dev2": { "type": "Output", "net": "data", "order": 2, "bits": 5 },
"dev3": { "type": "Input", "net": "addr2", "order": 3, "bits": 4 },
"dev4": { "type": "Output", "net": "data2", "order": 4, "bits": 5 },
"dev5": { "type": "Input", "net": "wraddr", "order": 5, "bits": 4 },
"dev6": { "type": "Input", "net": "wrdata", "order": 6, "bits": 5 },
"dev7": { "type": "Input", "net": "wraddr2", "order": 7, "bits": 4 },
"dev8": { "type": "Input", "net": "wrdata2", "order": 8, "bits": 5 },
"dev9": {
"label": "mem",
"type": "Memory",
"bits": 5,
"abits": 4,
"words": 16,
"offset": 0,
"rdports": [{}, { "clock_polarity": true }],
"wrports": [
{ "clock_polarity": true },
{ "clock_polarity": true }
],
memdata: [13, '00001', 3, '11111'],
},
"memdata": [13, "00001", 3, "11111"]
}
},
connectors: [
{
to: {
id: 'dev9',
port: 'rd1clk',
},
from: {
id: 'dev0',
port: 'out',
},
name: 'clk',
},
{
to: {
id: 'dev9',
port: 'wr0clk',
},
from: {
id: 'dev0',
port: 'out',
},
name: 'clk',
},
{
to: {
id: 'dev9',
port: 'wr1clk',
},
from: {
id: 'dev0',
port: 'out',
},
name: 'clk',
},
{
to: {
id: 'dev9',
port: 'rd0addr',
},
from: {
id: 'dev1',
port: 'out',
},
name: 'addr',
},
{
to: {
id: 'dev2',
port: 'in',
},
from: {
id: 'dev9',
port: 'rd0data',
},
name: 'data',
},
{
to: {
id: 'dev9',
port: 'rd1addr',
},
from: {
id: 'dev3',
port: 'out',
},
name: 'addr2',
},
{
to: {
id: 'dev4',
port: 'in',
},
from: {
id: 'dev9',
port: 'rd1data',
},
name: 'data2',
},
{
to: {
id: 'dev9',
port: 'wr0addr',
},
from: {
id: 'dev5',
port: 'out',
},
name: 'wraddr',
},
{
to: {
id: 'dev9',
port: 'wr0data',
},
from: {
id: 'dev6',
port: 'out',
},
name: 'wrdata',
},
{
to: {
id: 'dev9',
port: 'wr1addr',
},
from: {
id: 'dev7',
port: 'out',
},
name: 'wraddr2',
},
{
to: {
id: 'dev9',
port: 'wr1data',
},
from: {
id: 'dev8',
port: 'out',
},
name: 'wrdata2',
},

"connectors": [
{ "to": { "id": "dev9", "port": "rd1clk" }, "from": { "id": "dev0", "port": "out" }, "name": "clk" },
{ "to": { "id": "dev9", "port": "wr0clk" }, "from": { "id": "dev0", "port": "out" }, "name": "clk" },
{ "to": { "id": "dev9", "port": "wr1clk" }, "from": { "id": "dev0", "port": "out" }, "name": "clk" },
{ "to": { "id": "dev9", "port": "rd0addr" }, "from": { "id": "dev1", "port": "out" }, "name": "addr" },
{ "to": { "id": "dev2", "port": "in" }, "from": { "id": "dev9", "port": "rd0data" }, "name": "data" },
{ "to": { "id": "dev9", "port": "rd1addr" }, "from": { "id": "dev3", "port": "out" }, "name": "addr2" },
{ "to": { "id": "dev4", "port": "in" }, "from": { "id": "dev9", "port": "rd1data" }, "name": "data2" },
{ "to": { "id": "dev9", "port": "wr0addr" }, "from": { "id": "dev5", "port": "out" }, "name": "wraddr" },
{ "to": { "id": "dev9", "port": "wr0data" }, "from": { "id": "dev6", "port": "out" }, "name": "wrdata" },
{ "to": { "id": "dev9", "port": "wr1addr" }, "from": { "id": "dev7", "port": "out" }, "name": "wraddr2" },
{ "to": { "id": "dev9", "port": "wr1data" }, "from": { "id": "dev8", "port": "out" }, "name": "wrdata2" }
],
subcircuits: {},
}
})

"subcircuits": {}
};

// Make array helpers globally available
window.Array = Array;
});
39 changes: 39 additions & 0 deletions src/simulator/src/sentry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as Sentry from "@sentry/browser";
import { BrowserTracing } from "@sentry/tracing";

export function initSentry() {
const isLocalDev =
window.location.hostname === "localhost" ||
window.location.hostname === "127.0.0.1";

Sentry.init({
dsn: "https://5f707d900ca6bd2a13fbe838135c0742@o4510363436187648.ingest.us.sentry.io/4510363491237888",

integrations: [
new BrowserTracing({
tracingOrigins: ["localhost", /^\//],
}),
],

environment: isLocalDev ? "development" : "production",

tracesSampleRate: 1.0,

beforeSend(event, hint) {
// Prevent sending events while developing
if (isLocalDev) {
console.log("⚠️ Sentry blocked (development mode):", event);
return null;
}
return event;
},

initialScope: {
tags: {
application: "circuitverse-simulator",
},
},
});

console.log("✅ Sentry initialized");
}