@ui-inspect/rspack-plugin 0.1.17

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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Rspack plugin for ui-inspect
3
+ */
4
+ export * from './plugin.js';
5
+ export * from './types.js';
6
+ export { default } from './plugin.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Rspack plugin for ui-inspect
3
+ */
4
+ export * from './plugin.js';
5
+ export * from './types.js';
6
+ export { default } from './plugin.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @ui-inspect/rspack-plugin
3
+ *
4
+ * Rspack plugin for ui-inspect.
5
+ * Injects browser UI into development builds served by rspack-dev-server.
6
+ */
7
+ import type { UiInspectPluginOptions } from './types.js';
8
+ interface RspackCompiler {
9
+ options: {
10
+ mode?: string;
11
+ devServer?: Record<string, unknown> & {
12
+ setupMiddlewares?: (middlewares: RspackMiddleware[], devServer: RspackDevServer) => RspackMiddleware[];
13
+ };
14
+ [key: string]: unknown;
15
+ };
16
+ hooks: {
17
+ compilation: {
18
+ tap: (name: string, fn: (c: RspackCompilation) => void) => void;
19
+ };
20
+ [key: string]: unknown;
21
+ };
22
+ }
23
+ interface RspackCompilation {
24
+ hooks: {
25
+ processAssets: {
26
+ tap: (opts: {
27
+ name: string;
28
+ stage: number;
29
+ }, fn: (assets: Record<string, RspackAsset>) => void) => void;
30
+ };
31
+ };
32
+ PROCESS_ASSETS_STAGE_ADDITIONS?: number;
33
+ }
34
+ interface RspackAsset {
35
+ source: () => string;
36
+ size: () => number;
37
+ }
38
+ interface RspackMiddleware {
39
+ [key: string]: unknown;
40
+ }
41
+ interface RspackResponse {
42
+ setHeader(k: string, v: string): void;
43
+ end(d?: string | Buffer): void;
44
+ }
45
+ interface RspackDevServer {
46
+ app?: {
47
+ get?(path: string, handler: (req: unknown, res: RspackResponse) => void): void;
48
+ [key: string]: unknown;
49
+ };
50
+ [key: string]: unknown;
51
+ }
52
+ export interface RspackUiInspectPluginOptions extends UiInspectPluginOptions {
53
+ }
54
+ export declare class RspackUiInspectPlugin {
55
+ private readonly options;
56
+ constructor(options?: RspackUiInspectPluginOptions);
57
+ apply(compiler: RspackCompiler): void;
58
+ private setupDevServerMiddleware;
59
+ private injectScriptIntoHtml;
60
+ }
61
+ export declare function uiInspect(options?: RspackUiInspectPluginOptions): RspackUiInspectPlugin;
62
+ export default RspackUiInspectPlugin;
63
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAUzD,UAAU,cAAc;IACtB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;YACpC,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,EAAE,SAAS,EAAE,eAAe,KAAK,gBAAgB,EAAE,CAAC;SACxG,CAAC;QACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,KAAK,EAAE;QACL,WAAW,EAAE;YAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,KAAK,IAAI,CAAA;SAAE,CAAC;QACjF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,UAAU,iBAAiB;IACzB,KAAK,EAAE;QACL,aAAa,EAAE;YACb,GAAG,EAAE,CAAC,IAAI,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC;SACzG,CAAC;KACH,CAAC;IACF,8BAA8B,CAAC,EAAE,MAAM,CAAC;CACzC;AAED,UAAU,WAAW;IAAG,MAAM,EAAE,MAAM,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,MAAM,CAAA;CAAE;AAElE,UAAU,gBAAgB;IAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE;AACrD,UAAU,cAAc;IAAG,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE;AAClG,UAAU,eAAe;IACvB,GAAG,CAAC,EAAE;QACJ,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAAC;QAC/E,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;CAAG;AAE/E,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;gBAErD,OAAO,GAAE,4BAAiC;IAQtD,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IASrC,OAAO,CAAC,wBAAwB;IAgChC,OAAO,CAAC,oBAAoB;CA4B7B;AAED,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,qBAAqB,CAEvF;AAED,eAAe,qBAAqB,CAAC"}
package/dist/plugin.js ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @ui-inspect/rspack-plugin
3
+ *
4
+ * Rspack plugin for ui-inspect.
5
+ * Injects browser UI into development builds served by rspack-dev-server.
6
+ */
7
+ import { readFileSync } from 'node:fs';
8
+ import { clientSource, getDianaAssetPath } from '@ui-inspect/browser-ui/plugin-runtime';
9
+ const PLUGIN_NAME = '@ui-inspect/rspack-plugin';
10
+ const CLIENT_PATH = '/@ui-inspect/client.js';
11
+ const DIANA_PATH = '/@ui-inspect/diana.webp';
12
+ const DEFAULT_DAEMON_URL = 'http://127.0.0.1:17321';
13
+ export class RspackUiInspectPlugin {
14
+ constructor(options = {}) {
15
+ this.options = {
16
+ daemonUrl: options.daemonUrl || DEFAULT_DAEMON_URL,
17
+ root: options.root || process.cwd(),
18
+ enabled: options.enabled !== false,
19
+ };
20
+ }
21
+ apply(compiler) {
22
+ if (!this.options.enabled)
23
+ return;
24
+ this.setupDevServerMiddleware(compiler);
25
+ if (compiler.options.mode !== 'production') {
26
+ this.injectScriptIntoHtml(compiler);
27
+ }
28
+ }
29
+ setupDevServerMiddleware(compiler) {
30
+ const devServer = compiler.options.devServer;
31
+ if (!devServer)
32
+ return;
33
+ const originalSetup = devServer.setupMiddlewares;
34
+ const plugin = this;
35
+ devServer.setupMiddlewares = function (middlewares, devServer) {
36
+ const clientScript = clientSource({
37
+ daemonUrl: plugin.options.daemonUrl,
38
+ root: plugin.options.root,
39
+ });
40
+ let dianaBuffer = null;
41
+ try {
42
+ dianaBuffer = readFileSync(getDianaAssetPath());
43
+ }
44
+ catch { /* sprite optional */ }
45
+ if (devServer.app) {
46
+ devServer.app.get?.(CLIENT_PATH, (_req, res) => {
47
+ res.setHeader('content-type', 'application/javascript; charset=utf-8');
48
+ res.end(clientScript);
49
+ });
50
+ devServer.app.get?.(DIANA_PATH, (_req, res) => {
51
+ res.setHeader('content-type', 'image/webp');
52
+ res.end(dianaBuffer ?? Buffer.alloc(0));
53
+ });
54
+ }
55
+ return originalSetup ? originalSetup(middlewares, devServer) : middlewares;
56
+ };
57
+ }
58
+ injectScriptIntoHtml(compiler) {
59
+ const pluginName = this.constructor.name || PLUGIN_NAME;
60
+ compiler.hooks.compilation.tap(pluginName, (compilation) => {
61
+ const stage = compilation.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;
62
+ compilation.hooks.processAssets.tap({ name: pluginName, stage }, (assets) => {
63
+ for (const assetName of Object.keys(assets)) {
64
+ if (!assetName.endsWith('.html'))
65
+ continue;
66
+ const asset = assets[assetName];
67
+ if (!asset || typeof asset.source !== 'function')
68
+ continue;
69
+ const html = asset.source();
70
+ if (html.includes(`src="${CLIENT_PATH}"`))
71
+ continue;
72
+ const script = `<script type="module" src="${CLIENT_PATH}"></script>`;
73
+ const bodyClose = html.match(/<\/body>/i);
74
+ const injected = bodyClose
75
+ ? html.slice(0, bodyClose.index) + script + html.slice(bodyClose.index)
76
+ : html + script;
77
+ assets[assetName] = { source: () => injected, size: () => injected.length };
78
+ }
79
+ });
80
+ });
81
+ }
82
+ }
83
+ export function uiInspect(options) {
84
+ return new RspackUiInspectPlugin(options);
85
+ }
86
+ export default RspackUiInspectPlugin;
87
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Type definitions for ui-inspect Rspack plugin
3
+ */
4
+ export interface UiInspectPluginOptions {
5
+ /**
6
+ * Daemon URL for SSE connection
7
+ * @default "http://127.0.0.1:17321"
8
+ */
9
+ daemonUrl?: string;
10
+ /**
11
+ * Project root path
12
+ * @default process.cwd()
13
+ */
14
+ root?: string;
15
+ /**
16
+ * Whether to enable the plugin
17
+ * @default true
18
+ */
19
+ enabled?: boolean;
20
+ }
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for ui-inspect Rspack plugin
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@ui-inspect/rspack-plugin",
3
+ "version": "0.1.17",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "src",
16
+ "!dist/**/*.test.*",
17
+ "!src/**/*.test.*"
18
+ ],
19
+ "peerDependencies": {
20
+ "@rspack/core": "^1.0.0"
21
+ },
22
+ "peerDependenciesMeta": {
23
+ "@rspack/core": {
24
+ "optional": true
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "@ui-inspect/protocol": "0.1.17",
29
+ "@ui-inspect/browser-ui": "0.1.17"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5.6.3"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "typecheck": "tsc --noEmit",
37
+ "watch": "tsc --watch"
38
+ }
39
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Rspack plugin for ui-inspect
3
+ */
4
+
5
+ export * from './plugin.js';
6
+ export * from './types.js';
7
+ export { default } from './plugin.js';
package/src/plugin.ts ADDED
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @ui-inspect/rspack-plugin
3
+ *
4
+ * Rspack plugin for ui-inspect.
5
+ * Injects browser UI into development builds served by rspack-dev-server.
6
+ */
7
+
8
+ import { readFileSync } from 'node:fs';
9
+ import { clientSource, getDianaAssetPath } from '@ui-inspect/browser-ui/plugin-runtime';
10
+ import type { UiInspectPluginOptions } from './types.js';
11
+
12
+ const PLUGIN_NAME = '@ui-inspect/rspack-plugin';
13
+
14
+ const CLIENT_PATH = '/@ui-inspect/client.js';
15
+ const DIANA_PATH = '/@ui-inspect/diana.webp';
16
+ const DEFAULT_DAEMON_URL = 'http://127.0.0.1:17321';
17
+
18
+ // Minimal Rspack type surface. Rspack intentionally mirrors Webpack's plugin
19
+ // shape, but this package does not import or depend on webpack.
20
+ interface RspackCompiler {
21
+ options: {
22
+ mode?: string;
23
+ devServer?: Record<string, unknown> & {
24
+ setupMiddlewares?: (middlewares: RspackMiddleware[], devServer: RspackDevServer) => RspackMiddleware[];
25
+ };
26
+ [key: string]: unknown;
27
+ };
28
+ hooks: {
29
+ compilation: { tap: (name: string, fn: (c: RspackCompilation) => void) => void };
30
+ [key: string]: unknown;
31
+ };
32
+ }
33
+
34
+ interface RspackCompilation {
35
+ hooks: {
36
+ processAssets: {
37
+ tap: (opts: { name: string; stage: number }, fn: (assets: Record<string, RspackAsset>) => void) => void;
38
+ };
39
+ };
40
+ PROCESS_ASSETS_STAGE_ADDITIONS?: number;
41
+ }
42
+
43
+ interface RspackAsset { source: () => string; size: () => number }
44
+
45
+ interface RspackMiddleware { [key: string]: unknown }
46
+ interface RspackResponse { setHeader(k: string, v: string): void; end(d?: string | Buffer): void }
47
+ interface RspackDevServer {
48
+ app?: {
49
+ get?(path: string, handler: (req: unknown, res: RspackResponse) => void): void;
50
+ [key: string]: unknown;
51
+ };
52
+ [key: string]: unknown;
53
+ }
54
+
55
+ export interface RspackUiInspectPluginOptions extends UiInspectPluginOptions {}
56
+
57
+ export class RspackUiInspectPlugin {
58
+ private readonly options: Required<RspackUiInspectPluginOptions>;
59
+
60
+ constructor(options: RspackUiInspectPluginOptions = {}) {
61
+ this.options = {
62
+ daemonUrl: options.daemonUrl || DEFAULT_DAEMON_URL,
63
+ root: options.root || process.cwd(),
64
+ enabled: options.enabled !== false,
65
+ };
66
+ }
67
+
68
+ apply(compiler: RspackCompiler): void {
69
+ if (!this.options.enabled) return;
70
+
71
+ this.setupDevServerMiddleware(compiler);
72
+ if (compiler.options.mode !== 'production') {
73
+ this.injectScriptIntoHtml(compiler);
74
+ }
75
+ }
76
+
77
+ private setupDevServerMiddleware(compiler: RspackCompiler): void {
78
+ const devServer = compiler.options.devServer;
79
+ if (!devServer) return;
80
+
81
+ const originalSetup = devServer.setupMiddlewares;
82
+ const plugin = this;
83
+
84
+ devServer.setupMiddlewares = function (middlewares: RspackMiddleware[], devServer: RspackDevServer): RspackMiddleware[] {
85
+ const clientScript = clientSource({
86
+ daemonUrl: plugin.options.daemonUrl,
87
+ root: plugin.options.root,
88
+ });
89
+
90
+ let dianaBuffer: Buffer | null = null;
91
+ try { dianaBuffer = readFileSync(getDianaAssetPath()); } catch { /* sprite optional */ }
92
+
93
+ if (devServer.app) {
94
+ devServer.app.get?.(CLIENT_PATH, (_req: unknown, res: RspackResponse) => {
95
+ res.setHeader('content-type', 'application/javascript; charset=utf-8');
96
+ res.end(clientScript);
97
+ });
98
+
99
+ devServer.app.get?.(DIANA_PATH, (_req: unknown, res: RspackResponse) => {
100
+ res.setHeader('content-type', 'image/webp');
101
+ res.end(dianaBuffer ?? Buffer.alloc(0));
102
+ });
103
+ }
104
+
105
+ return originalSetup ? originalSetup(middlewares, devServer) : middlewares;
106
+ };
107
+ }
108
+
109
+ private injectScriptIntoHtml(compiler: RspackCompiler): void {
110
+ const pluginName = this.constructor.name || PLUGIN_NAME;
111
+
112
+ compiler.hooks.compilation.tap(pluginName, (compilation: RspackCompilation) => {
113
+ const stage = compilation.PROCESS_ASSETS_STAGE_ADDITIONS ?? 1000;
114
+
115
+ compilation.hooks.processAssets.tap({ name: pluginName, stage }, (assets: Record<string, RspackAsset>) => {
116
+ for (const assetName of Object.keys(assets)) {
117
+ if (!assetName.endsWith('.html')) continue;
118
+
119
+ const asset = assets[assetName];
120
+ if (!asset || typeof asset.source !== 'function') continue;
121
+
122
+ const html = asset.source();
123
+
124
+ if (html.includes(`src="${CLIENT_PATH}"`)) continue;
125
+
126
+ const script = `<script type="module" src="${CLIENT_PATH}"></script>`;
127
+ const bodyClose = html.match(/<\/body>/i);
128
+ const injected = bodyClose
129
+ ? html.slice(0, bodyClose.index) + script + html.slice(bodyClose.index)
130
+ : html + script;
131
+
132
+ assets[assetName] = { source: () => injected, size: () => injected.length } as typeof asset;
133
+ }
134
+ });
135
+ });
136
+ }
137
+ }
138
+
139
+ export function uiInspect(options?: RspackUiInspectPluginOptions): RspackUiInspectPlugin {
140
+ return new RspackUiInspectPlugin(options);
141
+ }
142
+
143
+ export default RspackUiInspectPlugin;
package/src/types.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Type definitions for ui-inspect Rspack plugin
3
+ */
4
+
5
+ export interface UiInspectPluginOptions {
6
+ /**
7
+ * Daemon URL for SSE connection
8
+ * @default "http://127.0.0.1:17321"
9
+ */
10
+ daemonUrl?: string;
11
+
12
+ /**
13
+ * Project root path
14
+ * @default process.cwd()
15
+ */
16
+ root?: string;
17
+
18
+ /**
19
+ * Whether to enable the plugin
20
+ * @default true
21
+ */
22
+ enabled?: boolean;
23
+ }