@shaper.org/core 1.0.2 → 1.0.4-prerelease
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/client/index.d.mts +61 -0
- package/dist/client/index.mjs +79 -0
- package/dist/node/index.d.mts +27 -0
- package/dist/node/index.mjs +48 -0
- package/dist/runtime/error-tracker.ts +54 -104
- package/dist/runtime/vite-hook.ts +112 -111
- package/package.json +14 -3
- package/dist/index.d.mts +0 -72
- package/dist/index.mjs +0 -94
- package/src/runtime/error-tracker.ts +0 -166
- package/src/runtime/vite-hook.ts +0 -133
- package/src/runtime/vite-message.ts +0 -61
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/client/iframe-post-message.d.ts
|
|
2
|
+
type PostMessageType = "server-ready" | "all-routes" | "route-change" | "route-refresh" | "error";
|
|
3
|
+
interface PostMessage {
|
|
4
|
+
message: any;
|
|
5
|
+
type: PostMessageType;
|
|
6
|
+
object: "shaper-post-message";
|
|
7
|
+
}
|
|
8
|
+
interface RouteInfo {
|
|
9
|
+
name: string;
|
|
10
|
+
path: string;
|
|
11
|
+
file: string;
|
|
12
|
+
}
|
|
13
|
+
interface ServerReadyMessage extends PostMessage {
|
|
14
|
+
type: "server-ready";
|
|
15
|
+
message: {
|
|
16
|
+
satus: "ok";
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
interface AllRoutesMessage extends PostMessage {
|
|
20
|
+
type: "all-routes";
|
|
21
|
+
message: {
|
|
22
|
+
routes: RouteInfo[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
interface RouteChangeMessage extends PostMessage {
|
|
26
|
+
type: "route-change";
|
|
27
|
+
message: RouteInfo;
|
|
28
|
+
}
|
|
29
|
+
interface RouteRefreshMessage extends PostMessage {
|
|
30
|
+
type: "route-refresh";
|
|
31
|
+
message: RouteInfo;
|
|
32
|
+
}
|
|
33
|
+
interface ErrorInfo {
|
|
34
|
+
errorType: string;
|
|
35
|
+
timestamp: number;
|
|
36
|
+
lineno?: number;
|
|
37
|
+
colno?: number;
|
|
38
|
+
stack: string;
|
|
39
|
+
has_blank_screen: boolean;
|
|
40
|
+
filename?: string;
|
|
41
|
+
}
|
|
42
|
+
declare class IframePostMessageClient {
|
|
43
|
+
authHost: string;
|
|
44
|
+
private receiveCallbacks;
|
|
45
|
+
constructor();
|
|
46
|
+
_ensure_route_file(route: RouteInfo): void;
|
|
47
|
+
_send(message: PostMessage): void;
|
|
48
|
+
/**
|
|
49
|
+
* Allow consumers to register callbacks for incoming messages.
|
|
50
|
+
*/
|
|
51
|
+
onMessage(callback: (event: MessageEvent<any>) => void): void;
|
|
52
|
+
onReceiveMessage(message: MessageEvent<any>): void;
|
|
53
|
+
sendServerReady(): void;
|
|
54
|
+
sendAllRoutes(routes: RouteInfo[]): void;
|
|
55
|
+
sendRouteChange(route: RouteInfo): void;
|
|
56
|
+
sendRouteRefresh(route: RouteInfo): void;
|
|
57
|
+
sendError(errorInfo: ErrorInfo): void;
|
|
58
|
+
sendConsole(): void;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { AllRoutesMessage, IframePostMessageClient, PostMessage, PostMessageType, RouteChangeMessage, RouteInfo, RouteRefreshMessage, ServerReadyMessage };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//#region src/client/iframe-post-message.ts
|
|
2
|
+
var IframePostMessageClient = class {
|
|
3
|
+
authHost;
|
|
4
|
+
receiveCallbacks = [];
|
|
5
|
+
constructor() {
|
|
6
|
+
if (!import.meta.env) throw new Error("import.meta.env is not defined");
|
|
7
|
+
const AUTH_HOST = import.meta.env.VITE_FRONT_URL;
|
|
8
|
+
this.authHost = AUTH_HOST.endsWith("/") ? AUTH_HOST.slice(0, -1) : AUTH_HOST;
|
|
9
|
+
this.receiveCallbacks = [];
|
|
10
|
+
this.onReceiveMessage = this.onReceiveMessage.bind(this);
|
|
11
|
+
window.addEventListener("message", this.onReceiveMessage);
|
|
12
|
+
}
|
|
13
|
+
_ensure_route_file(route) {
|
|
14
|
+
if (!route.file.startsWith("src")) throw Error(`Invalid route file, route file should be relative to the root got: ${route.file}`);
|
|
15
|
+
}
|
|
16
|
+
_send(message) {
|
|
17
|
+
window.parent.postMessage(message, this.authHost);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Allow consumers to register callbacks for incoming messages.
|
|
21
|
+
*/
|
|
22
|
+
onMessage(callback) {
|
|
23
|
+
this.receiveCallbacks.push(callback);
|
|
24
|
+
}
|
|
25
|
+
onReceiveMessage(message) {
|
|
26
|
+
if (message.origin !== this.authHost) return;
|
|
27
|
+
for (const cb of this.receiveCallbacks) try {
|
|
28
|
+
cb(message);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error("Provided callback failed:", err);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
sendServerReady() {
|
|
34
|
+
this._send({
|
|
35
|
+
type: "server-ready",
|
|
36
|
+
message: { satus: "ok" },
|
|
37
|
+
object: "shaper-post-message"
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
sendAllRoutes(routes) {
|
|
41
|
+
for (let route of routes) this._ensure_route_file(route);
|
|
42
|
+
const message = {
|
|
43
|
+
type: "all-routes",
|
|
44
|
+
message: { routes },
|
|
45
|
+
object: "shaper-post-message"
|
|
46
|
+
};
|
|
47
|
+
this._send(message);
|
|
48
|
+
}
|
|
49
|
+
sendRouteChange(route) {
|
|
50
|
+
this._ensure_route_file(route);
|
|
51
|
+
const message = {
|
|
52
|
+
type: "route-change",
|
|
53
|
+
message: { ...route },
|
|
54
|
+
object: "shaper-post-message"
|
|
55
|
+
};
|
|
56
|
+
this._send(message);
|
|
57
|
+
}
|
|
58
|
+
sendRouteRefresh(route) {
|
|
59
|
+
this._ensure_route_file(route);
|
|
60
|
+
const message = {
|
|
61
|
+
type: "route-refresh",
|
|
62
|
+
message: { ...route },
|
|
63
|
+
object: "shaper-post-message"
|
|
64
|
+
};
|
|
65
|
+
this._send(message);
|
|
66
|
+
}
|
|
67
|
+
sendError(errorInfo) {
|
|
68
|
+
const message = {
|
|
69
|
+
type: "error",
|
|
70
|
+
message: errorInfo,
|
|
71
|
+
object: "shaper-post-message"
|
|
72
|
+
};
|
|
73
|
+
this._send(message);
|
|
74
|
+
}
|
|
75
|
+
sendConsole() {}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { IframePostMessageClient };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as vite0 from "vite";
|
|
2
|
+
import { HmrContext, ViteDevServer } from "vite";
|
|
3
|
+
|
|
4
|
+
//#region src/node/hmr-events-plugin.d.ts
|
|
5
|
+
declare const HMREventsPlugin: () => {
|
|
6
|
+
name: string;
|
|
7
|
+
enforce: string;
|
|
8
|
+
apply: string;
|
|
9
|
+
resolveId(id: string): "virtual:hmr-events-plugin" | undefined;
|
|
10
|
+
load(id: string): string | undefined;
|
|
11
|
+
transformIndexHtml(html: string): {
|
|
12
|
+
html: string;
|
|
13
|
+
tags: {
|
|
14
|
+
tag: string;
|
|
15
|
+
injectTo: string;
|
|
16
|
+
type: string;
|
|
17
|
+
attrs: {
|
|
18
|
+
src: string;
|
|
19
|
+
type: string;
|
|
20
|
+
};
|
|
21
|
+
}[];
|
|
22
|
+
};
|
|
23
|
+
configureServer(server: ViteDevServer): void;
|
|
24
|
+
handleHotUpdate(ctx: HmrContext): vite0.ModuleNode[];
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { HMREventsPlugin };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { fileURLToPath } from "url";
|
|
2
|
+
|
|
3
|
+
//#region src/node/hmr-events-plugin.ts
|
|
4
|
+
const HMREventsPlugin = () => {
|
|
5
|
+
return {
|
|
6
|
+
name: "hmr-events-plugin",
|
|
7
|
+
enforce: "post",
|
|
8
|
+
apply: "serve",
|
|
9
|
+
resolveId(id) {
|
|
10
|
+
if (id === "virtual:hmr-events-plugin") return id;
|
|
11
|
+
},
|
|
12
|
+
load(id) {
|
|
13
|
+
if (id === "virtual:hmr-events-plugin") {
|
|
14
|
+
const runtimePath = fileURLToPath(new URL("../runtime/error-tracker", import.meta.url));
|
|
15
|
+
return `import ${JSON.stringify(runtimePath)};`;
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
transformIndexHtml(html) {
|
|
19
|
+
return {
|
|
20
|
+
html,
|
|
21
|
+
tags: [{
|
|
22
|
+
tag: "script",
|
|
23
|
+
injectTo: "body",
|
|
24
|
+
type: "module",
|
|
25
|
+
attrs: {
|
|
26
|
+
src: "/@id/virtual:hmr-events-plugin",
|
|
27
|
+
type: "module"
|
|
28
|
+
}
|
|
29
|
+
}]
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
configureServer(server) {
|
|
33
|
+
server.ws.on("breeze:beforeUpdate", (event) => {});
|
|
34
|
+
server.ws.on("breeze:afterUpdate", (event) => {
|
|
35
|
+
for (let eventMessage of event.data) console.log(eventMessage.message);
|
|
36
|
+
console.log("[breeze] end update");
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
handleHotUpdate(ctx) {
|
|
40
|
+
const { file, timestamp, read, server, modules } = ctx;
|
|
41
|
+
console.log(`[breeze] hmr update: ${file}`);
|
|
42
|
+
return modules;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { HMREventsPlugin };
|
|
@@ -1,46 +1,22 @@
|
|
|
1
1
|
import { ViteHook } from "./vite-hook";
|
|
2
2
|
import { ViteMessage } from "./vite-message";
|
|
3
|
-
|
|
4
|
-
interface LogEvent {
|
|
5
|
-
type: "logEvent";
|
|
6
|
-
logLevel: string;
|
|
7
|
-
timestamp: number;
|
|
8
|
-
message: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface UnhandledrejectionEvent {
|
|
12
|
-
type: "unhandledrejectionEvent";
|
|
13
|
-
message: string;
|
|
14
|
-
timestamp: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ErrorEvent {
|
|
18
|
-
type: "errorEvent";
|
|
19
|
-
lineno: number;
|
|
20
|
-
colno: number;
|
|
21
|
-
filename: string;
|
|
22
|
-
message: string;
|
|
23
|
-
timestamp: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
type Event = LogEvent | UnhandledrejectionEvent | ErrorEvent;
|
|
3
|
+
import { IframePostMessageClient } from "../client";
|
|
27
4
|
|
|
28
5
|
class ErrorTracker {
|
|
29
|
-
eventsQueue: Event[];
|
|
30
|
-
|
|
31
6
|
public vHook: ViteHook;
|
|
32
7
|
public viteMessage: ViteMessage;
|
|
8
|
+
private iframeClient: IframePostMessageClient;
|
|
33
9
|
|
|
34
10
|
constructor() {
|
|
35
|
-
this.eventsQueue = [];
|
|
36
|
-
|
|
37
11
|
this.viteMessage = new ViteMessage();
|
|
38
12
|
|
|
39
13
|
this.vHook = new ViteHook();
|
|
14
|
+
|
|
15
|
+
this.iframeClient = new IframePostMessageClient();
|
|
40
16
|
}
|
|
41
17
|
|
|
42
18
|
isBlankScreen() {
|
|
43
|
-
const app = document.querySelector("div#
|
|
19
|
+
const app = document.querySelector("div#root");
|
|
44
20
|
return app ? app.childElementCount === 0 : false;
|
|
45
21
|
}
|
|
46
22
|
|
|
@@ -48,35 +24,29 @@ class ErrorTracker {
|
|
|
48
24
|
this.handleError();
|
|
49
25
|
this.handleUnhandledrejection();
|
|
50
26
|
this.consoleInterception();
|
|
27
|
+
}
|
|
51
28
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.vHook.onAfterUpdate((data, timestamp) => {
|
|
63
|
-
setTimeout(() => {
|
|
64
|
-
const endTimestamp = Date.now();
|
|
65
|
-
|
|
66
|
-
let events = this.eventsQueue.filter(
|
|
67
|
-
(event) =>
|
|
68
|
-
event.timestamp >= startTimestamp &&
|
|
69
|
-
event.timestamp <= endTimestamp,
|
|
70
|
-
);
|
|
29
|
+
formatConsoleMessage(args: unknown[]): string {
|
|
30
|
+
let error;
|
|
31
|
+
const texts = [];
|
|
32
|
+
for (let arg of args) {
|
|
33
|
+
if (arg instanceof Error) {
|
|
34
|
+
error = arg;
|
|
35
|
+
} else {
|
|
36
|
+
texts.push(arg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
71
39
|
|
|
72
|
-
|
|
40
|
+
if (error) {
|
|
41
|
+
return error.stack || error.message;
|
|
42
|
+
}
|
|
73
43
|
|
|
74
|
-
|
|
75
|
-
}, 5);
|
|
76
|
-
});
|
|
44
|
+
return texts.map((text) => String(text)).join(" ");
|
|
77
45
|
}
|
|
78
46
|
|
|
79
47
|
consoleInterception() {
|
|
48
|
+
type LogLevel = keyof typeof originalConsole;
|
|
49
|
+
|
|
80
50
|
const originalConsole = {
|
|
81
51
|
log: console.log,
|
|
82
52
|
warn: console.warn,
|
|
@@ -84,83 +54,63 @@ class ErrorTracker {
|
|
|
84
54
|
trace: console.trace,
|
|
85
55
|
// debug: console.debug,
|
|
86
56
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return arg.toString();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
this.eventsQueue.push({
|
|
97
|
-
type: "logEvent",
|
|
98
|
-
logLevel,
|
|
99
|
-
timestamp: Date.now(),
|
|
100
|
-
message: logArgumentsString.join(" "),
|
|
101
|
-
});
|
|
57
|
+
for (let logLevel of Object.keys(originalConsole) as LogLevel[]) {
|
|
58
|
+
console[logLevel] = function (
|
|
59
|
+
this: ErrorTracker,
|
|
60
|
+
...args: unknown[]
|
|
61
|
+
) {
|
|
102
62
|
originalConsole[logLevel].apply(this, args);
|
|
63
|
+
|
|
64
|
+
const message = this.formatConsoleMessage(args);
|
|
65
|
+
|
|
66
|
+
if (!message) return;
|
|
67
|
+
|
|
68
|
+
if (logLevel === "error") {
|
|
69
|
+
console.debug("console error", message);
|
|
70
|
+
this.iframeClient.sendError({
|
|
71
|
+
errorType: "RUNTIME_ERROR",
|
|
72
|
+
timestamp: Date.now(),
|
|
73
|
+
stack: message,
|
|
74
|
+
has_blank_screen: this.isBlankScreen(),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
103
77
|
}.bind(this);
|
|
104
78
|
}
|
|
105
79
|
}
|
|
106
80
|
|
|
107
81
|
handleUnhandledrejection() {
|
|
108
82
|
window.addEventListener("unhandledrejection", (evt) => {
|
|
109
|
-
console.debug(evt);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
message: evt.reason.stack || evt.reason.message,
|
|
83
|
+
console.debug("handleUnhandledrejection", evt);
|
|
84
|
+
this.iframeClient.sendError({
|
|
85
|
+
errorType: "RUNTIME_ERROR",
|
|
113
86
|
timestamp: Date.now(),
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
87
|
+
stack: evt.reason.stack || evt.reason.message,
|
|
88
|
+
has_blank_screen: this.isBlankScreen(),
|
|
89
|
+
});
|
|
117
90
|
});
|
|
118
91
|
}
|
|
119
92
|
|
|
120
93
|
handleError() {
|
|
121
94
|
window.addEventListener("error", (evt) => {
|
|
95
|
+
console.debug("handleError", evt);
|
|
122
96
|
let message;
|
|
123
97
|
if (evt.error) {
|
|
124
98
|
message = evt.error.stack || evt.error.message;
|
|
125
99
|
} else {
|
|
126
100
|
message = evt.message;
|
|
127
101
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
102
|
+
this.iframeClient.sendError({
|
|
103
|
+
errorType: "RUNTIME_ERROR",
|
|
104
|
+
timestamp: Date.now(),
|
|
105
|
+
stack: message,
|
|
106
|
+
has_blank_screen: this.isBlankScreen(),
|
|
132
107
|
lineno: evt.lineno,
|
|
133
108
|
colno: evt.colno,
|
|
134
109
|
filename: evt.filename,
|
|
135
|
-
|
|
136
|
-
timestamp: Date.now(),
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
this.eventsQueue.push(errorMessage);
|
|
110
|
+
});
|
|
140
111
|
});
|
|
141
|
-
|
|
142
|
-
// This handle the following kind of runtime error
|
|
143
|
-
// For now it's diffcult to know what to do because those errors are not sync with the HMR lifecyle
|
|
144
|
-
// Maybe use a queue
|
|
145
|
-
// <script setup lang="ts">
|
|
146
|
-
// import { onMounted } from 'vue';
|
|
147
|
-
|
|
148
|
-
// onMounted(() => {
|
|
149
|
-
// // This will trigger the error event because it happens at runtime
|
|
150
|
-
// setTimeout(() => {
|
|
151
|
-
// undefinedFunction(); // Runtime error - WILL trigger window.error
|
|
152
|
-
// }, 0);
|
|
153
|
-
// });
|
|
154
|
-
// </script>
|
|
155
112
|
}
|
|
156
113
|
}
|
|
157
114
|
|
|
158
115
|
const tracker = new ErrorTracker();
|
|
159
116
|
tracker.start();
|
|
160
|
-
|
|
161
|
-
// HMR listening
|
|
162
|
-
// const handleMessage = (event) => {
|
|
163
|
-
// console.log(event);
|
|
164
|
-
// };
|
|
165
|
-
|
|
166
|
-
// window.addEventListener("message", handleMessage);
|
|
@@ -1,133 +1,134 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
ErrorPayload,
|
|
3
|
+
FullReloadPayload,
|
|
4
|
+
PrunePayload,
|
|
5
|
+
UpdatePayload,
|
|
6
6
|
} from "vite/types/hmrPayload.js";
|
|
7
7
|
import { ViteHotContext } from "vite/types/hot.js";
|
|
8
8
|
|
|
9
9
|
type ViteUpdateCallback =
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
| ((data: UpdatePayload, timestamp: number) => void)
|
|
11
|
+
| null;
|
|
12
12
|
|
|
13
13
|
type VitePruneCallback =
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
| ((data: PrunePayload, timestamp: number) => void)
|
|
15
|
+
| null;
|
|
16
16
|
|
|
17
17
|
type VitFullReloadCallback =
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
| ((data: FullReloadPayload, timestamp: number) => void)
|
|
19
|
+
| null;
|
|
20
20
|
|
|
21
21
|
type ViteErrorCallback =
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
| ((data: ErrorPayload, timestamp: number) => void)
|
|
23
|
+
| null;
|
|
24
24
|
|
|
25
25
|
type ViteInvalidateCallback = ((data: any, timestamp: number) => void) | null;
|
|
26
26
|
|
|
27
27
|
type ViteWebSocketConnectCallback =
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
| ((data: any, timestamp: number) => void)
|
|
29
|
+
| null;
|
|
30
30
|
|
|
31
31
|
type ViteWebSocketDisconnectCallback =
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
| ((data: any, timestamp: number) => void)
|
|
33
|
+
| null;
|
|
34
34
|
|
|
35
35
|
class ViteHook {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
36
|
+
private hmr: ViteHotContext | undefined;
|
|
37
|
+
constructor() {
|
|
38
|
+
this.hmr = import.meta.hot;
|
|
39
|
+
}
|
|
40
|
+
hotExists(hmr: ViteHotContext | undefined): hmr is ViteHotContext {
|
|
41
|
+
if (hmr) return true;
|
|
42
|
+
console.error("HotContext does not exists");
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
onBeforeUpdate(fn: ViteUpdateCallback = null) {
|
|
47
|
+
if (!this.hotExists(this.hmr)) return;
|
|
48
|
+
|
|
49
|
+
this.hmr.on("vite:beforeUpdate", (data: UpdatePayload) => {
|
|
50
|
+
const timestamp = Date.now();
|
|
51
|
+
console.debug("beforeUpdate");
|
|
52
|
+
fn && fn(data, timestamp);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
onAfterUpdate(fn: ViteUpdateCallback = null) {
|
|
57
|
+
if (!this.hotExists(this.hmr)) return;
|
|
58
|
+
|
|
59
|
+
this.hmr.on("vite:afterUpdate", (data: UpdatePayload) => {
|
|
60
|
+
const timestamp = Date.now();
|
|
61
|
+
console.debug("afterUpdate");
|
|
62
|
+
fn && fn(data, timestamp);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
onBeforePrune(fn: VitePruneCallback = null) {
|
|
67
|
+
if (!this.hotExists(this.hmr)) return;
|
|
68
|
+
|
|
69
|
+
this.hmr.on("vite:beforePrune", (data: PrunePayload) => {
|
|
70
|
+
const timestamp = Date.now();
|
|
71
|
+
console.debug("beforePrune");
|
|
72
|
+
|
|
73
|
+
fn && fn(data, timestamp);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
onBeforeFullReload(fn: VitFullReloadCallback = null) {
|
|
78
|
+
if (!this.hotExists(this.hmr)) return;
|
|
79
|
+
|
|
80
|
+
this.hmr.on("vite:beforeFullReload", (data: FullReloadPayload) => {
|
|
81
|
+
const timestamp = Date.now();
|
|
82
|
+
console.debug("beforeFullReload");
|
|
83
|
+
|
|
84
|
+
fn && fn(data, timestamp);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onError(fn: ViteErrorCallback = null) {
|
|
89
|
+
if (!this.hotExists(this.hmr)) return;
|
|
90
|
+
|
|
91
|
+
this.hmr.on("vite:error", (data: ErrorPayload) => {
|
|
92
|
+
const timestamp = Date.now();
|
|
93
|
+
console.debug("error");
|
|
94
|
+
console.log(this.hmr);
|
|
95
|
+
|
|
96
|
+
fn && fn(data, timestamp);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
onInvalidate(fn: ViteInvalidateCallback = null) {
|
|
101
|
+
if (!this.hotExists(this.hmr)) return;
|
|
102
|
+
|
|
103
|
+
this.hmr.on("vite:invalidate", (data: any) => {
|
|
104
|
+
const timestamp = Date.now();
|
|
105
|
+
console.debug("invalidate");
|
|
106
|
+
|
|
107
|
+
fn && fn(data, timestamp);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
onWsConnect(fn: ViteWebSocketConnectCallback = null) {
|
|
112
|
+
if (!this.hotExists(this.hmr)) return;
|
|
113
|
+
|
|
114
|
+
this.hmr.on("vite:ws:connect", (data: any) => {
|
|
115
|
+
const timestamp = Date.now();
|
|
116
|
+
console.debug("ws:connect");
|
|
117
|
+
|
|
118
|
+
fn && fn(data, timestamp);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
onWsDisconnect(fn: ViteWebSocketDisconnectCallback = null) {
|
|
123
|
+
if (!this.hotExists(this.hmr)) return;
|
|
124
|
+
|
|
125
|
+
this.hmr.on("vite:ws:disconnect", (data: any) => {
|
|
126
|
+
const timestamp = Date.now();
|
|
127
|
+
console.debug(":ws:disconnect");
|
|
128
|
+
|
|
129
|
+
fn && fn(data, timestamp);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
export { ViteHook };
|
package/package.json
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shaper.org/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4-prerelease",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
"src/runtime"
|
|
8
|
+
"dist"
|
|
10
9
|
],
|
|
11
10
|
"exports": {
|
|
12
11
|
".": {
|
|
13
12
|
"import": "./dist/index.mjs",
|
|
14
13
|
"types": "./dist/index.d.ts"
|
|
15
14
|
},
|
|
15
|
+
"./client": {
|
|
16
|
+
"import": "./dist/client/index.mjs",
|
|
17
|
+
"types": "./dist/client/index.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./node": {
|
|
20
|
+
"import": "./dist/node/index.mjs",
|
|
21
|
+
"types": "./dist/node/index.d.ts"
|
|
22
|
+
},
|
|
16
23
|
"./package.json": "./package.json"
|
|
17
24
|
},
|
|
18
25
|
"types": "./dist/index.d.ts",
|
|
@@ -47,6 +54,10 @@
|
|
|
47
54
|
],
|
|
48
55
|
"copy": [
|
|
49
56
|
"src/runtime/"
|
|
57
|
+
],
|
|
58
|
+
"entry": [
|
|
59
|
+
"src/node/index.ts",
|
|
60
|
+
"src/client/index.ts"
|
|
50
61
|
]
|
|
51
62
|
},
|
|
52
63
|
"publishConfig": {
|
package/dist/index.d.mts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import * as vite0 from "vite";
|
|
2
|
-
import { HmrContext, ViteDevServer } from "vite";
|
|
3
|
-
|
|
4
|
-
//#region src/iframe-post-message.d.ts
|
|
5
|
-
type PostMessageType = "server-ready" | "all-routes" | "route-change" | "route-refresh";
|
|
6
|
-
interface PostMessage {
|
|
7
|
-
message: any;
|
|
8
|
-
type: PostMessageType;
|
|
9
|
-
}
|
|
10
|
-
interface RouteInfo {
|
|
11
|
-
name: string;
|
|
12
|
-
path: string;
|
|
13
|
-
file: string;
|
|
14
|
-
}
|
|
15
|
-
interface ServerReadyMessage extends PostMessage {
|
|
16
|
-
type: "server-ready";
|
|
17
|
-
message: {
|
|
18
|
-
satus: "ok";
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
interface AllRoutesMessage extends PostMessage {
|
|
22
|
-
type: "all-routes";
|
|
23
|
-
message: {
|
|
24
|
-
routes: RouteInfo[];
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
interface RouteChangeMessage extends PostMessage {
|
|
28
|
-
type: "route-change";
|
|
29
|
-
message: {
|
|
30
|
-
route: RouteInfo;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
interface RouteRefreshMessage extends PostMessage {
|
|
34
|
-
type: "route-refresh";
|
|
35
|
-
message: {
|
|
36
|
-
route: RouteInfo;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
declare class IframePostMessageClient {
|
|
40
|
-
authHost: string;
|
|
41
|
-
constructor();
|
|
42
|
-
_ensure_route_file(route: RouteInfo): void;
|
|
43
|
-
_send(message: PostMessage): void;
|
|
44
|
-
sendServerReady(): void;
|
|
45
|
-
sendAllRoutes(routes: RouteInfo[]): void;
|
|
46
|
-
sendRouteChange(route: RouteInfo): void;
|
|
47
|
-
sendRouteRefresh(route: RouteInfo): void;
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/hmr-events-plugin.d.ts
|
|
51
|
-
declare const HMREventsPlugin: () => {
|
|
52
|
-
name: string;
|
|
53
|
-
enforce: string;
|
|
54
|
-
resolveId(id: string): "virtual:hmr-events-plugin" | undefined;
|
|
55
|
-
load(id: string): string | undefined;
|
|
56
|
-
transformIndexHtml(html: string): {
|
|
57
|
-
html: string;
|
|
58
|
-
tags: {
|
|
59
|
-
tag: string;
|
|
60
|
-
injectTo: string;
|
|
61
|
-
type: string;
|
|
62
|
-
attrs: {
|
|
63
|
-
src: string;
|
|
64
|
-
type: string;
|
|
65
|
-
};
|
|
66
|
-
}[];
|
|
67
|
-
};
|
|
68
|
-
configureServer(server: ViteDevServer): void;
|
|
69
|
-
handleHotUpdate(ctx: HmrContext): vite0.ModuleNode[];
|
|
70
|
-
};
|
|
71
|
-
//#endregion
|
|
72
|
-
export { AllRoutesMessage, HMREventsPlugin, IframePostMessageClient, PostMessage, PostMessageType, RouteChangeMessage, RouteInfo, RouteRefreshMessage, ServerReadyMessage };
|
package/dist/index.mjs
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { fileURLToPath } from "url";
|
|
2
|
-
|
|
3
|
-
//#region src/iframe-post-message.ts
|
|
4
|
-
var IframePostMessageClient = class {
|
|
5
|
-
authHost;
|
|
6
|
-
constructor() {
|
|
7
|
-
if (!import.meta.env) throw new Error("import.meta.env is not defined");
|
|
8
|
-
const AUTH_HOST = import.meta.env.VITE_FRONT_URL;
|
|
9
|
-
this.authHost = AUTH_HOST.endsWith("/") ? AUTH_HOST.slice(0, -1) : AUTH_HOST;
|
|
10
|
-
}
|
|
11
|
-
_ensure_route_file(route) {
|
|
12
|
-
if (!route.file.startsWith("src")) throw Error(`Invalid route path, route path should be relative to the root got: ${route.file}`);
|
|
13
|
-
}
|
|
14
|
-
_send(message) {
|
|
15
|
-
window.parent.postMessage(message, this.authHost);
|
|
16
|
-
}
|
|
17
|
-
sendServerReady() {
|
|
18
|
-
this._send({
|
|
19
|
-
type: "server-ready",
|
|
20
|
-
message: { satus: "ok" }
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
sendAllRoutes(routes) {
|
|
24
|
-
for (let route of routes) this._ensure_route_file(route);
|
|
25
|
-
const message = {
|
|
26
|
-
type: "all-routes",
|
|
27
|
-
message: { routes }
|
|
28
|
-
};
|
|
29
|
-
this._send(message);
|
|
30
|
-
}
|
|
31
|
-
sendRouteChange(route) {
|
|
32
|
-
this._ensure_route_file(route);
|
|
33
|
-
const message = {
|
|
34
|
-
type: "route-change",
|
|
35
|
-
message: { route }
|
|
36
|
-
};
|
|
37
|
-
this._send(message);
|
|
38
|
-
}
|
|
39
|
-
sendRouteRefresh(route) {
|
|
40
|
-
this._ensure_route_file(route);
|
|
41
|
-
const message = {
|
|
42
|
-
type: "route-refresh",
|
|
43
|
-
message: { route }
|
|
44
|
-
};
|
|
45
|
-
this._send(message);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/hmr-events-plugin.ts
|
|
51
|
-
const HMREventsPlugin = () => {
|
|
52
|
-
return {
|
|
53
|
-
name: "hmr-events-plugin",
|
|
54
|
-
enforce: "pre",
|
|
55
|
-
resolveId(id) {
|
|
56
|
-
if (id === "virtual:hmr-events-plugin") return id;
|
|
57
|
-
},
|
|
58
|
-
load(id) {
|
|
59
|
-
if (id === "virtual:hmr-events-plugin") {
|
|
60
|
-
const runtimePath = fileURLToPath(new URL("./runtime/error-tracker", import.meta.url));
|
|
61
|
-
return `import ${JSON.stringify(runtimePath)};`;
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
transformIndexHtml(html) {
|
|
65
|
-
return {
|
|
66
|
-
html,
|
|
67
|
-
tags: [{
|
|
68
|
-
tag: "script",
|
|
69
|
-
injectTo: "body",
|
|
70
|
-
type: "module",
|
|
71
|
-
attrs: {
|
|
72
|
-
src: "/@id/virtual:hmr-events-plugin",
|
|
73
|
-
type: "module"
|
|
74
|
-
}
|
|
75
|
-
}]
|
|
76
|
-
};
|
|
77
|
-
},
|
|
78
|
-
configureServer(server) {
|
|
79
|
-
server.ws.on("breeze:beforeUpdate", (event) => {});
|
|
80
|
-
server.ws.on("breeze:afterUpdate", (event) => {
|
|
81
|
-
for (let eventMessage of event.data) console.log(eventMessage.message);
|
|
82
|
-
console.log("[breeze] end update");
|
|
83
|
-
});
|
|
84
|
-
},
|
|
85
|
-
handleHotUpdate(ctx) {
|
|
86
|
-
const { file, timestamp, read, server, modules } = ctx;
|
|
87
|
-
console.log(`[breeze] hmr update: ${file}`);
|
|
88
|
-
return modules;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
//#endregion
|
|
94
|
-
export { HMREventsPlugin, IframePostMessageClient };
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { ViteHook } from "./vite-hook";
|
|
2
|
-
import { ViteMessage } from "./vite-message";
|
|
3
|
-
|
|
4
|
-
interface LogEvent {
|
|
5
|
-
type: "logEvent";
|
|
6
|
-
logLevel: string;
|
|
7
|
-
timestamp: number;
|
|
8
|
-
message: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface UnhandledrejectionEvent {
|
|
12
|
-
type: "unhandledrejectionEvent";
|
|
13
|
-
message: string;
|
|
14
|
-
timestamp: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ErrorEvent {
|
|
18
|
-
type: "errorEvent";
|
|
19
|
-
lineno: number;
|
|
20
|
-
colno: number;
|
|
21
|
-
filename: string;
|
|
22
|
-
message: string;
|
|
23
|
-
timestamp: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
type Event = LogEvent | UnhandledrejectionEvent | ErrorEvent;
|
|
27
|
-
|
|
28
|
-
class ErrorTracker {
|
|
29
|
-
eventsQueue: Event[];
|
|
30
|
-
|
|
31
|
-
public vHook: ViteHook;
|
|
32
|
-
public viteMessage: ViteMessage;
|
|
33
|
-
|
|
34
|
-
constructor() {
|
|
35
|
-
this.eventsQueue = [];
|
|
36
|
-
|
|
37
|
-
this.viteMessage = new ViteMessage();
|
|
38
|
-
|
|
39
|
-
this.vHook = new ViteHook();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
isBlankScreen() {
|
|
43
|
-
const app = document.querySelector("div#app");
|
|
44
|
-
return app ? app.childElementCount === 0 : false;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
start() {
|
|
48
|
-
this.handleError();
|
|
49
|
-
this.handleUnhandledrejection();
|
|
50
|
-
this.consoleInterception();
|
|
51
|
-
|
|
52
|
-
let startTimestamp: number;
|
|
53
|
-
this.vHook.onBeforeUpdate((data, timestamp) => {
|
|
54
|
-
startTimestamp = timestamp;
|
|
55
|
-
this.viteMessage.sendBeforeUpdate(data);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
this.vHook.onError((data, timestamp) => {
|
|
59
|
-
console.debug(data);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
this.vHook.onAfterUpdate((data, timestamp) => {
|
|
63
|
-
setTimeout(() => {
|
|
64
|
-
const endTimestamp = Date.now();
|
|
65
|
-
|
|
66
|
-
let events = this.eventsQueue.filter(
|
|
67
|
-
(event) =>
|
|
68
|
-
event.timestamp >= startTimestamp &&
|
|
69
|
-
event.timestamp <= endTimestamp,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
this.viteMessage.sendAfterUpdate(events);
|
|
73
|
-
|
|
74
|
-
this.eventsQueue = [];
|
|
75
|
-
}, 5);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
consoleInterception() {
|
|
80
|
-
const originalConsole = {
|
|
81
|
-
log: console.log,
|
|
82
|
-
warn: console.warn,
|
|
83
|
-
error: console.error,
|
|
84
|
-
trace: console.trace,
|
|
85
|
-
// debug: console.debug,
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
for (let logLevel of Object.keys(originalConsole)) {
|
|
89
|
-
console[logLevel] = function (...args) {
|
|
90
|
-
const logArgumentsString = args.map((arg) => {
|
|
91
|
-
if (arg) {
|
|
92
|
-
return arg.toString();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
this.eventsQueue.push({
|
|
97
|
-
type: "logEvent",
|
|
98
|
-
logLevel,
|
|
99
|
-
timestamp: Date.now(),
|
|
100
|
-
message: logArgumentsString.join(" "),
|
|
101
|
-
});
|
|
102
|
-
originalConsole[logLevel].apply(this, args);
|
|
103
|
-
}.bind(this);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
handleUnhandledrejection() {
|
|
108
|
-
window.addEventListener("unhandledrejection", (evt) => {
|
|
109
|
-
console.debug(evt);
|
|
110
|
-
const UnhandledrejectionMessage = {
|
|
111
|
-
type: "unhandledrejectionEvent",
|
|
112
|
-
message: evt.reason.stack || evt.reason.message,
|
|
113
|
-
timestamp: Date.now(),
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
this.eventsQueue.push(UnhandledrejectionMessage);
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
handleError() {
|
|
121
|
-
window.addEventListener("error", (evt) => {
|
|
122
|
-
let message;
|
|
123
|
-
if (evt.error) {
|
|
124
|
-
message = evt.error.stack || evt.error.message;
|
|
125
|
-
} else {
|
|
126
|
-
message = evt.message;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
console.debug(evt);
|
|
130
|
-
const errorMessage = {
|
|
131
|
-
type: "errorEvent",
|
|
132
|
-
lineno: evt.lineno,
|
|
133
|
-
colno: evt.colno,
|
|
134
|
-
filename: evt.filename,
|
|
135
|
-
message: message,
|
|
136
|
-
timestamp: Date.now(),
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
this.eventsQueue.push(errorMessage);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// This handle the following kind of runtime error
|
|
143
|
-
// For now it's diffcult to know what to do because those errors are not sync with the HMR lifecyle
|
|
144
|
-
// Maybe use a queue
|
|
145
|
-
// <script setup lang="ts">
|
|
146
|
-
// import { onMounted } from 'vue';
|
|
147
|
-
|
|
148
|
-
// onMounted(() => {
|
|
149
|
-
// // This will trigger the error event because it happens at runtime
|
|
150
|
-
// setTimeout(() => {
|
|
151
|
-
// undefinedFunction(); // Runtime error - WILL trigger window.error
|
|
152
|
-
// }, 0);
|
|
153
|
-
// });
|
|
154
|
-
// </script>
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const tracker = new ErrorTracker();
|
|
159
|
-
tracker.start();
|
|
160
|
-
|
|
161
|
-
// HMR listening
|
|
162
|
-
// const handleMessage = (event) => {
|
|
163
|
-
// console.log(event);
|
|
164
|
-
// };
|
|
165
|
-
|
|
166
|
-
// window.addEventListener("message", handleMessage);
|
package/src/runtime/vite-hook.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ErrorPayload,
|
|
3
|
-
FullReloadPayload,
|
|
4
|
-
PrunePayload,
|
|
5
|
-
UpdatePayload,
|
|
6
|
-
} from "vite/types/hmrPayload.js";
|
|
7
|
-
import { ViteHotContext } from "vite/types/hot.js";
|
|
8
|
-
|
|
9
|
-
type ViteUpdateCallback =
|
|
10
|
-
| ((data: UpdatePayload, timestamp: number) => void)
|
|
11
|
-
| null;
|
|
12
|
-
|
|
13
|
-
type VitePruneCallback =
|
|
14
|
-
| ((data: PrunePayload, timestamp: number) => void)
|
|
15
|
-
| null;
|
|
16
|
-
|
|
17
|
-
type VitFullReloadCallback =
|
|
18
|
-
| ((data: FullReloadPayload, timestamp: number) => void)
|
|
19
|
-
| null;
|
|
20
|
-
|
|
21
|
-
type ViteErrorCallback =
|
|
22
|
-
| ((data: ErrorPayload, timestamp: number) => void)
|
|
23
|
-
| null;
|
|
24
|
-
|
|
25
|
-
type ViteInvalidateCallback = ((data: any, timestamp: number) => void) | null;
|
|
26
|
-
|
|
27
|
-
type ViteWebSocketConnectCallback =
|
|
28
|
-
| ((data: any, timestamp: number) => void)
|
|
29
|
-
| null;
|
|
30
|
-
|
|
31
|
-
type ViteWebSocketDisconnectCallback =
|
|
32
|
-
| ((data: any, timestamp: number) => void)
|
|
33
|
-
| null;
|
|
34
|
-
|
|
35
|
-
class ViteHook {
|
|
36
|
-
private hmr: ViteHotContext | undefined;
|
|
37
|
-
constructor() {
|
|
38
|
-
this.hmr = import.meta.hot;
|
|
39
|
-
}
|
|
40
|
-
hotExists(hmr: ViteHotContext | undefined): hmr is ViteHotContext {
|
|
41
|
-
if (hmr) return true;
|
|
42
|
-
console.error("HotContext does not exists");
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
onBeforeUpdate(fn: ViteUpdateCallback = null) {
|
|
47
|
-
if (!this.hotExists(this.hmr)) return;
|
|
48
|
-
|
|
49
|
-
this.hmr.on("vite:beforeUpdate", (data: UpdatePayload) => {
|
|
50
|
-
const timestamp = Date.now();
|
|
51
|
-
console.debug("beforeUpdate");
|
|
52
|
-
fn && fn(data, timestamp);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
onAfterUpdate(fn: ViteUpdateCallback = null) {
|
|
57
|
-
if (!this.hotExists(this.hmr)) return;
|
|
58
|
-
|
|
59
|
-
this.hmr.on("vite:afterUpdate", (data: UpdatePayload) => {
|
|
60
|
-
const timestamp = Date.now();
|
|
61
|
-
console.debug("afterUpdate");
|
|
62
|
-
fn && fn(data, timestamp);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
onBeforePrune(fn: VitePruneCallback = null) {
|
|
67
|
-
if (!this.hotExists(this.hmr)) return;
|
|
68
|
-
|
|
69
|
-
this.hmr.on("vite:beforePrune", (data: PrunePayload) => {
|
|
70
|
-
const timestamp = Date.now();
|
|
71
|
-
console.debug("beforePrune");
|
|
72
|
-
|
|
73
|
-
fn && fn(data, timestamp);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
onBeforeFullReload(fn: VitFullReloadCallback = null) {
|
|
78
|
-
if (!this.hotExists(this.hmr)) return;
|
|
79
|
-
|
|
80
|
-
this.hmr.on("vite:beforeFullReload", (data: FullReloadPayload) => {
|
|
81
|
-
const timestamp = Date.now();
|
|
82
|
-
console.debug("beforeFullReload");
|
|
83
|
-
|
|
84
|
-
fn && fn(data, timestamp);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
onError(fn: ViteErrorCallback = null) {
|
|
89
|
-
if (!this.hotExists(this.hmr)) return;
|
|
90
|
-
|
|
91
|
-
this.hmr.on("vite:error", (data: ErrorPayload) => {
|
|
92
|
-
const timestamp = Date.now();
|
|
93
|
-
console.debug("error");
|
|
94
|
-
|
|
95
|
-
fn && fn(data, timestamp);
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
onInvalidate(fn: ViteInvalidateCallback = null) {
|
|
100
|
-
if (!this.hotExists(this.hmr)) return;
|
|
101
|
-
|
|
102
|
-
this.hmr.on("vite:invalidate", (data: any) => {
|
|
103
|
-
const timestamp = Date.now();
|
|
104
|
-
console.debug("invalidate");
|
|
105
|
-
|
|
106
|
-
fn && fn(data, timestamp);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
onWsConnect(fn: ViteWebSocketConnectCallback = null) {
|
|
111
|
-
if (!this.hotExists(this.hmr)) return;
|
|
112
|
-
|
|
113
|
-
this.hmr.on("vite:ws:connect", (data: any) => {
|
|
114
|
-
const timestamp = Date.now();
|
|
115
|
-
console.debug("ws:connect");
|
|
116
|
-
|
|
117
|
-
fn && fn(data, timestamp);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
onWsDisconnect(fn: ViteWebSocketDisconnectCallback = null) {
|
|
122
|
-
if (!this.hotExists(this.hmr)) return;
|
|
123
|
-
|
|
124
|
-
this.hmr.on("vite:ws:disconnect", (data: any) => {
|
|
125
|
-
const timestamp = Date.now();
|
|
126
|
-
console.debug(":ws:disconnect");
|
|
127
|
-
|
|
128
|
-
fn && fn(data, timestamp);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export { ViteHook };
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { ViteHotContext } from "vite/types/hot.js";
|
|
2
|
-
|
|
3
|
-
interface MessageEvent {
|
|
4
|
-
type: "custom";
|
|
5
|
-
event: string;
|
|
6
|
-
data: any;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
enum MessageEventType {
|
|
10
|
-
BEFORE_UPDATE = "breeze:beforeUpdate",
|
|
11
|
-
AFTER_UPDATE = "breeze:afterUpdate",
|
|
12
|
-
ERROR = "breeze:error",
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
class ViteMessage {
|
|
16
|
-
private server: ViteHotContext | undefined;
|
|
17
|
-
|
|
18
|
-
constructor() {
|
|
19
|
-
this.server = import.meta.hot;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
hotExists(server: ViteHotContext | undefined): server is ViteHotContext {
|
|
23
|
-
if (server) return true;
|
|
24
|
-
console.error("HotContext does not exists");
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
send(event: string, message: MessageEvent) {
|
|
29
|
-
if (!this.hotExists(this.server)) return;
|
|
30
|
-
this.server.send(event, message);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
sendBeforeUpdate(data: any) {
|
|
34
|
-
if (!this.hotExists(this.server)) return;
|
|
35
|
-
this.server.send(MessageEventType.BEFORE_UPDATE, {
|
|
36
|
-
type: "custom",
|
|
37
|
-
event: MessageEventType.BEFORE_UPDATE,
|
|
38
|
-
data: data,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
sendError(data: any) {
|
|
43
|
-
if (!this.hotExists(this.server)) return;
|
|
44
|
-
this.server.send(MessageEventType.ERROR, {
|
|
45
|
-
type: "custom",
|
|
46
|
-
event: MessageEventType.ERROR,
|
|
47
|
-
data: data,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
sendAfterUpdate(data: any) {
|
|
52
|
-
if (!this.hotExists(this.server)) return;
|
|
53
|
-
this.server.send(MessageEventType.AFTER_UPDATE, {
|
|
54
|
-
type: "custom",
|
|
55
|
-
event: MessageEventType.AFTER_UPDATE,
|
|
56
|
-
data: data,
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export { ViteMessage };
|