brick-break 1.1.0 → 1.3.0

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/README.md CHANGED
@@ -54,12 +54,44 @@ bb go build
54
54
 
55
55
  if it can fail, brick-break can make it funnier.
56
56
 
57
+ ## next.js hmr support
58
+
59
+ for errors that happen while the dev server is running (hot reload):
60
+
61
+ ```bash
62
+ bb init
63
+ ```
64
+
65
+ this automatically adds `<BrickBreak />` to your layout.tsx.
66
+
67
+ or add it manually:
68
+
69
+ ```tsx
70
+ // app/layout.tsx
71
+ import { BrickBreak } from 'brick-break/next'
72
+
73
+ export default function RootLayout({ children }) {
74
+ return (
75
+ <html>
76
+ <body>
77
+ <BrickBreak />
78
+ {children}
79
+ </body>
80
+ </html>
81
+ )
82
+ }
83
+ ```
84
+
85
+ now errors play the sound even during hot reload.
86
+
57
87
  ## how it works
58
88
 
59
89
  1. runs your command
60
90
  2. build fails? plays the sound
61
91
  3. thats it
62
92
 
93
+ (for next.js hmr: watches for the error overlay in the browser)
94
+
63
95
  ## requirements
64
96
 
65
97
  uses your system audio player (already installed):
package/dist/cli.js CHANGED
@@ -2,10 +2,57 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const index_1 = require("./index");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
5
7
  const args = process.argv.slice(2);
6
8
  if (!args.length) {
7
9
  console.log('usage: bb <command>');
10
+ console.log(' bb init - setup next.js hmr support');
8
11
  console.log('example: bb npm run build');
9
12
  process.exit(1);
10
13
  }
14
+ // handle init command
15
+ if (args[0] === 'init') {
16
+ const layoutPaths = [
17
+ (0, path_1.join)(process.cwd(), 'app/layout.tsx'),
18
+ (0, path_1.join)(process.cwd(), 'src/app/layout.tsx'),
19
+ (0, path_1.join)(process.cwd(), 'app/layout.jsx'),
20
+ (0, path_1.join)(process.cwd(), 'src/app/layout.jsx'),
21
+ ];
22
+ const layoutPath = layoutPaths.find(p => (0, fs_1.existsSync)(p));
23
+ if (!layoutPath) {
24
+ console.log('\x1b[31merror: no layout.tsx found\x1b[0m');
25
+ console.log('make sure you are in a next.js project root');
26
+ process.exit(1);
27
+ }
28
+ let content = (0, fs_1.readFileSync)(layoutPath, 'utf-8');
29
+ if (content.includes('brick-break')) {
30
+ console.log('\x1b[33mbrick-break already installed in layout\x1b[0m');
31
+ process.exit(0);
32
+ }
33
+ // add import at the top (after other imports or 'use client')
34
+ const importLine = "import { BrickBreak } from 'brick-break/next'\n";
35
+ if (content.includes("'use client'") || content.includes('"use client"')) {
36
+ content = content.replace(/(["']use client["'][\s\n]*)/, `$1${importLine}`);
37
+ }
38
+ else if (content.includes('import ')) {
39
+ content = content.replace(/(import .+\n)/, `${importLine}$1`);
40
+ }
41
+ else {
42
+ content = importLine + content;
43
+ }
44
+ // add <BrickBreak /> after <body> or <body ...>
45
+ content = content.replace(/(<body[^>]*>)(\s*)/, '$1$2<BrickBreak />\n ');
46
+ (0, fs_1.writeFileSync)(layoutPath, content);
47
+ console.log('\x1b[32m✓ added BrickBreak to ' + layoutPath + '\x1b[0m');
48
+ console.log('hmr errors will now play the sound');
49
+ process.exit(0);
50
+ }
51
+ // detect next.js dev mode
52
+ const isNextDev = args.some(a => a.includes('next')) && args.some(a => a === 'dev');
53
+ if (isNextDev) {
54
+ console.log('\x1b[36m');
55
+ console.log('brick-break: for hmr error sounds, run: bb init');
56
+ console.log('\x1b[0m');
57
+ }
11
58
  (0, index_1.runCommand)(args);
package/dist/next.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function BrickBreak({ children }: {
3
+ children?: ReactNode;
4
+ }): import("react/jsx-runtime").JSX.Element;
package/dist/next.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BrickBreak = BrickBreak;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ let lastPlayed = 0;
8
+ const cooldown = 3000;
9
+ function playSound() {
10
+ const now = Date.now();
11
+ if (now - lastPlayed < cooldown)
12
+ return;
13
+ lastPlayed = now;
14
+ const audio = new Audio('https://unpkg.com/brick-break/sound.mp3');
15
+ audio.play().catch(() => { });
16
+ }
17
+ function BrickBreak({ children }) {
18
+ const seenErrors = (0, react_1.useRef)(new Set());
19
+ (0, react_1.useEffect)(() => {
20
+ if (process.env.NODE_ENV !== 'development')
21
+ return;
22
+ const observer = new MutationObserver(() => {
23
+ // nextjs error overlay
24
+ const dialog = document.querySelector('[data-nextjs-dialog]');
25
+ if (dialog) {
26
+ const errorText = dialog.textContent || '';
27
+ if (!seenErrors.current.has(errorText)) {
28
+ seenErrors.current.add(errorText);
29
+ playSound();
30
+ }
31
+ }
32
+ });
33
+ observer.observe(document.body, { childList: true, subtree: true });
34
+ return () => observer.disconnect();
35
+ }, []);
36
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
37
+ }
package/package.json CHANGED
@@ -1,9 +1,19 @@
1
1
  {
2
2
  "name": "brick-break",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Play a Lego break sound when your build fails",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./next": {
13
+ "types": "./dist/next.d.ts",
14
+ "default": "./dist/next.js"
15
+ }
16
+ },
7
17
  "bin": {
8
18
  "brick-break": "dist/cli.js",
9
19
  "bb": "dist/cli.js"
@@ -23,7 +33,8 @@
23
33
  "error",
24
34
  "fun",
25
35
  "developer-experience",
26
- "nextjs"
36
+ "nextjs",
37
+ "react"
27
38
  ],
28
39
  "author": "ShinniUwU",
29
40
  "license": "MIT",
@@ -35,8 +46,17 @@
35
46
  "bugs": {
36
47
  "url": "https://github.com/ShinniUwU/brick-break/issues"
37
48
  },
49
+ "peerDependencies": {
50
+ "react": ">=18.0.0"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "react": {
54
+ "optional": true
55
+ }
56
+ },
38
57
  "devDependencies": {
39
58
  "@types/node": "^20.0.0",
59
+ "@types/react": "^18.0.0",
40
60
  "typescript": "^5.0.0"
41
61
  }
42
62
  }