@swf2es/desktop 0.1.15 → 0.1.16

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.
Files changed (52) hide show
  1. package/README.md +44 -11
  2. package/dist/launch/launch.js +4 -1
  3. package/dist/launch/launch.js.map +1 -1
  4. package/dist/main/main.js +66 -8
  5. package/dist/main/main.js.map +1 -1
  6. package/dist/main/netlog.d.ts +21 -0
  7. package/dist/main/netlog.d.ts.map +1 -0
  8. package/dist/main/netlog.js +90 -0
  9. package/dist/main/netlog.js.map +1 -0
  10. package/dist/main/sockets.d.ts +4 -2
  11. package/dist/main/sockets.d.ts.map +1 -1
  12. package/dist/main/sockets.js +15 -2
  13. package/dist/main/sockets.js.map +1 -1
  14. package/dist/main/websocket-connections.d.ts +62 -0
  15. package/dist/main/websocket-connections.d.ts.map +1 -0
  16. package/dist/main/websocket-connections.js +198 -0
  17. package/dist/main/websocket-connections.js.map +1 -0
  18. package/dist/main/websockets.d.ts +11 -0
  19. package/dist/main/websockets.d.ts.map +1 -0
  20. package/dist/main/websockets.js +93 -0
  21. package/dist/main/websockets.js.map +1 -0
  22. package/dist/preload/preload.cjs +20 -0
  23. package/dist/preload/preload.cjs.map +1 -1
  24. package/dist/renderer/air.d.ts.map +1 -1
  25. package/dist/renderer/air.js +1 -0
  26. package/dist/renderer/air.js.map +1 -1
  27. package/dist/renderer/full-screen.d.ts +4 -0
  28. package/dist/renderer/full-screen.d.ts.map +1 -0
  29. package/dist/renderer/full-screen.js +32 -0
  30. package/dist/renderer/full-screen.js.map +1 -0
  31. package/dist/renderer/index.d.ts.map +1 -1
  32. package/dist/renderer/index.js +4 -0
  33. package/dist/renderer/index.js.map +1 -1
  34. package/dist/renderer/websockets.d.ts +4 -0
  35. package/dist/renderer/websockets.d.ts.map +1 -0
  36. package/dist/renderer/websockets.js +36 -0
  37. package/dist/renderer/websockets.js.map +1 -0
  38. package/dist/shared/api.d.ts +53 -0
  39. package/dist/shared/api.d.ts.map +1 -1
  40. package/package.json +7 -7
  41. package/src/launch/launch.ts +5 -2
  42. package/src/main/main.ts +88 -9
  43. package/src/main/netlog.ts +108 -0
  44. package/src/main/sockets.ts +17 -1
  45. package/src/main/websocket-connections.ts +264 -0
  46. package/src/main/websockets.ts +115 -0
  47. package/src/preload/preload.cts +23 -0
  48. package/src/renderer/air.ts +1 -0
  49. package/src/renderer/full-screen.ts +44 -0
  50. package/src/renderer/index.ts +4 -0
  51. package/src/renderer/websockets.ts +43 -0
  52. package/src/shared/api.ts +40 -0
@@ -4,8 +4,10 @@
4
4
  import { configure } from "@swf2es/web";
5
5
  import { airHosts, airPath } from "./air.js";
6
6
  import { shellFiles } from "./files.js";
7
+ import { windowFullScreen } from "./full-screen.js";
7
8
  import { shellFetch } from "./network.js";
8
9
  import { shellSocketHost } from "./sockets.js";
10
+ import { shellWebSocketHost } from "./websockets.js";
9
11
  const desktop = window.swf2esDesktop;
10
12
  /** The AIR application playing, whose local URLs are read through the shell; null for a SWF. */
11
13
  let airLaunch = null;
@@ -13,6 +15,7 @@ configure({
13
15
  cache: true,
14
16
  fileHost: shellFiles(desktop.files),
15
17
  sockets: shellSocketHost(desktop.sockets),
18
+ webSockets: shellWebSocketHost(desktop.webSockets),
16
19
  fetch: shellFetch(desktop.network, () => {
17
20
  const launch = airLaunch;
18
21
  return launch
@@ -23,6 +26,7 @@ configure({
23
26
  : null;
24
27
  }),
25
28
  loadPolicyFile: (url) => desktop.network.loadPolicyFile(url),
29
+ fullScreen: windowFullScreen(desktop.fullScreen),
26
30
  });
27
31
  const byId = (id) => document.getElementById(id);
28
32
  const player = byId("player");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { WebSocketHost } from "@swf2es/player";
2
+ import type { DesktopWebSockets } from "../shared/api.js";
3
+ export declare function shellWebSocketHost(webSockets: DesktopWebSockets): WebSocketHost;
4
+ //# sourceMappingURL=websockets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websockets.d.ts","sourceRoot":"","sources":["../../src/renderer/websockets.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,GAAG,aAAa,CAoC/E"}
@@ -0,0 +1,36 @@
1
+ export function shellWebSocketHost(webSockets) {
2
+ // Until its close, which the shell sends after a failure too.
3
+ const open = new Map();
4
+ webSockets.onEvent((id, event) => {
5
+ const events = open.get(id);
6
+ if (!events) {
7
+ return;
8
+ }
9
+ switch (event.type) {
10
+ case "open":
11
+ events.open(event.protocol);
12
+ break;
13
+ case "message":
14
+ events.message(event.data);
15
+ break;
16
+ case "error":
17
+ events.error();
18
+ break;
19
+ case "close":
20
+ open.delete(id);
21
+ events.close(event.code);
22
+ break;
23
+ }
24
+ });
25
+ return {
26
+ connect(url, protocols, events) {
27
+ const id = webSockets.connect(url, protocols);
28
+ open.set(id, events);
29
+ return {
30
+ send: (data) => webSockets.send(id, data),
31
+ close: (code) => webSockets.close(id, code),
32
+ };
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=websockets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websockets.js","sourceRoot":"","sources":["../../src/renderer/websockets.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,kBAAkB,CAAC,UAA6B;IAC9D,8DAA8D;IAC9D,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;IAChD,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM;YACR,KAAK,OAAO;gBACV,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzB,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM;YAC5B,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACrB,OAAO;gBACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;gBACzC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC;aAC5C,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -50,6 +50,23 @@ export interface AirWindowState {
50
50
  active: boolean;
51
51
  visible: boolean;
52
52
  }
53
+ /** One of the system's displays as flash.display.Screen reads it: all of it, and what a window may fill. */
54
+ export interface AirScreenState {
55
+ bounds: {
56
+ x: number;
57
+ y: number;
58
+ width: number;
59
+ height: number;
60
+ };
61
+ visibleBounds: {
62
+ x: number;
63
+ y: number;
64
+ width: number;
65
+ height: number;
66
+ };
67
+ colorDepth: number;
68
+ main: boolean;
69
+ }
53
70
  /**
54
71
  * An AIR application's own reach, only while one the user opened plays:
55
72
  * the file system, read and written synchronously as File does, and the
@@ -72,6 +89,8 @@ export interface DesktopAir {
72
89
  remove(path: string): boolean;
73
90
  move(from: string, to: string): boolean;
74
91
  window(): AirWindowState;
92
+ /** The displays as they are now; none where no application plays. */
93
+ screens(): AirScreenState[];
75
94
  setBounds(bounds: {
76
95
  x: number;
77
96
  y: number;
@@ -136,6 +155,28 @@ export interface DesktopSockets {
136
155
  close(id: number): void;
137
156
  onEvent(listener: (id: number, event: SocketEvent) => void): void;
138
157
  }
158
+ /** What befalls a WebSocket, as player's WebSocketEvents has it. */
159
+ export type WebSocketEvent = {
160
+ type: "open";
161
+ protocol: string;
162
+ } | {
163
+ type: "message";
164
+ data: string | Uint8Array;
165
+ } | {
166
+ type: "close";
167
+ code: number;
168
+ } | {
169
+ type: "error";
170
+ };
171
+ /** air.net.WebSocket's connections, opened by the shell, for an AIR application alone. */
172
+ export interface DesktopWebSockets {
173
+ /** A connection's id; its events follow, an "error" then a "close" if the shell refuses it. */
174
+ connect(url: string, protocols: string[]): number;
175
+ /** A text message for a string, a binary one for bytes. */
176
+ send(id: number, data: string | Uint8Array): void;
177
+ close(id: number, code?: number): void;
178
+ onEvent(listener: (id: number, event: WebSocketEvent) => void): void;
179
+ }
139
180
  /** A request of a SWF's, as player's FetchRequest has it. */
140
181
  export interface NetworkRequest {
141
182
  url: string;
@@ -182,8 +223,19 @@ export interface DesktopFiles {
182
223
  write(id: number, bytes: Uint8Array): Promise<void>;
183
224
  release(id: number): void;
184
225
  }
226
+ /**
227
+ * The window's full screen, which a SWF's Stage.displayState asks for
228
+ * while one the user opened plays, with no gesture, as AIR's and the
229
+ * projector's did.
230
+ */
231
+ export interface DesktopFullScreen {
232
+ set(fullScreen: boolean): void;
233
+ /** The window has entered or left full screen, a SWF's doing or the user's (F11). */
234
+ onChange(listener: (fullScreen: boolean) => void): void;
235
+ }
185
236
  export interface DesktopApi {
186
237
  files: DesktopFiles;
238
+ fullScreen: DesktopFullScreen;
187
239
  /** The page has loaded and listens: what it is to show. */
188
240
  start(): Promise<StartState>;
189
241
  /** The shell opened a SWF: play it in place of what plays. */
@@ -199,6 +251,7 @@ export interface DesktopApi {
199
251
  /** Ask the user for a library; the page reloads once the shell has it. */
200
252
  chooseLibrary(name: LibraryName): void;
201
253
  sockets: DesktopSockets;
254
+ webSockets: DesktopWebSockets;
202
255
  network: DesktopNetwork;
203
256
  air: DesktopAir;
204
257
  }
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/shared/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/shared/api.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swf2es/desktop",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "swf2es's desktop app: local and remote SWFs, and AIR applications, in an Electron window",
5
5
  "keywords": [
6
6
  "swf",
@@ -35,12 +35,12 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "electron": "44.10.2",
38
- "@swf2es/codegen": "0.1.15",
39
- "@swf2es/format": "0.1.15",
40
- "@swf2es/context3d": "0.1.15",
41
- "@swf2es/player": "0.1.15",
42
- "@swf2es/player-hosts": "0.1.15",
43
- "@swf2es/web": "0.1.15"
38
+ "@swf2es/context3d": "0.1.16",
39
+ "@swf2es/format": "0.1.16",
40
+ "@swf2es/codegen": "0.1.16",
41
+ "@swf2es/player": "0.1.16",
42
+ "@swf2es/web": "0.1.16",
43
+ "@swf2es/player-hosts": "0.1.16"
44
44
  },
45
45
  "scripts": {
46
46
  "fetch-electron": "node node_modules/electron/install.js",
@@ -3,7 +3,7 @@
3
3
  // swf2es-desktop command of the package npm installs, and a checkout's
4
4
  // `start`.
5
5
  //
6
- // npx @swf2es/desktop [--trace] [file.swf | https://host/movie.swf]
6
+ // npx @swf2es/desktop [--trace] [--log-network] [file.swf | https://host/movie.swf]
7
7
  // npx @swf2es/desktop [--trace] app.xml [root-dir] [-- arguments...]
8
8
  // pnpm --filter @swf2es/desktop start ... the same, in a checkout
9
9
  //
@@ -64,7 +64,10 @@ if (!build || appRoot.includes(`${join("node_modules", "@swf2es")}`)) {
64
64
  build = JSON.parse(readFileSync(join(appRoot, "package.json"), "utf8")).version;
65
65
  }
66
66
 
67
- const env = { ...process.env, SWF2ES_DESKTOP_BUILD: build };
67
+ const env: NodeJS.ProcessEnv = { ...process.env, SWF2ES_DESKTOP_BUILD: build };
68
+ // Set by tools that are Electron apps themselves, an editor's terminals and tasks among them,
69
+ // for the node they run: here it would make Electron run the app's main module as plain node.
70
+ delete env.ELECTRON_RUN_AS_NODE;
68
71
  const child = spawn(electronBinary() as string, [appRoot, ...args], { stdio: "inherit", env });
69
72
  child.on("exit", (code, signal) => process.exit(signal ? 1 : (code ?? 0)));
70
73
  for (const signal of ["SIGINT", "SIGTERM"] as const) {
package/src/main/main.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  // electron apps/desktop [--trace] [file.swf | http(s)://host/movie.swf]
6
6
  // electron apps/desktop [--trace] app.xml [root-dir] [-- arguments...]
7
7
  //
8
- // --ignore-certificate-errors[=host,...] leaves HTTPS certificates unchecked.
8
+ // --ignore-certificate-errors[=host,...] leaves HTTPS and WSS certificates unchecked.
9
9
  //
10
10
  // The second runs an AIR application by its descriptor, as adl does.
11
11
  import { statSync } from "node:fs";
@@ -23,11 +23,13 @@ import {
23
23
  Menu,
24
24
  type MenuItemConstructorOptions,
25
25
  safeStorage,
26
+ screen,
26
27
  session,
27
28
  shell,
28
29
  type WebContents,
29
30
  } from "electron";
30
31
  import type {
32
+ AirScreenState,
31
33
  AirWindowState,
32
34
  LibraryName,
33
35
  NetworkResponse,
@@ -48,11 +50,14 @@ import {
48
50
  writeOf,
49
51
  } from "./air.ts";
50
52
  import { bridgeFiles } from "./files.ts";
53
+ import { failureLine, requestLine } from "./netlog.ts";
51
54
  import { type Movie, Network, Refused, unverifiedHosts } from "./network.ts";
52
55
  import { APP_ORIGIN, registerScheme, serve } from "./protocol.ts";
53
56
  import { Sandbox } from "./sandbox.ts";
54
57
  import { SettingsFile } from "./settings.ts";
55
58
  import { bridgeSockets } from "./sockets.ts";
59
+ import { hasWebSocket, unverifiedDispatcher, webSocketOpener } from "./websocket-connections.ts";
60
+ import { bridgeWebSockets } from "./websockets.ts";
56
61
 
57
62
  const preload = fileURLToPath(new URL("../preload/preload.cjs", import.meta.url));
58
63
  const promptPreload = fileURLToPath(new URL("../preload/prompt.cjs", import.meta.url));
@@ -77,6 +82,11 @@ app.enableSandbox();
77
82
 
78
83
  /** --trace: what the page logs, a SWF's trace() among it, goes to the terminal. */
79
84
  const trace = process.argv.includes("--trace");
85
+ // Each request and socket of the SWF's said on stderr: the page's DevTools show none of them.
86
+ // --log-sockets says what each socket sends and receives as well, and so the rest too.
87
+ const logSockets = process.argv.includes("--log-sockets");
88
+ const logNetwork = logSockets || process.argv.includes("--log-network");
89
+ const netLog = logNetwork ? (line: string) => process.stderr.write(`${line}\n`) : null;
80
90
  const sandbox = new Sandbox();
81
91
  /** The SWF's http and https requests, judged as Flash's sandboxes had them. */
82
92
  /**
@@ -89,15 +99,23 @@ const unverified = unverifiedHosts(process.argv.slice(1));
89
99
  if (unverified) {
90
100
  process.stderr.write(
91
101
  unverified.all
92
- ? "swf2es: --ignore-certificate-errors: no HTTPS server's certificate is verified\n"
102
+ ? "swf2es: --ignore-certificate-errors: no HTTPS or WSS server's certificate is verified\n"
93
103
  : `swf2es: --ignore-certificate-errors: certificates are not verified for ${unverified.hosts.join(", ") || "no host"}\n`,
94
104
  );
95
105
  }
96
106
 
97
- const network = new Network({
98
- unverified: (host) =>
99
- !!unverified && (unverified.all || unverified.hosts.includes(host.toLowerCase())),
100
- });
107
+ const unverifiedHost = (host: string) =>
108
+ !!unverified && (unverified.all || unverified.hosts.includes(host.toLowerCase()));
109
+ const network = new Network({ unverified: unverifiedHost });
110
+ // What opens an AIR application's WebSockets: the global's client, a wss: server's certificate
111
+ // unchecked where the switch names its host.
112
+ const insecureWebSockets = unverified ? unverifiedDispatcher() : null;
113
+ if (unverified && !insecureWebSockets) {
114
+ process.stderr.write(
115
+ "swf2es: --ignore-certificate-errors: a WebSocket's certificate is verified all the same\n",
116
+ );
117
+ }
118
+
101
119
  /** What the page's requests under way abort with, by the preload's number. */
102
120
  const requests = new Map<number, AbortController>();
103
121
  let settings: SettingsFile;
@@ -560,6 +578,23 @@ async function askForSocket(name: string, swf: string, endpoint: string): Promis
560
578
  }
561
579
  }
562
580
 
581
+ /**
582
+ * Whether what plays may open a WebSocket to `url`: an AIR application,
583
+ * unasked and anywhere, as AIR's application sandbox connects and as its
584
+ * sockets do here. air.net.WebSocket is AIR's alone, so nothing else has one.
585
+ */
586
+ function permitWebSocket(url: string): boolean {
587
+ if (sandbox.application && hasWebSocket()) {
588
+ return true;
589
+ }
590
+
591
+ const why = sandbox.application
592
+ ? "this Electron has no WebSocket client"
593
+ : "only an AIR application has one";
594
+ process.stderr.write(`swf2es: no WebSocket to ${url.slice(0, 2048)}: ${why}\n`);
595
+ return false;
596
+ }
597
+
563
598
  async function showOpenDialog(): Promise<void> {
564
599
  if (!window) {
565
600
  return;
@@ -800,6 +835,9 @@ function createWindow(): void {
800
835
  window.on("closed", () => {
801
836
  window = null;
802
837
  });
838
+ // The page hears of full screen however it came, a SWF's Stage.displayState or the menu's F11.
839
+ window.on("enter-full-screen", () => window?.webContents.send("desktop:full-screen", true));
840
+ window.on("leave-full-screen", () => window?.webContents.send("desktop:full-screen", false));
803
841
  guard(window.webContents);
804
842
  void window.loadURL(`${APP_ORIGIN}/`);
805
843
  }
@@ -831,6 +869,12 @@ function listen(): void {
831
869
  build,
832
870
  };
833
871
  });
872
+ // Stage.displayState of a SWF the user opened: the window's full screen, asked with no gesture.
873
+ ipcMain.on("desktop:full-screen", (event, fullScreen: unknown) => {
874
+ if (trusted(event) && current && window) {
875
+ window.setFullScreen(fullScreen === true);
876
+ }
877
+ });
834
878
  ipcMain.on("desktop:open-dialog", (event) => {
835
879
  if (trusted(event)) {
836
880
  void showOpenDialog();
@@ -869,7 +913,14 @@ function listen(): void {
869
913
  void chooseLibrary(name);
870
914
  }
871
915
  });
872
- bridgeSockets(trusted, permitSocket);
916
+ bridgeSockets(trusted, permitSocket, netLog, logSockets);
917
+ bridgeWebSockets(
918
+ trusted,
919
+ permitWebSocket,
920
+ insecureWebSockets ? webSocketOpener(unverifiedHost, insecureWebSockets) : undefined,
921
+ netLog,
922
+ logSockets,
923
+ );
873
924
  ipcMain.handle("net:fetch", (event, id: unknown, request: unknown) => {
874
925
  if (!trusted(event) || typeof id !== "number") {
875
926
  throw new Error("not the app's page");
@@ -917,6 +968,17 @@ function windowState(w: BrowserWindow): AirWindowState {
917
968
  };
918
969
  }
919
970
 
971
+ /** The displays as an AIR application's Screen reads them: the work area is past the system's bars. */
972
+ function screenStates(): AirScreenState[] {
973
+ const primary = screen.getPrimaryDisplay().id;
974
+ return screen.getAllDisplays().map((display) => ({
975
+ bounds: display.bounds,
976
+ visibleBounds: display.workArea,
977
+ colorDepth: display.colorDepth,
978
+ main: display.id === primary,
979
+ }));
980
+ }
981
+
920
982
  /**
921
983
  * An AIR application's reach, shared/api.ts DesktopAir: the file system
922
984
  * and the window, only while one the user opened plays and only for its
@@ -999,6 +1061,9 @@ function listenForAir(): void {
999
1061
  ipcMain.on("air:window", (event) => {
1000
1062
  event.returnValue = playing(event) && window ? windowState(window) : null;
1001
1063
  });
1064
+ ipcMain.on("air:screens", (event) => {
1065
+ event.returnValue = playing(event) ? screenStates() : [];
1066
+ });
1002
1067
  ipcMain.on("air:set-bounds", (event, bounds: unknown) => {
1003
1068
  const b = bounds as { x?: unknown; y?: unknown; width?: unknown; height?: unknown } | null;
1004
1069
  const n = (v: unknown) => (typeof v === "number" && Number.isFinite(v) ? Math.round(v) : null);
@@ -1068,7 +1133,7 @@ async function fetchForPage(
1068
1133
  request: unknown,
1069
1134
  deliver: (response: NetworkResponse) => void,
1070
1135
  ): Promise<NetworkResponse> {
1071
- const asked = request as { url?: unknown; purpose?: unknown } | null;
1136
+ const asked = request as { url?: unknown; purpose?: unknown; method?: unknown } | null;
1072
1137
  const url = typeof asked?.url === "string" ? asked.url : "";
1073
1138
  const shown = url.slice(0, 2048);
1074
1139
  const movie = asked?.purpose === "movie" && sandbox.startRemote(url);
@@ -1079,13 +1144,27 @@ async function fetchForPage(
1079
1144
 
1080
1145
  const controller = new AbortController();
1081
1146
  requests.set(id, controller);
1147
+ const started = performance.now();
1148
+ const method = typeof asked?.method === "string" ? asked.method.slice(0, 16) : "GET";
1082
1149
  try {
1083
- return await network.fetch(request, controller.signal, deliver);
1150
+ const response = await network.fetch(request, controller.signal, deliver);
1151
+ netLog?.(
1152
+ requestLine(
1153
+ method,
1154
+ url,
1155
+ response.status,
1156
+ response.bytes?.length ?? null,
1157
+ performance.now() - started,
1158
+ ),
1159
+ );
1160
+ return response;
1084
1161
  } catch (error) {
1085
1162
  // A refusal says why; anything else, which should not happen, is said too.
1086
1163
  if (!controller.signal.aborted) {
1087
1164
  const why = error instanceof Refused ? error.message : `failed: ${error}`;
1088
1165
  process.stderr.write(`swf2es: not loading ${shown}: ${why}\n`);
1166
+ } else {
1167
+ netLog?.(failureLine(method, url, "aborted", performance.now() - started));
1089
1168
  }
1090
1169
 
1091
1170
  throw error;
@@ -0,0 +1,108 @@
1
+ // --log-network's lines: what a SWF asked of the network, as the terminal
2
+ // shows it. The page has no network of its own, so its DevTools' Network
3
+ // tab shows none of this; the main process, which sends the requests, says
4
+ // them here instead. Apart from Electron, so that node tests it.
5
+
6
+ /** A size as a person reads it: bytes, then kB and MB to one decimal. */
7
+ function size(bytes: number): string {
8
+ if (bytes < 1024) {
9
+ return `${bytes} B`;
10
+ }
11
+
12
+ return bytes < 1024 * 1024
13
+ ? `${(bytes / 1024).toFixed(1)} kB`
14
+ : `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
15
+ }
16
+
17
+ /** A URL short enough for a line, and with nothing a terminal would act on. */
18
+ function shown(url: string): string {
19
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is taken out
20
+ return url.slice(0, 2048).replace(/[\u0000-\u001f\u007f]/g, "?");
21
+ }
22
+
23
+ /** A request answered: its method, URL, status, body's size and how long it took. */
24
+ export function requestLine(
25
+ method: string,
26
+ url: string,
27
+ status: number,
28
+ bytes: number | null,
29
+ ms: number,
30
+ ): string {
31
+ const body = bytes === null ? "no body" : size(bytes);
32
+ return `swf2es: net ${method} ${shown(url)} ${status} ${body} ${Math.round(ms)} ms`;
33
+ }
34
+
35
+ /** A request that got no answer: refused, failed or aborted, and why. */
36
+ export function failureLine(method: string, url: string, why: string, ms: number): string {
37
+ return `swf2es: net ${method} ${shown(url)} ${why} ${Math.round(ms)} ms`;
38
+ }
39
+
40
+ /** A socket's connection asked for, opened, refused or closed. */
41
+ export function socketLine(id: number, what: string): string {
42
+ return `swf2es: socket #${id} ${shown(what)}`;
43
+ }
44
+
45
+ /** How much of a message --log-sockets shows. */
46
+ const PREVIEW = 512;
47
+
48
+ /** The start of `bytes`: as text where it is text, bytes that are no printable ASCII as dots, else in hex. */
49
+ function preview(bytes: Uint8Array): string {
50
+ const shownBytes = bytes.subarray(0, PREVIEW);
51
+ let printable = 0;
52
+ for (let i = 0; i < shownBytes.length; i++) {
53
+ const b = shownBytes[i];
54
+ if ((b >= 32 && b < 127) || b === 9 || b === 10 || b === 13 || b === 0) {
55
+ printable++;
56
+ }
57
+ }
58
+
59
+ let text = "";
60
+ // Mostly text, as a line protocol's messages are, a NUL ending each: shown as text.
61
+ if (printable * 10 >= shownBytes.length * 9) {
62
+ for (let i = 0; i < shownBytes.length; i++) {
63
+ const b = shownBytes[i];
64
+ text += b >= 32 && b < 127 ? String.fromCharCode(b) : ".";
65
+ }
66
+ } else {
67
+ for (let i = 0; i < shownBytes.length; i++) {
68
+ text += (i > 0 ? " " : "") + shownBytes[i].toString(16).padStart(2, "0");
69
+ }
70
+ }
71
+
72
+ return text + (bytes.length > PREVIEW ? "…" : "");
73
+ }
74
+
75
+ /**
76
+ * What a socket sent (">") or received ("<"): its size and its start, as
77
+ * text where it is text, bytes that are no printable ASCII as dots, else
78
+ * in hex. A message past PREVIEW bytes ends in an ellipsis.
79
+ */
80
+ export function socketDataLine(id: number, sent: boolean, bytes: Uint8Array): string {
81
+ return `swf2es: socket #${id} ${sent ? ">" : "<"} ${bytes.length} B ${preview(bytes)}`;
82
+ }
83
+
84
+ /** A WebSocket's connection asked for, opened, refused, failed or closed. */
85
+ export function webSocketLine(id: number, what: string): string {
86
+ return `swf2es: websocket #${id} ${shown(what)}`;
87
+ }
88
+
89
+ /**
90
+ * What a WebSocket sent (">") or received ("<"): a text message's size
91
+ * in UTF-8 and its first PREVIEW characters, control characters as dots;
92
+ * a binary one's as a socket's.
93
+ */
94
+ export function webSocketDataLine(id: number, sent: boolean, data: string | Uint8Array): string {
95
+ const head = `swf2es: websocket #${id} ${sent ? ">" : "<"}`;
96
+ if (typeof data !== "string") {
97
+ return `${head} binary ${data.length} B ${preview(data)}`;
98
+ }
99
+
100
+ // By code point, so that no pair is cut in two.
101
+ const characters = Array.from(data.slice(0, PREVIEW * 2)).slice(0, PREVIEW);
102
+ const text = characters
103
+ .join("")
104
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is taken out
105
+ .replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g, ".");
106
+ const more = text.length < data.length ? "…" : "";
107
+ return `${head} text ${Buffer.byteLength(data)} B ${text}${more}`;
108
+ }
@@ -3,15 +3,20 @@
3
3
  // connections (connections.ts) close as it navigates, reloads or goes.
4
4
  import { type IpcMainEvent, ipcMain, type WebContents } from "electron";
5
5
  import { Connections, validEndpoint } from "./connections.ts";
6
+ import { socketDataLine, socketLine } from "./netlog.ts";
6
7
 
7
8
  /**
8
9
  * Carry socket messages from pages that `trusted` accepts, each connection
9
10
  * made only as `permit` allows it, to the address it gives where it gives
10
- * one; null refuses it.
11
+ * one; null refuses it. `log`, where given, is told each connection asked
12
+ * for, opened, refused, failed and closed (--log-network), and with
13
+ * `data` what each sends and receives too (--log-sockets).
11
14
  */
12
15
  export function bridgeSockets(
13
16
  trusted: (event: IpcMainEvent) => boolean,
14
17
  permit: (host: string, port: number) => Promise<{ address?: string } | null>,
18
+ log: ((line: string) => void) | null = null,
19
+ data = false,
15
20
  ): void {
16
21
  const pages = new Map<WebContents, Connections>();
17
22
 
@@ -22,6 +27,12 @@ export function bridgeSockets(
22
27
  }
23
28
 
24
29
  const connections = new Connections((id, event) => {
30
+ if (log && event.type !== "data") {
31
+ log(socketLine(id, event.type === "error" ? `error: ${event.message}` : event.type));
32
+ } else if (log && data && event.type === "data") {
33
+ log(socketDataLine(id, false, event.bytes));
34
+ }
35
+
25
36
  if (!contents.isDestroyed()) {
26
37
  contents.send("socket:event", id, event);
27
38
  }
@@ -59,6 +70,7 @@ export function bridgeSockets(
59
70
  return;
60
71
  }
61
72
 
73
+ log?.(socketLine(id, `${allowed ? "connecting to" : "refused"} ${host}:${port}`));
62
74
  if (allowed) {
63
75
  connections.connect(id, host, port, allowed.address);
64
76
  } else {
@@ -69,6 +81,10 @@ export function bridgeSockets(
69
81
 
70
82
  ipcMain.on("socket:send", (event, id: unknown, bytes: unknown) => {
71
83
  if (trusted(event) && typeof id === "number" && bytes instanceof Uint8Array) {
84
+ if (log && data) {
85
+ log(socketDataLine(id, true, bytes));
86
+ }
87
+
72
88
  pages.get(event.sender)?.send(id, bytes);
73
89
  }
74
90
  });