@open-wxa/wxa-runner-core 0.12.0 → 0.12.2

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.
@@ -348,6 +348,7 @@ ${frames}` : "");
348
348
  "rmdir",
349
349
  "getFileInfo",
350
350
  "copyFile",
351
+ "rename",
351
352
  "readFile"
352
353
  ]) {
353
354
  const handler = (args, { api }) => {
@@ -752,6 +753,7 @@ ${frames}` : "");
752
753
  function createNetworkApis(options) {
753
754
  const controllers = /* @__PURE__ */ new Map();
754
755
  const sockets = /* @__PURE__ */ new Map();
756
+ const pendingSockets = /* @__PURE__ */ new Set();
755
757
  const { emit } = options;
756
758
  const startTask = (args, run) => {
757
759
  const id = String(++taskSeq);
@@ -889,17 +891,42 @@ ${frames}` : "");
889
891
  const socketTaskId = String(++taskSeq);
890
892
  let socket;
891
893
  try {
892
- socket = new WebSocket(args.url, args.protocols && args.protocols.length ? args.protocols : void 0);
894
+ if (options.socketProxy) {
895
+ const url = new URL("/__wxa__/socket", location.href);
896
+ url.protocol = location.protocol === "https:" ? "wss:" : "ws:";
897
+ socket = new WebSocket(url);
898
+ pendingSockets.add(socketTaskId);
899
+ } else socket = new WebSocket(args.url, args.protocols && args.protocols.length ? args.protocols : void 0);
893
900
  } catch (error) {
894
901
  return fail(api, reason(error));
895
902
  }
896
903
  socket.binaryType = "arraybuffer";
897
904
  sockets.set(socketTaskId, socket);
898
- socket.onopen = () => emit("onSocketTaskStateChange", { socketTaskId, state: "open", header: {}, profile: {} });
899
- socket.onmessage = (event) => emit("onSocketTaskStateChange", { socketTaskId, state: "message", data: event.data });
900
- socket.onerror = () => emit("onSocketTaskStateChange", { socketTaskId, state: "error", errMsg: "connectSocket:fail" });
905
+ let failed = false;
906
+ const onError = () => {
907
+ failed = true;
908
+ emit("onSocketTaskStateChange", { socketTaskId, state: "error", errMsg: "connectSocket:fail" });
909
+ };
910
+ socket.onopen = () => {
911
+ if (options.socketProxy) socket.send(JSON.stringify({
912
+ url: args.url,
913
+ header: args.header,
914
+ protocols: args.protocols,
915
+ timeout: args.timeout || options.defaultSocketTimeout?.() || 6e4
916
+ }));
917
+ else emit("onSocketTaskStateChange", { socketTaskId, state: "open", header: {}, profile: {} });
918
+ };
919
+ socket.onmessage = (event) => {
920
+ if (pendingSockets.has(socketTaskId)) {
921
+ const result = JSON.parse(event.data);
922
+ pendingSockets.delete(socketTaskId);
923
+ emit("onSocketTaskStateChange", { socketTaskId, state: "open", header: result.header, profile: {} });
924
+ } else emit("onSocketTaskStateChange", { socketTaskId, state: "message", data: event.data });
925
+ };
926
+ socket.onerror = onError;
901
927
  socket.onclose = (event) => {
902
928
  sockets.delete(socketTaskId);
929
+ if (pendingSockets.delete(socketTaskId) && !failed) onError();
903
930
  emit("onSocketTaskStateChange", { socketTaskId, state: "close", code: event.code, reason: event.reason });
904
931
  };
905
932
  return ok(api, { socketTaskId });
@@ -908,7 +935,7 @@ ${frames}` : "");
908
935
  const socket = sockets.get(String(args.socketTaskId));
909
936
  if (!socket) return fail(api, "socket task not found");
910
937
  if (args.operationType === "send") {
911
- if (socket.readyState !== WebSocket.OPEN) return fail(api, "socket is not open");
938
+ if (pendingSockets.has(String(args.socketTaskId)) || socket.readyState !== WebSocket.OPEN) return fail(api, "socket is not open");
912
939
  socket.send(args.data);
913
940
  } else if (args.operationType === "close") {
914
941
  socket.close(args.code || 1e3, args.reason);
@@ -1769,6 +1796,7 @@ ${frames}` : "");
1769
1796
  function iframeWebViews(doc) {
1770
1797
  return Array.from(doc?.querySelectorAll("iframe[data-wxa-src]") ?? []).map((frame) => ({ src: frame.dataset.wxaSrc, windowName: null }));
1771
1798
  }
1799
+ var COMMIT_WAIT_MS = 5e3;
1772
1800
  var WebViewWindows = class {
1773
1801
  /** @param isShown 页面当前是否显示:隐藏的页面先记下地址,显示时再打开窗口 */
1774
1802
  constructor(device, isShown) {
@@ -1847,14 +1875,36 @@ ${frames}` : "");
1847
1875
  open(record) {
1848
1876
  if (!record.src) return;
1849
1877
  if (record.win && !record.win.closed) {
1850
- record.win.location.href = record.src;
1878
+ this.navigate(record);
1851
1879
  } else {
1852
1880
  const features = `popup,width=${this.device.screenWidth},height=${this.device.screenHeight}`;
1853
1881
  record.win = window.open(record.src, record.name, features);
1854
- if (record.win) notify("open", record.name, record.src);
1882
+ if (record.win) {
1883
+ record.opening = { src: record.src, at: Date.now() };
1884
+ notify("open", record.name, record.src);
1885
+ }
1855
1886
  }
1856
1887
  this.render(record);
1857
1888
  }
1889
+ /**
1890
+ * 已打开的窗口跳到最新的 src。用已有的引用跳转,不靠窗口名:网页可能改了自己的 window.name,按名字找不到时会多开一个窗口。
1891
+ *
1892
+ * Chrome 里新窗口的初始页面还没提交时改它的地址,这次跳转偶尔会被丢掉,窗口停在原来的网页上(不经过 CDP 也一样)。
1893
+ * 窗口刚打开就改 src 会碰上,所以等初始页面提交后再跳
1894
+ */
1895
+ navigate(record) {
1896
+ const win = record.win;
1897
+ if (!win || win.closed || !record.src || record.retry !== void 0) return;
1898
+ if (record.opening && !committed(win, record.opening.src) && Date.now() - record.opening.at < COMMIT_WAIT_MS) {
1899
+ record.retry = window.setTimeout(() => {
1900
+ record.retry = void 0;
1901
+ this.navigate(record);
1902
+ }, 20);
1903
+ return;
1904
+ }
1905
+ record.opening = void 0;
1906
+ win.location.href = record.src;
1907
+ }
1858
1908
  render(record) {
1859
1909
  const opened = record.win && !record.win.closed;
1860
1910
  const [title, detail] = !record.src ? ["web-view \u8FD8\u6CA1\u6709\u8BBE\u7F6E src", ""] : opened ? ["H5 \u5DF2\u5728\u65B0\u7A97\u53E3\u6253\u5F00", record.src] : record.win === null && this.isShown(record.webviewId) ? ["\u6D4F\u89C8\u5668\u62E6\u622A\u4E86\u5F39\u51FA\u7A97\u53E3\uFF0C\u70B9\u4E0B\u9762\u7684\u6309\u94AE\u6253\u5F00 H5", record.src] : ["H5 \u5728\u65B0\u7A97\u53E3\u6253\u5F00", record.src];
@@ -1869,7 +1919,17 @@ ${frames}` : "");
1869
1919
  function windowName(webviewId, htmlId) {
1870
1920
  return `wxa-h5-${webviewId}-${htmlId}`;
1871
1921
  }
1922
+ function committed(win, src) {
1923
+ try {
1924
+ return win.location.href !== "about:blank" || src === "about:blank";
1925
+ } catch {
1926
+ return true;
1927
+ }
1928
+ }
1872
1929
  function close(record) {
1930
+ clearTimeout(record.retry);
1931
+ record.retry = void 0;
1932
+ record.opening = void 0;
1873
1933
  if (!record.win) return;
1874
1934
  record.win.close();
1875
1935
  record.win = null;
@@ -3135,6 +3195,8 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
3135
3195
  screenTop: () => this.shell.screenTop()
3136
3196
  }),
3137
3197
  ...createNetworkApis({
3198
+ socketProxy: this.info.socketProxy,
3199
+ defaultSocketTimeout: () => this.info.wxConfig.networkTimeout?.connectSocket || 6e4,
3138
3200
  emit: (event, data) => this.emitToService(event, data),
3139
3201
  defaultTimeout: () => this.info.wxConfig.networkTimeout?.request || 6e4,
3140
3202
  routes: this.routes,