Skip to content

Commit cde6085

Browse files
bfirshclaude
andcommitted
Consolidate prettier configuration across core and web
Move prettier from web's devDependencies to root-only, with a single shared configuration covering both core and web code. Expand root's prettier check to cover all JS/JSX/CSS files (test files, config files, and web code were previously unchecked). Create .prettierignore to prevent checking node_modules and dist. Widen glob patterns to **/*.{js,jsx,css} and simplify CLAUDE.md to document one format command instead of separate workflows. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 7468b30 commit cde6085

File tree

9 files changed

+3809
-3796
lines changed

9 files changed

+3809
-3796
lines changed

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist

CLAUDE.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
- `npm test` - Run code formatting check and tests (required before commits)
88
- `npm run build` - Build distribution files (`dist/jsnes.js` and `dist/jsnes.min.js`)
9-
- `npm run format` - Auto-format all source code with Prettier
10-
- `cd web && npx prettier --write src/` - Format web UI code (web has its own Prettier config; `npm run format` only covers `src/`)
9+
- `npm run format` - Auto-format all code (core and web) with Prettier
1110
- `npm run test:watch` - Run tests in watch mode for development
1211
- `npm run typecheck` - TypeScript type checking (verifies `.d.ts` files)
1312
- `node bench.js` - Run performance benchmark (~1800 fps baseline). Run this on major changes or when you suspect a performance regression/improvement.

bench.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ for (const [name, romPath] of Object.entries(ROMS)) {
6464
}
6565

6666
if (results.length > 1) {
67-
const avgFps =
68-
results.reduce((sum, r) => sum + r.fps, 0) / results.length;
67+
const avgFps = results.reduce((sum, r) => sum + r.fps, 0) / results.length;
6968
const avgMs =
7069
results.reduce((sum, r) => sum + r.msPerFrame, 0) / results.length;
7170
console.log(

example/nes-embed.js

Lines changed: 133 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,169 @@
11
const SCREEN_WIDTH = 256;
22
const SCREEN_HEIGHT = 240;
3-
const FRAMEBUFFER_SIZE = SCREEN_WIDTH*SCREEN_HEIGHT;
3+
const FRAMEBUFFER_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT;
44

55
let canvas_ctx, image;
66
let framebuffer_u8, framebuffer_u32;
77

88
const AUDIO_BUFFERING = 512;
9-
const SAMPLE_COUNT = 4*1024;
9+
const SAMPLE_COUNT = 4 * 1024;
1010
const SAMPLE_MASK = SAMPLE_COUNT - 1;
1111
let audio_samples_L = new Float32Array(SAMPLE_COUNT);
1212
let audio_samples_R = new Float32Array(SAMPLE_COUNT);
13-
let audio_write_cursor = 0, audio_read_cursor = 0;
13+
let audio_write_cursor = 0,
14+
audio_read_cursor = 0;
1415
let audio_started = false;
1516

1617
let nes = new jsnes.NES({
17-
onFrame: function(framebuffer_24){
18-
for(let i = 0; i < FRAMEBUFFER_SIZE; i++) framebuffer_u32[i] = 0xFF000000 | framebuffer_24[i];
19-
},
20-
onAudioSample: function(l, r){
21-
audio_samples_L[audio_write_cursor] = l;
22-
audio_samples_R[audio_write_cursor] = r;
23-
audio_write_cursor = (audio_write_cursor + 1) & SAMPLE_MASK;
24-
},
18+
onFrame: function (framebuffer_24) {
19+
for (let i = 0; i < FRAMEBUFFER_SIZE; i++)
20+
framebuffer_u32[i] = 0xff000000 | framebuffer_24[i];
21+
},
22+
onAudioSample: function (l, r) {
23+
audio_samples_L[audio_write_cursor] = l;
24+
audio_samples_R[audio_write_cursor] = r;
25+
audio_write_cursor = (audio_write_cursor + 1) & SAMPLE_MASK;
26+
},
2527
});
2628

27-
function onAnimationFrame(){
28-
window.requestAnimationFrame(onAnimationFrame);
29-
if (!audio_started) {
30-
nes.frame();
31-
}
29+
function onAnimationFrame() {
30+
window.requestAnimationFrame(onAnimationFrame);
31+
if (!audio_started) {
32+
nes.frame();
33+
}
3234

33-
image.data.set(framebuffer_u8);
34-
canvas_ctx.putImageData(image, 0, 0);
35+
image.data.set(framebuffer_u8);
36+
canvas_ctx.putImageData(image, 0, 0);
3537
}
3638

37-
function audio_remain(){
38-
return (audio_write_cursor - audio_read_cursor) & SAMPLE_MASK;
39+
function audio_remain() {
40+
return (audio_write_cursor - audio_read_cursor) & SAMPLE_MASK;
3941
}
4042

41-
function audio_callback(event){
42-
let dst = event.outputBuffer;
43-
let len = dst.length;
44-
45-
// Attempt to avoid buffer underruns.
46-
if(audio_remain() < AUDIO_BUFFERING) nes.frame();
47-
48-
let dst_l = dst.getChannelData(0);
49-
let dst_r = dst.getChannelData(1);
50-
for(let i = 0; i < len; i++){
51-
let src_idx = (audio_read_cursor + i) & SAMPLE_MASK;
52-
dst_l[i] = audio_samples_L[src_idx];
53-
dst_r[i] = audio_samples_R[src_idx];
54-
}
55-
56-
audio_read_cursor = (audio_read_cursor + len) & SAMPLE_MASK;
43+
function audio_callback(event) {
44+
let dst = event.outputBuffer;
45+
let len = dst.length;
46+
47+
// Attempt to avoid buffer underruns.
48+
if (audio_remain() < AUDIO_BUFFERING) nes.frame();
49+
50+
let dst_l = dst.getChannelData(0);
51+
let dst_r = dst.getChannelData(1);
52+
for (let i = 0; i < len; i++) {
53+
let src_idx = (audio_read_cursor + i) & SAMPLE_MASK;
54+
dst_l[i] = audio_samples_L[src_idx];
55+
dst_r[i] = audio_samples_R[src_idx];
56+
}
57+
58+
audio_read_cursor = (audio_read_cursor + len) & SAMPLE_MASK;
5759
}
5860

59-
function keyboard(callback, event){
60-
event.preventDefault();
61-
let player = 1;
62-
switch(event.keyCode){
63-
case 38: // UP
64-
callback(player, jsnes.Controller.BUTTON_UP); break;
65-
case 40: // Down
66-
callback(player, jsnes.Controller.BUTTON_DOWN); break;
67-
case 37: // Left
68-
callback(player, jsnes.Controller.BUTTON_LEFT); break;
69-
case 39: // Right
70-
callback(player, jsnes.Controller.BUTTON_RIGHT); break;
71-
case 65: // 'a' - qwerty, dvorak
72-
case 81: // 'q' - azerty
73-
callback(player, jsnes.Controller.BUTTON_A); break;
74-
case 83: // 's' - qwerty, azerty
75-
case 79: // 'o' - dvorak
76-
callback(player, jsnes.Controller.BUTTON_B); break;
77-
case 9: // Tab
78-
callback(player, jsnes.Controller.BUTTON_SELECT); break;
79-
case 13: // Return
80-
callback(player, jsnes.Controller.BUTTON_START); break;
81-
default: break;
82-
}
61+
function keyboard(callback, event) {
62+
event.preventDefault();
63+
let player = 1;
64+
switch (event.keyCode) {
65+
case 38: // UP
66+
callback(player, jsnes.Controller.BUTTON_UP);
67+
break;
68+
case 40: // Down
69+
callback(player, jsnes.Controller.BUTTON_DOWN);
70+
break;
71+
case 37: // Left
72+
callback(player, jsnes.Controller.BUTTON_LEFT);
73+
break;
74+
case 39: // Right
75+
callback(player, jsnes.Controller.BUTTON_RIGHT);
76+
break;
77+
case 65: // 'a' - qwerty, dvorak
78+
case 81: // 'q' - azerty
79+
callback(player, jsnes.Controller.BUTTON_A);
80+
break;
81+
case 83: // 's' - qwerty, azerty
82+
case 79: // 'o' - dvorak
83+
callback(player, jsnes.Controller.BUTTON_B);
84+
break;
85+
case 9: // Tab
86+
callback(player, jsnes.Controller.BUTTON_SELECT);
87+
break;
88+
case 13: // Return
89+
callback(player, jsnes.Controller.BUTTON_START);
90+
break;
91+
default:
92+
break;
93+
}
8394
}
8495

8596
let audio_ctx;
86-
function nes_init(canvas_id){
87-
let canvas = document.getElementById(canvas_id);
88-
canvas_ctx = canvas.getContext("2d");
89-
image = canvas_ctx.getImageData(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
90-
91-
canvas_ctx.fillStyle = "black";
92-
canvas_ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
93-
94-
// Allocate framebuffer array.
95-
let buffer = new ArrayBuffer(image.data.length);
96-
framebuffer_u8 = new Uint8ClampedArray(buffer);
97-
framebuffer_u32 = new Uint32Array(buffer);
98-
99-
// Setup audio.
100-
audio_ctx = new window.AudioContext();
101-
let script_processor = audio_ctx.createScriptProcessor(AUDIO_BUFFERING, 0, 2);
102-
script_processor.onaudioprocess = audio_callback;
103-
script_processor.connect(audio_ctx.destination);
104-
if (audio_ctx.state === 'suspended') {
105-
let audioButton = document.getElementById('audio');
106-
audioButton.style.display = 'block';
107-
} else {
108-
audio_started = true;
109-
}
97+
function nes_init(canvas_id) {
98+
let canvas = document.getElementById(canvas_id);
99+
canvas_ctx = canvas.getContext("2d");
100+
image = canvas_ctx.getImageData(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
101+
102+
canvas_ctx.fillStyle = "black";
103+
canvas_ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
104+
105+
// Allocate framebuffer array.
106+
let buffer = new ArrayBuffer(image.data.length);
107+
framebuffer_u8 = new Uint8ClampedArray(buffer);
108+
framebuffer_u32 = new Uint32Array(buffer);
109+
110+
// Setup audio.
111+
audio_ctx = new window.AudioContext();
112+
let script_processor = audio_ctx.createScriptProcessor(AUDIO_BUFFERING, 0, 2);
113+
script_processor.onaudioprocess = audio_callback;
114+
script_processor.connect(audio_ctx.destination);
115+
if (audio_ctx.state === "suspended") {
116+
let audioButton = document.getElementById("audio");
117+
audioButton.style.display = "block";
118+
} else {
119+
audio_started = true;
120+
}
110121
}
111122

112-
function nes_boot(rom_data){
113-
nes.loadROM(rom_data);
114-
window.requestAnimationFrame(onAnimationFrame);
123+
function nes_boot(rom_data) {
124+
nes.loadROM(rom_data);
125+
window.requestAnimationFrame(onAnimationFrame);
115126
}
116127

117-
function nes_load_data(canvas_id, rom_data){
118-
nes_init(canvas_id);
119-
nes_boot(rom_data);
128+
function nes_load_data(canvas_id, rom_data) {
129+
nes_init(canvas_id);
130+
nes_boot(rom_data);
120131
}
121132

122-
function nes_load_url(canvas_id, path){
123-
nes_init(canvas_id);
124-
125-
let req = new XMLHttpRequest();
126-
req.open("GET", path);
127-
req.overrideMimeType("text/plain; charset=x-user-defined");
128-
req.onerror = () => console.log(`Error loading ${path}: ${req.statusText}`);
129-
130-
req.onload = function() {
131-
if (this.status === 200) {
132-
nes_boot(this.responseText);
133-
} else if (this.status === 0) {
134-
// Aborted, so ignore error
135-
} else {
136-
req.onerror();
137-
}
138-
};
139-
140-
req.send();
133+
function nes_load_url(canvas_id, path) {
134+
nes_init(canvas_id);
135+
136+
let req = new XMLHttpRequest();
137+
req.open("GET", path);
138+
req.overrideMimeType("text/plain; charset=x-user-defined");
139+
req.onerror = () => console.log(`Error loading ${path}: ${req.statusText}`);
140+
141+
req.onload = function () {
142+
if (this.status === 200) {
143+
nes_boot(this.responseText);
144+
} else if (this.status === 0) {
145+
// Aborted, so ignore error
146+
} else {
147+
req.onerror();
148+
}
149+
};
150+
151+
req.send();
141152
}
142153

143-
document.addEventListener('keydown', (event) => {keyboard(nes.buttonDown, event)});
144-
document.addEventListener('keyup', (event) => {keyboard(nes.buttonUp, event)});
154+
document.addEventListener("keydown", (event) => {
155+
keyboard(nes.buttonDown, event);
156+
});
157+
document.addEventListener("keyup", (event) => {
158+
keyboard(nes.buttonUp, event);
159+
});
145160

146-
document.addEventListener('DOMContentLoaded', (event) => {
147-
let audioButton = document.getElementById('audio');
148-
audioButton.addEventListener('click', () => {
149-
audio_ctx.resume().then(() => {
150-
audio_started = true;
151-
});
152-
audioButton.style.display = 'none';
161+
document.addEventListener("DOMContentLoaded", (event) => {
162+
let audioButton = document.getElementById("audio");
163+
audioButton.addEventListener("click", () => {
164+
audio_ctx.resume().then(() => {
165+
audio_started = true;
153166
});
167+
audioButton.style.display = "none";
168+
});
154169
});

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
"scripts": {
1515
"build": "webpack",
1616
"typecheck": "tsc --noEmit",
17-
"test": "npm run typecheck && prettier --check src/**/*.js && node --test ./test/*.spec.js",
17+
"test": "npm run typecheck && prettier --check '**/*.{js,jsx,css}' && node --test ./test/*.spec.js",
1818
"test:watch": "node --test --watch ./test/*.spec.js",
1919
"prepublish": "npm run build",
20-
"format": "prettier --write src/**/*.js"
20+
"format": "prettier --write '**/*.{js,jsx,css}'"
2121
},
2222
"devDependencies": {
2323
"@types/node": "^25.0.2",

0 commit comments

Comments
 (0)