process.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.ProcessRunner = void 0;
  6. var _utils = require("playwright-core/lib/utils");
  7. var _util = require("../util");
  8. var _esmLoaderHost = require("./esmLoaderHost");
  9. var _esmUtils = require("../transform/esmUtils");
  10. /**
  11. * Copyright Microsoft Corporation. All rights reserved.
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the "License");
  14. * you may not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * http://www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS,
  21. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. */
  25. class ProcessRunner {
  26. async gracefullyClose() {}
  27. dispatchEvent(method, params) {
  28. const response = {
  29. method,
  30. params
  31. };
  32. sendMessageToParent({
  33. method: '__dispatch__',
  34. params: response
  35. });
  36. }
  37. }
  38. exports.ProcessRunner = ProcessRunner;
  39. let closed = false;
  40. sendMessageToParent({
  41. method: 'ready'
  42. });
  43. process.on('disconnect', gracefullyCloseAndExit);
  44. process.on('SIGINT', () => {});
  45. process.on('SIGTERM', () => {});
  46. // Clear execArgv immediately, so that the user-code does not inherit our loader.
  47. process.execArgv = (0, _esmUtils.execArgvWithoutExperimentalLoaderOptions)();
  48. // Node.js >= 20
  49. if (process.env.PW_TS_ESM_LOADER_ON) (0, _esmLoaderHost.registerESMLoader)();
  50. let processRunner;
  51. let processName;
  52. const startingEnv = {
  53. ...process.env
  54. };
  55. process.on('message', async message => {
  56. if (message.method === '__init__') {
  57. const {
  58. processParams,
  59. runnerParams,
  60. runnerScript
  61. } = message.params;
  62. setTtyParams(process.stdout, processParams.stdoutParams);
  63. setTtyParams(process.stderr, processParams.stderrParams);
  64. void (0, _utils.startProfiling)();
  65. const {
  66. create
  67. } = require(runnerScript);
  68. processRunner = create(runnerParams);
  69. processName = processParams.processName;
  70. return;
  71. }
  72. if (message.method === '__stop__') {
  73. const keys = new Set([...Object.keys(process.env), ...Object.keys(startingEnv)]);
  74. const producedEnv = [...keys].filter(key => startingEnv[key] !== process.env[key]).map(key => {
  75. var _process$env$key;
  76. return [key, (_process$env$key = process.env[key]) !== null && _process$env$key !== void 0 ? _process$env$key : null];
  77. });
  78. sendMessageToParent({
  79. method: '__env_produced__',
  80. params: producedEnv
  81. });
  82. await gracefullyCloseAndExit();
  83. return;
  84. }
  85. if (message.method === '__dispatch__') {
  86. const {
  87. id,
  88. method,
  89. params
  90. } = message.params;
  91. try {
  92. const result = await processRunner[method](params);
  93. const response = {
  94. id,
  95. result
  96. };
  97. sendMessageToParent({
  98. method: '__dispatch__',
  99. params: response
  100. });
  101. } catch (e) {
  102. const response = {
  103. id,
  104. error: (0, _util.serializeError)(e)
  105. };
  106. sendMessageToParent({
  107. method: '__dispatch__',
  108. params: response
  109. });
  110. }
  111. }
  112. });
  113. async function gracefullyCloseAndExit() {
  114. var _processRunner;
  115. if (closed) return;
  116. closed = true;
  117. // Force exit after 30 seconds.
  118. // eslint-disable-next-line no-restricted-properties
  119. setTimeout(() => process.exit(0), 30000);
  120. // Meanwhile, try to gracefully shutdown.
  121. await ((_processRunner = processRunner) === null || _processRunner === void 0 ? void 0 : _processRunner.gracefullyClose().catch(() => {}));
  122. if (processName) await (0, _utils.stopProfiling)(processName).catch(() => {});
  123. // eslint-disable-next-line no-restricted-properties
  124. process.exit(0);
  125. }
  126. function sendMessageToParent(message) {
  127. try {
  128. process.send(message);
  129. } catch (e) {
  130. // Can throw when closing.
  131. }
  132. }
  133. function setTtyParams(stream, params) {
  134. stream.isTTY = true;
  135. if (params.rows) stream.rows = params.rows;
  136. if (params.columns) stream.columns = params.columns;
  137. stream.getColorDepth = () => params.colorDepth;
  138. stream.hasColors = (count = 16) => {
  139. // count is optional and the first argument may actually be env.
  140. if (typeof count !== 'number') count = 16;
  141. return count <= 2 ** params.colorDepth;
  142. };
  143. }