@shaper.org/vite-react-plugin 1.0.16 → 1.0.18

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.mts CHANGED
@@ -2,26 +2,10 @@ import * as vite0 from "vite";
2
2
  import { UserConfig } from "vite";
3
3
 
4
4
  //#region src/index.d.ts
5
- declare const reactPlugin: (config: UserConfig) => ({
6
- name: string;
7
- enforce: string;
8
- resolveId(id: string): "virtual:hmr-events-plugin" | undefined;
9
- load(id: string): string | undefined;
10
- transformIndexHtml(html: string): {
11
- html: string;
12
- tags: {
13
- tag: string;
14
- injectTo: string;
15
- type: string;
16
- attrs: {
17
- src: string;
18
- type: string;
19
- };
20
- }[];
21
- };
22
- configureServer(server: vite0.ViteDevServer): void;
23
- handleHotUpdate(ctx: vite0.HmrContext): vite0.ModuleNode[];
24
- } | {
5
+ type ReactPluginConfig = UserConfig & {
6
+ useGenerouted?: boolean;
7
+ };
8
+ declare const reactPlugin: (config: ReactPluginConfig) => ({
25
9
  name: string;
26
10
  enforce: string;
27
11
  transform(code: any, id: any): Promise<{
@@ -34,6 +18,9 @@ declare const reactPlugin: (config: UserConfig) => ({
34
18
  apply: string;
35
19
  configResolved(resolvedConfig: vite0.ResolvedConfig): void;
36
20
  transform(code: string, id: string, options: Record<string, any>): Promise<string | undefined>;
21
+ } | {
22
+ name: string;
23
+ configureServer(server: any): void;
37
24
  })[];
38
25
  //#endregion
39
26
  export { reactPlugin };
package/dist/index.mjs CHANGED
@@ -15,9 +15,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
15
  var __getOwnPropNames = Object.getOwnPropertyNames;
16
16
  var __getProtoOf = Object.getPrototypeOf;
17
17
  var __hasOwnProp = Object.prototype.hasOwnProperty;
18
- var __commonJS = (cb, mod) => function() {
19
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
20
- };
18
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
21
19
  var __copyProps = (to, from, except, desc) => {
22
20
  if (from && typeof from === "object" || typeof from === "function") {
23
21
  for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
@@ -39,9 +37,35 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
37
 
40
38
  //#endregion
41
39
  //#region src/react-route-plugin.ts
42
- const mainContentPath = join(dirname(fileURLToPath(import.meta.url)), "../templates/main.ts");
43
- const appendTo = "src/routes.tsx";
40
+ const mainContentPath$1 = join(dirname(fileURLToPath(import.meta.url)), "../templates/main.ts");
41
+ const appendTo$1 = "src/main.tsx";
44
42
  const reactRoutesPlugin = () => {
43
+ return {
44
+ name: "react-routes-plugin",
45
+ enforce: "post",
46
+ apply: "serve",
47
+ configResolved(resolvedConfig) {},
48
+ async transform(code, id, options) {
49
+ if (options?.ssr) return;
50
+ const [filename] = id.split("?", 2);
51
+ if (typeof appendTo$1 === "string" && filename.endsWith(appendTo$1)) {
52
+ const transformed = await transform(await readFile(mainContentPath$1, { encoding: "utf-8" }), {
53
+ loader: "ts",
54
+ format: "esm",
55
+ target: "es2022"
56
+ });
57
+ code = `${code}\n${transformed.code}`;
58
+ }
59
+ return code;
60
+ }
61
+ };
62
+ };
63
+
64
+ //#endregion
65
+ //#region src/react-route-generouted.ts
66
+ const mainContentPath = join(dirname(fileURLToPath(import.meta.url)), "../templates/main-generouted.ts");
67
+ const appendTo = "src/router.ts";
68
+ const reactRoutesGeneroutedPlugin = () => {
45
69
  return {
46
70
  name: "react-routes-plugin",
47
71
  enforce: "post",
@@ -65,7 +89,7 @@ const reactRoutesPlugin = () => {
65
89
 
66
90
  //#endregion
67
91
  //#region ../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/constants.js
68
- var require_constants = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/constants.js": ((exports, module) => {
92
+ var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
69
93
  const WIN_SLASH = "\\\\/";
70
94
  const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
71
95
  /**
@@ -226,11 +250,11 @@ var require_constants = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/p
226
250
  return win32$1 === true ? WINDOWS_CHARS : POSIX_CHARS;
227
251
  }
228
252
  };
229
- }) });
253
+ }));
230
254
 
231
255
  //#endregion
232
256
  //#region ../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/utils.js
233
- var require_utils = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/utils.js": ((exports) => {
257
+ var require_utils = /* @__PURE__ */ __commonJSMin(((exports) => {
234
258
  const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = require_constants();
235
259
  exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
236
260
  exports.hasRegexChars = (str) => REGEX_SPECIAL_CHARS.test(str);
@@ -275,11 +299,11 @@ var require_utils = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picom
275
299
  if (last === "") return segs[segs.length - 2];
276
300
  return last;
277
301
  };
278
- }) });
302
+ }));
279
303
 
280
304
  //#endregion
281
305
  //#region ../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/scan.js
282
- var require_scan = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/scan.js": ((exports, module) => {
306
+ var require_scan = /* @__PURE__ */ __commonJSMin(((exports, module) => {
283
307
  const utils$3 = require_utils();
284
308
  const { CHAR_ASTERISK, CHAR_AT, CHAR_BACKWARD_SLASH, CHAR_COMMA, CHAR_DOT, CHAR_EXCLAMATION_MARK, CHAR_FORWARD_SLASH, CHAR_LEFT_CURLY_BRACE, CHAR_LEFT_PARENTHESES, CHAR_LEFT_SQUARE_BRACKET, CHAR_PLUS, CHAR_QUESTION_MARK, CHAR_RIGHT_CURLY_BRACE, CHAR_RIGHT_PARENTHESES, CHAR_RIGHT_SQUARE_BRACKET } = require_constants();
285
309
  const isPathSeparator = (code) => {
@@ -563,11 +587,11 @@ var require_scan = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picoma
563
587
  return state;
564
588
  };
565
589
  module.exports = scan$1;
566
- }) });
590
+ }));
567
591
 
568
592
  //#endregion
569
593
  //#region ../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/parse.js
570
- var require_parse = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/parse.js": ((exports, module) => {
594
+ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
571
595
  const constants$1 = require_constants();
572
596
  const utils$2 = require_utils();
573
597
  /**
@@ -1422,11 +1446,11 @@ var require_parse = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picom
1422
1446
  return source;
1423
1447
  };
1424
1448
  module.exports = parse$1;
1425
- }) });
1449
+ }));
1426
1450
 
1427
1451
  //#endregion
1428
1452
  //#region ../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/picomatch.js
1429
- var require_picomatch$1 = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/lib/picomatch.js": ((exports, module) => {
1453
+ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1430
1454
  const scan = require_scan();
1431
1455
  const parse = require_parse();
1432
1456
  const utils$1 = require_utils();
@@ -1715,11 +1739,11 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm
1715
1739
  * Expose "picomatch"
1716
1740
  */
1717
1741
  module.exports = picomatch$1;
1718
- }) });
1742
+ }));
1719
1743
 
1720
1744
  //#endregion
1721
1745
  //#region ../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/index.js
1722
- var require_picomatch = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/picomatch@4.0.3/node_modules/picomatch/index.js": ((exports, module) => {
1746
+ var require_picomatch = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1723
1747
  const pico = require_picomatch$1();
1724
1748
  const utils = require_utils();
1725
1749
  function picomatch(glob, options, returnState = false) {
@@ -1731,10 +1755,10 @@ var require_picomatch = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/p
1731
1755
  }
1732
1756
  Object.assign(picomatch, pico);
1733
1757
  module.exports = picomatch;
1734
- }) });
1758
+ }));
1735
1759
 
1736
1760
  //#endregion
1737
- //#region ../../node_modules/.pnpm/@rollup+pluginutils@5.3.0_rollup@4.53.3/node_modules/@rollup/pluginutils/dist/es/index.js
1761
+ //#region ../../node_modules/.pnpm/@rollup+pluginutils@5.3.0_rollup@4.59.0/node_modules/@rollup/pluginutils/dist/es/index.js
1738
1762
  var import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
1739
1763
  function isArray(arg) {
1740
1764
  return Array.isArray(arg);
@@ -1861,13 +1885,47 @@ function jsxSourcePlugin(options = {}) {
1861
1885
  };
1862
1886
  }
1863
1887
 
1888
+ //#endregion
1889
+ //#region src/analyze-deps-plugin.ts
1890
+ function analyzeDepsPlugin() {
1891
+ return {
1892
+ name: "analyze-deps",
1893
+ configureServer(server) {
1894
+ server.middlewares.use("/__analyze", async (req, res) => {
1895
+ console.log(req.url);
1896
+ try {
1897
+ const entry = new URL(req.url, "http://localhost").searchParams.get("entry");
1898
+ await server.transformRequest(entry);
1899
+ const mod = await server.moduleGraph.getModuleByUrl(entry);
1900
+ const result = [];
1901
+ for (const nodeModule of mod._clientModule.importedModules) result.push({
1902
+ id: nodeModule.id,
1903
+ file: nodeModule.file
1904
+ });
1905
+ res.setHeader("Content-Type", "application/json");
1906
+ res.statusCode = 200;
1907
+ res.end(JSON.stringify({
1908
+ modules: result,
1909
+ file: mod._clientModule.file
1910
+ }));
1911
+ } catch (err) {
1912
+ res.setHeader("Content-Type", "application/json");
1913
+ res.statusCode = 500;
1914
+ res.end(JSON.stringify({ msg: err.message ?? "Unexpected error." }));
1915
+ }
1916
+ });
1917
+ }
1918
+ };
1919
+ }
1920
+
1864
1921
  //#endregion
1865
1922
  //#region src/index.ts
1866
1923
  const reactPlugin = (config) => {
1867
1924
  return [
1868
1925
  HMREventsPlugin(),
1869
1926
  jsxSourcePlugin(config),
1870
- reactRoutesPlugin()
1927
+ config?.useGenerouted ? reactRoutesGeneroutedPlugin() : reactRoutesPlugin(),
1928
+ analyzeDepsPlugin()
1871
1929
  ];
1872
1930
  };
1873
1931
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaper.org/vite-react-plugin",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "private": false,
@@ -0,0 +1,243 @@
1
+ /// <reference lib="dom" />
2
+ import { IframePostMessageClient } from "@shaper.org/core/client";
3
+ import { routes } from "@generouted/react-router/lazy";
4
+
5
+ export const eventMap = {
6
+ MouseUp: 0,
7
+ MouseDown: 1,
8
+ Click: 2,
9
+ ContextMenu: 3,
10
+ DblClick: 4,
11
+ Focus: 5,
12
+ Blur: 6,
13
+ TouchStart: 7,
14
+ TouchMove: 8,
15
+ TouchEnd: 9,
16
+ TouchCancel: 10,
17
+ };
18
+ export type EventName = keyof typeof eventMap;
19
+
20
+ export const settings = {
21
+ MouseUp: true,
22
+ MouseDown: true,
23
+ Click: true,
24
+ ContextMenu: true,
25
+ DblClick: true,
26
+ Focus: true,
27
+ Blur: true,
28
+ TouchStart: true,
29
+ TouchMove: true,
30
+ TouchEnd: true,
31
+ TouchCancel: true,
32
+ };
33
+
34
+ export interface EventsSetting {
35
+ MouseUp?: boolean;
36
+ MouseDown?: boolean;
37
+ Click?: boolean;
38
+ ContextMenu?: boolean;
39
+ DblClick?: boolean;
40
+ Focus?: boolean;
41
+ Blur?: boolean;
42
+ TouchStart?: boolean;
43
+ TouchMove?: boolean;
44
+ TouchEnd?: boolean;
45
+ TouchCancel?: boolean;
46
+ }
47
+
48
+ export interface Router {
49
+ routes: Array<{ path: string; name?: string }>;
50
+ state: {
51
+ matches: Array<{
52
+ route: { path: string; name?: string };
53
+ }>;
54
+ };
55
+ }
56
+
57
+ export interface GeneroutedRoute {
58
+ id: string;
59
+ path: string;
60
+ }
61
+
62
+ export interface GeneroutedRoutes {
63
+ children: GeneroutedRoute[];
64
+ }
65
+
66
+ export interface ReactRouteMonitorOptions {
67
+ routes: GeneroutedRoutes[];
68
+ eventSettings: EventsSetting;
69
+ }
70
+
71
+ export class ReactRouteMonitor {
72
+ private iframeClient: IframePostMessageClient;
73
+ private eventSettings: EventsSetting;
74
+
75
+ private origPush: History["pushState"];
76
+ private origReplace: History["replaceState"];
77
+
78
+ private listeners: Array<() => void>;
79
+
80
+ private selectedNode: HTMLElement | null = null;
81
+
82
+ private routes: GeneroutedRoutes[];
83
+
84
+ constructor({ routes, eventSettings }: ReactRouteMonitorOptions) {
85
+ this.routes = routes;
86
+ this.iframeClient = new IframePostMessageClient();
87
+
88
+ // store originals
89
+ this.origPush = history.pushState;
90
+ this.origReplace = history.replaceState;
91
+
92
+ this.listeners = [];
93
+
94
+ this.eventSettings = this._buildEventSettings(eventSettings);
95
+ }
96
+
97
+ _buildEventSettings(userSettings: EventsSetting) {
98
+ const settings: EventsSetting = {};
99
+
100
+ (Object.keys(eventMap) as EventName[]).forEach((key) => {
101
+ settings[key] =
102
+ typeof userSettings[key] === "boolean"
103
+ ? userSettings[key]!
104
+ : false;
105
+ });
106
+
107
+ return settings;
108
+ }
109
+
110
+ start() {
111
+ this.patchHistory();
112
+ this.attachGlobalListeners();
113
+ window.addEventListener("locationchange", this.onLocationChange);
114
+ window.addEventListener("popstate", this.triggerRouteChange);
115
+
116
+ this.sendAllRoutes = this.sendAllRoutes.bind(this);
117
+ window.addEventListener("getroutes", this.sendAllRoutes);
118
+ }
119
+
120
+ stop() {
121
+ // Restore history
122
+ history.pushState = this.origPush;
123
+ history.replaceState = this.origReplace;
124
+
125
+ // Remove listeners
126
+ this.listeners.forEach((remove: () => void) => remove());
127
+ this.listeners = [];
128
+
129
+ window.removeEventListener("locationchange", this.onLocationChange);
130
+ window.removeEventListener("popstate", this.triggerRouteChange);
131
+ window.removeEventListener("getroutes", this.triggerRoutes);
132
+ }
133
+
134
+ patchHistory() {
135
+ history.pushState = (...args) => {
136
+ this.origPush.apply(history, args);
137
+ this.triggerRouteChange();
138
+ };
139
+
140
+ history.replaceState = (...args) => {
141
+ this.origReplace.apply(history, args);
142
+ this.triggerRouteChange();
143
+ };
144
+ }
145
+
146
+ sendAllRoutes(event: CustomEvent<{ routes: GeneroutedRoute[] }>) {
147
+ if (!event) return;
148
+
149
+ const validRoutes = event.detail.routes.filter(
150
+ (route) => route.path !== "*",
151
+ );
152
+
153
+ const routes = validRoutes.map((route) => ({
154
+ name: route.id,
155
+ path: route.id === "index" ? route.path : `/${route.path}`,
156
+ file: `src/${route.id}.tsx`,
157
+ }));
158
+
159
+ this.iframeClient.sendAllRoutes(routes);
160
+ }
161
+
162
+ triggerRoutes = () => {
163
+ window.dispatchEvent(
164
+ new CustomEvent("getroutes", {
165
+ detail: { routes: this.routes[0].children },
166
+ }),
167
+ );
168
+ };
169
+
170
+ triggerRouteChange = () => {
171
+ window.dispatchEvent(
172
+ new CustomEvent("locationchange", {
173
+ detail: { node: this.selectedNode },
174
+ }),
175
+ );
176
+ };
177
+
178
+ onLocationChange = (_event: CustomEvent<{ node?: HTMLElement }>) => {
179
+ const toPathname = window.location.pathname;
180
+
181
+ const matches = this.routes[0].children.filter((r) =>
182
+ toPathname === "/"
183
+ ? r.path === toPathname
184
+ : `/${r.path}` === toPathname,
185
+ );
186
+
187
+ if (matches.length === 0) return;
188
+
189
+ const to = matches[0];
190
+
191
+ const routeInfo = {
192
+ name: to.id,
193
+ path: to.id === "index" ? to.path : `/${to.path}`,
194
+ file: `src/${to.id}.tsx`,
195
+ };
196
+ this.iframeClient.sendRouteChange(routeInfo);
197
+ };
198
+
199
+ attachGlobalListeners() {
200
+ (Object.keys(eventMap) as EventName[])
201
+ .filter((key) => this.eventSettings[key] !== false)
202
+ .forEach((key) => {
203
+ const handler = this._createInteractionHandler(key);
204
+ const remove = this._addEventListenerToDocument(
205
+ key.toLowerCase(),
206
+ handler,
207
+ );
208
+ this.listeners.push(remove);
209
+ });
210
+ }
211
+
212
+ _addEventListenerToDocument(eventName: string, handler: EventListener) {
213
+ document.addEventListener(eventName, handler, true);
214
+ return () => document.removeEventListener(eventName, handler, true);
215
+ }
216
+
217
+ _createInteractionHandler(eventType: EventName) {
218
+ return (event: Event) => {
219
+ if (eventMap[eventType] === eventMap.Click) {
220
+ const target = event.target as HTMLElement | null;
221
+
222
+ if (!target) return;
223
+
224
+ this.selectedNode = target;
225
+
226
+ const a = target.closest("a");
227
+
228
+ if (!a || a.target === "_blank" || a.href.startsWith("mailto:"))
229
+ return;
230
+ }
231
+ };
232
+ }
233
+ }
234
+
235
+ const monitor = new ReactRouteMonitor({
236
+ routes,
237
+ eventSettings: {
238
+ Click: true,
239
+ },
240
+ });
241
+
242
+ monitor.start();
243
+ monitor.triggerRoutes();
package/templates/main.ts CHANGED
@@ -139,6 +139,8 @@ export class ReactRouteMonitor {
139
139
  (route) => route.element !== undefined && route.path !== "*",
140
140
  );
141
141
 
142
+ console.log(validRoutes);
143
+
142
144
  const routes = validRoutes.map((route) => ({
143
145
  name: route.path,
144
146
  path: route.path,
@@ -231,7 +233,7 @@ export class ReactRouteMonitor {
231
233
  };
232
234
  }
233
235
  }
234
-
236
+ console.log(router);
235
237
  const monitor = new ReactRouteMonitor({
236
238
  router,
237
239
  eventSettings: {
@@ -239,7 +241,5 @@ const monitor = new ReactRouteMonitor({
239
241
  },
240
242
  });
241
243
 
242
-
243
-
244
244
  monitor.start();
245
245
  monitor.triggerRoutes();