@jsenv/terminal-recorder 1.5.15 → 1.5.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/terminal-recorder",
3
- "version": "1.5.15",
3
+ "version": "1.5.17",
4
4
  "description": "Record terminal output as .svg, .gif, .webm, .mp4",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,7 +20,7 @@
20
20
  ".": {
21
21
  "node": "./src/main.js",
22
22
  "browser": {
23
- "development": "./src/main_browser.js",
23
+ "dev:jsenv": "./src/main_browser.js",
24
24
  "default": "./dist/terminal_recorder_browser.js"
25
25
  }
26
26
  },
@@ -37,8 +37,8 @@
37
37
  "prepublishOnly": "npm run build"
38
38
  },
39
39
  "dependencies": {
40
- "@jsenv/humanize": "1.5.0",
41
- "@jsenv/server": "16.0.8",
40
+ "@jsenv/humanize": "1.5.2",
41
+ "@jsenv/server": "16.1.2",
42
42
  "@playwright/browser-chromium": "1.51.1",
43
43
  "@jsenv/terminal-text-size": "0.0.1",
44
44
  "ansi-regex": "6.1.0",
@@ -0,0 +1,132 @@
1
+ const css = /* css */ `
2
+ dialog {
3
+ opacity: 0;
4
+ transition: all 0.3s allow-discrete;
5
+ }
6
+ dialog::backdrop {
7
+ background-image: linear-gradient(
8
+ 45deg,
9
+ magenta,
10
+ rebeccapurple,
11
+ dodgerblue,
12
+ green
13
+ );
14
+ opacity: 0;
15
+ transition: all 0.3s allow-discrete;
16
+ }
17
+ dialog:open {
18
+ opacity: 1;
19
+ }
20
+ dialog:open::backdrop {
21
+ opacity: 0.75;
22
+ }`;
23
+
24
+ const html = /* html */ `<style>
25
+ ${css}
26
+ </style>
27
+ <dialog>
28
+ <p>Connection with server is lost</p>
29
+ <button autofocus name="reconnect">Retry</button>
30
+ </dialog>`;
31
+
32
+ class JsenvAutoreloadOnServerRestart extends HTMLElement {
33
+ constructor({ url } = {}) {
34
+ super();
35
+ const root = this.attachShadow({ mode: "open" });
36
+ root.innerHTML = html;
37
+
38
+ const dialog = root.querySelector("dialog");
39
+ const reconnectButton = dialog.querySelector('button[name="reconnect"]');
40
+
41
+ (async () => {
42
+ const connect = () => {
43
+ const websocket = new WebSocket(url);
44
+ const connectedPromise = new Promise((resolve) => {
45
+ websocket.onerror = () => {
46
+ resolve(null);
47
+ };
48
+ websocket.onopen = () => {
49
+ resolve(websocket);
50
+ };
51
+ });
52
+ return connectedPromise;
53
+ };
54
+
55
+ const initialWebSocket = await connect();
56
+ if (!initialWebSocket) {
57
+ return;
58
+ }
59
+ initialWebSocket.onclose = async () => {
60
+ console.info("connection to server lost, trying to reconnect");
61
+ const retry = async () => {
62
+ let attemptCount = 0;
63
+ let timeToWait = 100;
64
+ const tryToReconnect = async () => {
65
+ const newWebsocket = await connect();
66
+ if (newWebsocket) {
67
+ dialog.close();
68
+ console.info("reconnected to server, reloading the page...");
69
+ window.location.reload(true);
70
+ return;
71
+ }
72
+ attemptCount++;
73
+ if (attemptCount === 10) {
74
+ dialog.showModal();
75
+ reconnectButton.onclick = async () => {
76
+ reconnectButton.disabled = true;
77
+ const previousContext = reconnectButton.textContent;
78
+ reconnectButton.textContent = "Retrying...";
79
+ await retry();
80
+ reconnectButton.textContent = previousContext;
81
+ reconnectButton.disabled = false;
82
+ };
83
+ return;
84
+ }
85
+ timeToWait += 100;
86
+ await new Promise((resolve) => setTimeout(resolve, timeToWait));
87
+ await tryToReconnect();
88
+ };
89
+ await tryToReconnect();
90
+ };
91
+ retry();
92
+ };
93
+ })();
94
+ }
95
+ }
96
+ if (!customElements.get("jsenv-autoreload-on-server-restart")) {
97
+ customElements.define(
98
+ "jsenv-autoreload-on-server-restart",
99
+ JsenvAutoreloadOnServerRestart,
100
+ );
101
+ }
102
+
103
+ const websocketEndpoint =
104
+ document.currentScript.getAttribute("data-ws-endpoint") ||
105
+ "/.internal/alive.websocket";
106
+
107
+ const jsenvAutoreloadOnServerRestartElement =
108
+ new JsenvAutoreloadOnServerRestart({
109
+ url: (() => {
110
+ const websocketScheme =
111
+ self.location.protocol === "https:" ? "wss" : "ws";
112
+ const websocketUrl = `${websocketScheme}://${self.location.host}${websocketEndpoint}`;
113
+ return websocketUrl;
114
+ })(),
115
+ });
116
+
117
+ // script is injected into document.body
118
+ if (document.body) {
119
+ document.currentScript.parentNode.replaceChild(
120
+ jsenvAutoreloadOnServerRestartElement,
121
+ document.currentScript,
122
+ );
123
+ }
124
+ // script injected outisde document.body (likely in head)
125
+ else {
126
+ document.currentScript.parentNode.removeChild(document.currentScript);
127
+ document.onreadystatechange = () => {
128
+ if (document.readyState === "interactive") {
129
+ document.body.appendChild(jsenvAutoreloadOnServerRestartElement);
130
+ }
131
+ };
132
+ }
@@ -28,7 +28,8 @@
28
28
  ]
29
29
  });
30
30
  </script>
31
- </jsenv-scripts>
31
+ <script src="/@fs/Users/dmail/Documents/dev/core/packages/independent/backend/server/src/services/autoreload_on_server_restart/client/autoreload_on_server_restart.js" jsenv-injected-by="jsenv:autoreload_on_server_restart" data-ws-endpoint="/.internal/events.websocket"></script>
32
+ </jsenv-scripts>
32
33
 
33
34
 
34
35
 
@@ -1,6 +1,5 @@
1
1
  import { ANSI, UNICODE } from "@jsenv/humanize";
2
2
  import { spawn } from "node:child_process";
3
-
4
3
  import { startTerminalRecording } from "./terminal_recording.js";
5
4
 
6
5
  export const recordCommandToSvg = async (
@@ -12,11 +12,15 @@
12
12
  // import prettier from "prettier";
13
13
  import { renderTerminalSvg } from "./svg/render_terminal_svg.js";
14
14
 
15
- const isDev = process.execArgv.includes("--conditions=development");
15
+ const isDev = process.execArgv.some(
16
+ (arg) =>
17
+ arg.includes("--conditions=development") ||
18
+ arg.includes("--conditions=dev:"),
19
+ );
16
20
 
17
21
  const startLocalServer = async () => {
18
22
  if (isDev) {
19
- const serverDirectoryUrl = new URL("./client/", import.meta.url);
23
+ const serverDirectoryUrl = import.meta.resolve("./client/");
20
24
  const { startDevServer } = await import("@jsenv/core");
21
25
  const devServer = await startDevServer({
22
26
  logLevel: "warn",
@@ -30,7 +34,7 @@ const startLocalServer = async () => {
30
34
  return devServer;
31
35
  }
32
36
 
33
- const serverDirectoryUrl = new URL("../dist/", import.meta.url);
37
+ const serverDirectoryUrl = import.meta.resolve("../dist/");
34
38
  const { startServer, createFileSystemFetch } = await import("@jsenv/server");
35
39
  const server = await startServer({
36
40
  logLevel: "warn",
@@ -87,9 +91,13 @@ export const startTerminalRecording = async ({
87
91
  page.on("pageerror", (error) => {
88
92
  throw error;
89
93
  });
90
- page.on("console", (consoleMessage) => {
94
+ const onConsole = (consoleMessage) => {
91
95
  console.log(`browser> ${consoleMessage.text()}`);
96
+ };
97
+ stopCallbackSet.add(() => {
98
+ page.off("console", onConsole);
92
99
  });
100
+ page.on("console", onConsole);
93
101
  await page.goto(`${server.origin}/xterm.html`);
94
102
  await page.evaluate(
95
103
  /* eslint-disable no-undef */