@jsenv/core 38.3.11 → 38.4.1

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 (118) hide show
  1. package/README.md +17 -18
  2. package/dist/babel_helpers/AsyncGenerator/AsyncGenerator.js +3 -3
  3. package/dist/babel_helpers/AwaitValue/AwaitValue.js +2 -2
  4. package/dist/babel_helpers/{overloadYield/overloadYield.js → OverloadYield/OverloadYield.js} +1 -1
  5. package/dist/babel_helpers/applyDecoratedDescriptor/applyDecoratedDescriptor.js +23 -14
  6. package/dist/babel_helpers/applyDecs/applyDecs.js +32 -21
  7. package/dist/babel_helpers/applyDecs2203/applyDecs2203.js +549 -549
  8. package/dist/babel_helpers/applyDecs2203R/applyDecs2203R.js +27 -15
  9. package/dist/babel_helpers/applyDecs2301/applyDecs2301.js +29 -18
  10. package/dist/babel_helpers/applyDecs2305/applyDecs2305.js +362 -541
  11. package/dist/babel_helpers/arrayLikeToArray/arrayLikeToArray.js +4 -4
  12. package/dist/babel_helpers/arrayWithHoles/arrayWithHoles.js +2 -2
  13. package/dist/babel_helpers/arrayWithoutHoles/arrayWithoutHoles.js +3 -3
  14. package/dist/babel_helpers/assertThisInitialized/assertThisInitialized.js +5 -3
  15. package/dist/babel_helpers/asyncGeneratorDelegate/asyncGeneratorDelegate.js +2 -2
  16. package/dist/babel_helpers/asyncIterator/asyncIterator.js +1 -1
  17. package/dist/babel_helpers/asyncToGenerator/asyncToGenerator.js +17 -17
  18. package/dist/babel_helpers/awaitAsyncGenerator/awaitAsyncGenerator.js +2 -2
  19. package/dist/babel_helpers/callSuper/callSuper.js +25 -0
  20. package/dist/babel_helpers/checkInRHS/checkInRHS.js +10 -8
  21. package/dist/babel_helpers/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +9 -6
  22. package/dist/babel_helpers/classApplyDescriptorGet/classApplyDescriptorGet.js +2 -2
  23. package/dist/babel_helpers/classApplyDescriptorSet/classApplyDescriptorSet.js +3 -3
  24. package/dist/babel_helpers/classCallCheck/classCallCheck.js +1 -1
  25. package/dist/babel_helpers/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -2
  26. package/dist/babel_helpers/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +7 -2
  27. package/dist/babel_helpers/classExtractFieldDescriptor/classExtractFieldDescriptor.js +9 -3
  28. package/dist/babel_helpers/classNameTDZError/classNameTDZError.js +3 -1
  29. package/dist/babel_helpers/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +4 -4
  30. package/dist/babel_helpers/classPrivateFieldGet/classPrivateFieldGet.js +4 -4
  31. package/dist/babel_helpers/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +2 -2
  32. package/dist/babel_helpers/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +2 -2
  33. package/dist/babel_helpers/classPrivateFieldSet/classPrivateFieldSet.js +5 -5
  34. package/dist/babel_helpers/classPrivateMethodGet/classPrivateMethodGet.js +2 -2
  35. package/dist/babel_helpers/classPrivateMethodSet/classPrivateMethodSet.js +1 -1
  36. package/dist/babel_helpers/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +11 -7
  37. package/dist/babel_helpers/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +7 -7
  38. package/dist/babel_helpers/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +8 -4
  39. package/dist/babel_helpers/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +1 -1
  40. package/dist/babel_helpers/construct/construct.js +18 -14
  41. package/dist/babel_helpers/createClass/createClass.js +1 -1
  42. package/dist/babel_helpers/createForOfIteratorHelper/createForOfIteratorHelper.js +21 -20
  43. package/dist/babel_helpers/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +10 -9
  44. package/dist/babel_helpers/createRawReactElement/createRawReactElement.js +11 -11
  45. package/dist/babel_helpers/createSuper/createSuper.js +11 -11
  46. package/dist/babel_helpers/decorate/decorate.js +255 -170
  47. package/dist/babel_helpers/defaults/defaults.js +5 -5
  48. package/dist/babel_helpers/defineAccessor/defineAccessor.js +1 -1
  49. package/dist/babel_helpers/defineEnumerableProperties/defineEnumerableProperties.js +11 -11
  50. package/dist/babel_helpers/defineProperty/defineProperty.js +4 -4
  51. package/dist/babel_helpers/dispose/dispose.js +39 -39
  52. package/dist/babel_helpers/extends/extends.js +4 -4
  53. package/dist/babel_helpers/get/get.js +2 -2
  54. package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +1 -1
  55. package/dist/babel_helpers/identity/identity.js +1 -1
  56. package/dist/babel_helpers/importDeferProxy/importDeferProxy.js +27 -27
  57. package/dist/babel_helpers/inherits/inherits.js +4 -4
  58. package/dist/babel_helpers/inheritsLoose/inheritsLoose.js +4 -4
  59. package/dist/babel_helpers/initializerDefineProperty/initializerDefineProperty.js +5 -3
  60. package/dist/babel_helpers/initializerWarningHelper/initializerWarningHelper.js +1 -1
  61. package/dist/babel_helpers/instanceof/instanceof.js +7 -3
  62. package/dist/babel_helpers/interopRequireDefault/interopRequireDefault.js +1 -1
  63. package/dist/babel_helpers/interopRequireWildcard/interopRequireWildcard.js +3 -1
  64. package/dist/babel_helpers/isNativeFunction/isNativeFunction.js +1 -1
  65. package/dist/babel_helpers/isNativeReflectConstruct/isNativeReflectConstruct.js +12 -14
  66. package/dist/babel_helpers/iterableToArray/iterableToArray.js +1 -1
  67. package/dist/babel_helpers/iterableToArrayLimit/iterableToArrayLimit.js +1 -1
  68. package/dist/babel_helpers/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +1 -1
  69. package/dist/babel_helpers/jsx/jsx.js +1 -1
  70. package/dist/babel_helpers/maybeArrayLike/maybeArrayLike.js +4 -4
  71. package/dist/babel_helpers/newArrowCheck/newArrowCheck.js +1 -1
  72. package/dist/babel_helpers/nonIterableRest/nonIterableRest.js +2 -2
  73. package/dist/babel_helpers/nonIterableSpread/nonIterableSpread.js +2 -2
  74. package/dist/babel_helpers/nullishReceiverError/nullishReceiverError.js +1 -1
  75. package/dist/babel_helpers/objectDestructuringEmpty/objectDestructuringEmpty.js +1 -1
  76. package/dist/babel_helpers/objectSpread/objectSpread.js +8 -8
  77. package/dist/babel_helpers/objectSpread2/objectSpread2.js +5 -3
  78. package/dist/babel_helpers/objectWithoutProperties/objectWithoutProperties.js +12 -12
  79. package/dist/babel_helpers/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +10 -10
  80. package/dist/babel_helpers/possibleConstructorReturn/possibleConstructorReturn.js +7 -5
  81. package/dist/babel_helpers/readOnlyError/readOnlyError.js +1 -1
  82. package/dist/babel_helpers/regeneratorRuntime/regeneratorRuntime.js +1 -1
  83. package/dist/babel_helpers/set/set.js +22 -19
  84. package/dist/babel_helpers/setFunctionName/setFunctionName.js +18 -0
  85. package/dist/babel_helpers/setPrototypeOf/setPrototypeOf.js +7 -6
  86. package/dist/babel_helpers/skipFirstGeneratorNext/skipFirstGeneratorNext.js +4 -4
  87. package/dist/babel_helpers/slicedToArray/slicedToArray.js +5 -5
  88. package/dist/babel_helpers/slicedToArrayLoose/slicedToArrayLoose.js +5 -5
  89. package/dist/babel_helpers/superPropBase/superPropBase.js +4 -4
  90. package/dist/babel_helpers/taggedTemplateLiteral/taggedTemplateLiteral.js +2 -2
  91. package/dist/babel_helpers/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +3 -3
  92. package/dist/babel_helpers/tdz/tdz.js +1 -1
  93. package/dist/babel_helpers/temporalRef/temporalRef.js +3 -3
  94. package/dist/babel_helpers/toArray/toArray.js +5 -5
  95. package/dist/babel_helpers/toConsumableArray/toConsumableArray.js +5 -5
  96. package/dist/babel_helpers/toPrimitive/toPrimitive.js +11 -7
  97. package/dist/babel_helpers/toPropertyKey/toPropertyKey.js +8 -4
  98. package/dist/babel_helpers/typeof/typeof.js +6 -5
  99. package/dist/babel_helpers/unsupportedIterableToArray/unsupportedIterableToArray.js +7 -7
  100. package/dist/babel_helpers/using/using.js +20 -20
  101. package/dist/babel_helpers/wrapAsyncGenerator/wrapAsyncGenerator.js +3 -3
  102. package/dist/babel_helpers/wrapNativeSuper/wrapNativeSuper.js +12 -12
  103. package/dist/babel_helpers/wrapRegExp/wrapRegExp.js +5 -3
  104. package/dist/babel_helpers/writeOnlyError/writeOnlyError.js +1 -1
  105. package/dist/js/ribbon.js +1 -1
  106. package/dist/js/ws.js +234 -146
  107. package/dist/jsenv_core.js +1365 -1211
  108. package/package.json +26 -22
  109. package/src/build/build.js +22 -14
  110. package/src/dev/start_dev_server.js +8 -21
  111. package/src/kitchen/errors.js +29 -24
  112. package/src/kitchen/kitchen.js +1 -1
  113. package/src/kitchen/url_graph/references.js +8 -0
  114. package/src/kitchen/url_graph/url_graph_report.js +5 -3
  115. package/src/plugins/plugins.js +2 -2
  116. package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +17 -7
  117. package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +10 -12
  118. package/src/plugins/ribbon/client/ribbon.js +1 -1
package/dist/js/ws.js CHANGED
@@ -890,7 +890,7 @@ const GET_PAYLOAD_LENGTH_64 = 2;
890
890
  const GET_MASK = 3;
891
891
  const GET_DATA = 4;
892
892
  const INFLATING = 5;
893
- const WAIT_MICROTASK = 6;
893
+ const DEFER_EVENT = 6;
894
894
 
895
895
  /**
896
896
  * HyBi Receiver implementation.
@@ -902,6 +902,9 @@ let Receiver$1 = class Receiver extends Writable {
902
902
  * Creates a Receiver instance.
903
903
  *
904
904
  * @param {Object} [options] Options object
905
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
906
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
907
+ * multiple times in the same tick
905
908
  * @param {String} [options.binaryType=nodebuffer] The type for binary data
906
909
  * @param {Object} [options.extensions] An object containing the negotiated
907
910
  * extensions
@@ -914,6 +917,7 @@ let Receiver$1 = class Receiver extends Writable {
914
917
  constructor(options = {}) {
915
918
  super();
916
919
 
920
+ this._allowSynchronousEvents = !!options.allowSynchronousEvents;
917
921
  this._binaryType = options.binaryType || BINARY_TYPES$1[0];
918
922
  this._extensions = options.extensions || {};
919
923
  this._isServer = !!options.isServer;
@@ -936,8 +940,9 @@ let Receiver$1 = class Receiver extends Writable {
936
940
  this._messageLength = 0;
937
941
  this._fragments = [];
938
942
 
939
- this._state = GET_INFO;
943
+ this._errored = false;
940
944
  this._loop = false;
945
+ this._state = GET_INFO;
941
946
  }
942
947
 
943
948
  /**
@@ -1009,53 +1014,42 @@ let Receiver$1 = class Receiver extends Writable {
1009
1014
  * @private
1010
1015
  */
1011
1016
  startLoop(cb) {
1012
- let err;
1013
1017
  this._loop = true;
1014
1018
 
1015
1019
  do {
1016
1020
  switch (this._state) {
1017
1021
  case GET_INFO:
1018
- err = this.getInfo();
1022
+ this.getInfo(cb);
1019
1023
  break;
1020
1024
  case GET_PAYLOAD_LENGTH_16:
1021
- err = this.getPayloadLength16();
1025
+ this.getPayloadLength16(cb);
1022
1026
  break;
1023
1027
  case GET_PAYLOAD_LENGTH_64:
1024
- err = this.getPayloadLength64();
1028
+ this.getPayloadLength64(cb);
1025
1029
  break;
1026
1030
  case GET_MASK:
1027
1031
  this.getMask();
1028
1032
  break;
1029
1033
  case GET_DATA:
1030
- err = this.getData(cb);
1034
+ this.getData(cb);
1031
1035
  break;
1032
1036
  case INFLATING:
1037
+ case DEFER_EVENT:
1033
1038
  this._loop = false;
1034
1039
  return;
1035
- default:
1036
- //
1037
- // `WAIT_MICROTASK`.
1038
- //
1039
- this._loop = false;
1040
-
1041
- queueTask(() => {
1042
- this._state = GET_INFO;
1043
- this.startLoop(cb);
1044
- });
1045
- return;
1046
1040
  }
1047
1041
  } while (this._loop);
1048
1042
 
1049
- cb(err);
1043
+ if (!this._errored) cb();
1050
1044
  }
1051
1045
 
1052
1046
  /**
1053
1047
  * Reads the first two bytes of a frame.
1054
1048
  *
1055
- * @return {(RangeError|undefined)} A possible error
1049
+ * @param {Function} cb Callback
1056
1050
  * @private
1057
1051
  */
1058
- getInfo() {
1052
+ getInfo(cb) {
1059
1053
  if (this._bufferedBytes < 2) {
1060
1054
  this._loop = false;
1061
1055
  return;
@@ -1064,27 +1058,31 @@ let Receiver$1 = class Receiver extends Writable {
1064
1058
  const buf = this.consume(2);
1065
1059
 
1066
1060
  if ((buf[0] & 0x30) !== 0x00) {
1067
- this._loop = false;
1068
- return error(
1061
+ const error = this.createError(
1069
1062
  RangeError,
1070
1063
  'RSV2 and RSV3 must be clear',
1071
1064
  true,
1072
1065
  1002,
1073
1066
  'WS_ERR_UNEXPECTED_RSV_2_3'
1074
1067
  );
1068
+
1069
+ cb(error);
1070
+ return;
1075
1071
  }
1076
1072
 
1077
1073
  const compressed = (buf[0] & 0x40) === 0x40;
1078
1074
 
1079
1075
  if (compressed && !this._extensions[PerMessageDeflate$3.extensionName]) {
1080
- this._loop = false;
1081
- return error(
1076
+ const error = this.createError(
1082
1077
  RangeError,
1083
1078
  'RSV1 must be clear',
1084
1079
  true,
1085
1080
  1002,
1086
1081
  'WS_ERR_UNEXPECTED_RSV_1'
1087
1082
  );
1083
+
1084
+ cb(error);
1085
+ return;
1088
1086
  }
1089
1087
 
1090
1088
  this._fin = (buf[0] & 0x80) === 0x80;
@@ -1093,86 +1091,100 @@ let Receiver$1 = class Receiver extends Writable {
1093
1091
 
1094
1092
  if (this._opcode === 0x00) {
1095
1093
  if (compressed) {
1096
- this._loop = false;
1097
- return error(
1094
+ const error = this.createError(
1098
1095
  RangeError,
1099
1096
  'RSV1 must be clear',
1100
1097
  true,
1101
1098
  1002,
1102
1099
  'WS_ERR_UNEXPECTED_RSV_1'
1103
1100
  );
1101
+
1102
+ cb(error);
1103
+ return;
1104
1104
  }
1105
1105
 
1106
1106
  if (!this._fragmented) {
1107
- this._loop = false;
1108
- return error(
1107
+ const error = this.createError(
1109
1108
  RangeError,
1110
1109
  'invalid opcode 0',
1111
1110
  true,
1112
1111
  1002,
1113
1112
  'WS_ERR_INVALID_OPCODE'
1114
1113
  );
1114
+
1115
+ cb(error);
1116
+ return;
1115
1117
  }
1116
1118
 
1117
1119
  this._opcode = this._fragmented;
1118
1120
  } else if (this._opcode === 0x01 || this._opcode === 0x02) {
1119
1121
  if (this._fragmented) {
1120
- this._loop = false;
1121
- return error(
1122
+ const error = this.createError(
1122
1123
  RangeError,
1123
1124
  `invalid opcode ${this._opcode}`,
1124
1125
  true,
1125
1126
  1002,
1126
1127
  'WS_ERR_INVALID_OPCODE'
1127
1128
  );
1129
+
1130
+ cb(error);
1131
+ return;
1128
1132
  }
1129
1133
 
1130
1134
  this._compressed = compressed;
1131
1135
  } else if (this._opcode > 0x07 && this._opcode < 0x0b) {
1132
1136
  if (!this._fin) {
1133
- this._loop = false;
1134
- return error(
1137
+ const error = this.createError(
1135
1138
  RangeError,
1136
1139
  'FIN must be set',
1137
1140
  true,
1138
1141
  1002,
1139
1142
  'WS_ERR_EXPECTED_FIN'
1140
1143
  );
1144
+
1145
+ cb(error);
1146
+ return;
1141
1147
  }
1142
1148
 
1143
1149
  if (compressed) {
1144
- this._loop = false;
1145
- return error(
1150
+ const error = this.createError(
1146
1151
  RangeError,
1147
1152
  'RSV1 must be clear',
1148
1153
  true,
1149
1154
  1002,
1150
1155
  'WS_ERR_UNEXPECTED_RSV_1'
1151
1156
  );
1157
+
1158
+ cb(error);
1159
+ return;
1152
1160
  }
1153
1161
 
1154
1162
  if (
1155
1163
  this._payloadLength > 0x7d ||
1156
1164
  (this._opcode === 0x08 && this._payloadLength === 1)
1157
1165
  ) {
1158
- this._loop = false;
1159
- return error(
1166
+ const error = this.createError(
1160
1167
  RangeError,
1161
1168
  `invalid payload length ${this._payloadLength}`,
1162
1169
  true,
1163
1170
  1002,
1164
1171
  'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'
1165
1172
  );
1173
+
1174
+ cb(error);
1175
+ return;
1166
1176
  }
1167
1177
  } else {
1168
- this._loop = false;
1169
- return error(
1178
+ const error = this.createError(
1170
1179
  RangeError,
1171
1180
  `invalid opcode ${this._opcode}`,
1172
1181
  true,
1173
1182
  1002,
1174
1183
  'WS_ERR_INVALID_OPCODE'
1175
1184
  );
1185
+
1186
+ cb(error);
1187
+ return;
1176
1188
  }
1177
1189
 
1178
1190
  if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
@@ -1180,54 +1192,58 @@ let Receiver$1 = class Receiver extends Writable {
1180
1192
 
1181
1193
  if (this._isServer) {
1182
1194
  if (!this._masked) {
1183
- this._loop = false;
1184
- return error(
1195
+ const error = this.createError(
1185
1196
  RangeError,
1186
1197
  'MASK must be set',
1187
1198
  true,
1188
1199
  1002,
1189
1200
  'WS_ERR_EXPECTED_MASK'
1190
1201
  );
1202
+
1203
+ cb(error);
1204
+ return;
1191
1205
  }
1192
1206
  } else if (this._masked) {
1193
- this._loop = false;
1194
- return error(
1207
+ const error = this.createError(
1195
1208
  RangeError,
1196
1209
  'MASK must be clear',
1197
1210
  true,
1198
1211
  1002,
1199
1212
  'WS_ERR_UNEXPECTED_MASK'
1200
1213
  );
1214
+
1215
+ cb(error);
1216
+ return;
1201
1217
  }
1202
1218
 
1203
1219
  if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
1204
1220
  else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
1205
- else return this.haveLength();
1221
+ else this.haveLength(cb);
1206
1222
  }
1207
1223
 
1208
1224
  /**
1209
1225
  * Gets extended payload length (7+16).
1210
1226
  *
1211
- * @return {(RangeError|undefined)} A possible error
1227
+ * @param {Function} cb Callback
1212
1228
  * @private
1213
1229
  */
1214
- getPayloadLength16() {
1230
+ getPayloadLength16(cb) {
1215
1231
  if (this._bufferedBytes < 2) {
1216
1232
  this._loop = false;
1217
1233
  return;
1218
1234
  }
1219
1235
 
1220
1236
  this._payloadLength = this.consume(2).readUInt16BE(0);
1221
- return this.haveLength();
1237
+ this.haveLength(cb);
1222
1238
  }
1223
1239
 
1224
1240
  /**
1225
1241
  * Gets extended payload length (7+64).
1226
1242
  *
1227
- * @return {(RangeError|undefined)} A possible error
1243
+ * @param {Function} cb Callback
1228
1244
  * @private
1229
1245
  */
1230
- getPayloadLength64() {
1246
+ getPayloadLength64(cb) {
1231
1247
  if (this._bufferedBytes < 8) {
1232
1248
  this._loop = false;
1233
1249
  return;
@@ -1241,38 +1257,42 @@ let Receiver$1 = class Receiver extends Writable {
1241
1257
  // if payload length is greater than this number.
1242
1258
  //
1243
1259
  if (num > Math.pow(2, 53 - 32) - 1) {
1244
- this._loop = false;
1245
- return error(
1260
+ const error = this.createError(
1246
1261
  RangeError,
1247
1262
  'Unsupported WebSocket frame: payload length > 2^53 - 1',
1248
1263
  false,
1249
1264
  1009,
1250
1265
  'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'
1251
1266
  );
1267
+
1268
+ cb(error);
1269
+ return;
1252
1270
  }
1253
1271
 
1254
1272
  this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
1255
- return this.haveLength();
1273
+ this.haveLength(cb);
1256
1274
  }
1257
1275
 
1258
1276
  /**
1259
1277
  * Payload length has been read.
1260
1278
  *
1261
- * @return {(RangeError|undefined)} A possible error
1279
+ * @param {Function} cb Callback
1262
1280
  * @private
1263
1281
  */
1264
- haveLength() {
1282
+ haveLength(cb) {
1265
1283
  if (this._payloadLength && this._opcode < 0x08) {
1266
1284
  this._totalPayloadLength += this._payloadLength;
1267
1285
  if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
1268
- this._loop = false;
1269
- return error(
1286
+ const error = this.createError(
1270
1287
  RangeError,
1271
1288
  'Max payload size exceeded',
1272
1289
  false,
1273
1290
  1009,
1274
1291
  'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
1275
1292
  );
1293
+
1294
+ cb(error);
1295
+ return;
1276
1296
  }
1277
1297
  }
1278
1298
 
@@ -1299,7 +1319,6 @@ let Receiver$1 = class Receiver extends Writable {
1299
1319
  * Reads data bytes.
1300
1320
  *
1301
1321
  * @param {Function} cb Callback
1302
- * @return {(Error|RangeError|undefined)} A possible error
1303
1322
  * @private
1304
1323
  */
1305
1324
  getData(cb) {
@@ -1321,7 +1340,10 @@ let Receiver$1 = class Receiver extends Writable {
1321
1340
  }
1322
1341
  }
1323
1342
 
1324
- if (this._opcode > 0x07) return this.controlMessage(data);
1343
+ if (this._opcode > 0x07) {
1344
+ this.controlMessage(data, cb);
1345
+ return;
1346
+ }
1325
1347
 
1326
1348
  if (this._compressed) {
1327
1349
  this._state = INFLATING;
@@ -1338,7 +1360,7 @@ let Receiver$1 = class Receiver extends Writable {
1338
1360
  this._fragments.push(data);
1339
1361
  }
1340
1362
 
1341
- return this.dataMessage();
1363
+ this.dataMessage(cb);
1342
1364
  }
1343
1365
 
1344
1366
  /**
@@ -1357,74 +1379,101 @@ let Receiver$1 = class Receiver extends Writable {
1357
1379
  if (buf.length) {
1358
1380
  this._messageLength += buf.length;
1359
1381
  if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
1360
- return cb(
1361
- error(
1362
- RangeError,
1363
- 'Max payload size exceeded',
1364
- false,
1365
- 1009,
1366
- 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
1367
- )
1382
+ const error = this.createError(
1383
+ RangeError,
1384
+ 'Max payload size exceeded',
1385
+ false,
1386
+ 1009,
1387
+ 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
1368
1388
  );
1389
+
1390
+ cb(error);
1391
+ return;
1369
1392
  }
1370
1393
 
1371
1394
  this._fragments.push(buf);
1372
1395
  }
1373
1396
 
1374
- const er = this.dataMessage();
1375
- if (er) return cb(er);
1376
-
1377
- this.startLoop(cb);
1397
+ this.dataMessage(cb);
1398
+ if (this._state === GET_INFO) this.startLoop(cb);
1378
1399
  });
1379
1400
  }
1380
1401
 
1381
1402
  /**
1382
1403
  * Handles a data message.
1383
1404
  *
1384
- * @return {(Error|undefined)} A possible error
1405
+ * @param {Function} cb Callback
1385
1406
  * @private
1386
1407
  */
1387
- dataMessage() {
1388
- if (this._fin) {
1389
- const messageLength = this._messageLength;
1390
- const fragments = this._fragments;
1391
-
1392
- this._totalPayloadLength = 0;
1393
- this._messageLength = 0;
1394
- this._fragmented = 0;
1395
- this._fragments = [];
1396
-
1397
- if (this._opcode === 2) {
1398
- let data;
1399
-
1400
- if (this._binaryType === 'nodebuffer') {
1401
- data = concat(fragments, messageLength);
1402
- } else if (this._binaryType === 'arraybuffer') {
1403
- data = toArrayBuffer(concat(fragments, messageLength));
1404
- } else {
1405
- data = fragments;
1406
- }
1408
+ dataMessage(cb) {
1409
+ if (!this._fin) {
1410
+ this._state = GET_INFO;
1411
+ return;
1412
+ }
1413
+
1414
+ const messageLength = this._messageLength;
1415
+ const fragments = this._fragments;
1416
+
1417
+ this._totalPayloadLength = 0;
1418
+ this._messageLength = 0;
1419
+ this._fragmented = 0;
1420
+ this._fragments = [];
1407
1421
 
1422
+ if (this._opcode === 2) {
1423
+ let data;
1424
+
1425
+ if (this._binaryType === 'nodebuffer') {
1426
+ data = concat(fragments, messageLength);
1427
+ } else if (this._binaryType === 'arraybuffer') {
1428
+ data = toArrayBuffer(concat(fragments, messageLength));
1429
+ } else {
1430
+ data = fragments;
1431
+ }
1432
+
1433
+ //
1434
+ // If the state is `INFLATING`, it means that the frame data was
1435
+ // decompressed asynchronously, so there is no need to defer the event
1436
+ // as it will be emitted asynchronously anyway.
1437
+ //
1438
+ if (this._state === INFLATING || this._allowSynchronousEvents) {
1408
1439
  this.emit('message', data, true);
1440
+ this._state = GET_INFO;
1409
1441
  } else {
1410
- const buf = concat(fragments, messageLength);
1442
+ this._state = DEFER_EVENT;
1443
+ queueTask(() => {
1444
+ this.emit('message', data, true);
1445
+ this._state = GET_INFO;
1446
+ this.startLoop(cb);
1447
+ });
1448
+ }
1449
+ } else {
1450
+ const buf = concat(fragments, messageLength);
1411
1451
 
1412
- if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1413
- this._loop = false;
1414
- return error(
1415
- Error,
1416
- 'invalid UTF-8 sequence',
1417
- true,
1418
- 1007,
1419
- 'WS_ERR_INVALID_UTF8'
1420
- );
1421
- }
1452
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1453
+ const error = this.createError(
1454
+ Error,
1455
+ 'invalid UTF-8 sequence',
1456
+ true,
1457
+ 1007,
1458
+ 'WS_ERR_INVALID_UTF8'
1459
+ );
1422
1460
 
1461
+ cb(error);
1462
+ return;
1463
+ }
1464
+
1465
+ if (this._state === INFLATING || this._allowSynchronousEvents) {
1423
1466
  this.emit('message', buf, false);
1467
+ this._state = GET_INFO;
1468
+ } else {
1469
+ this._state = DEFER_EVENT;
1470
+ queueTask(() => {
1471
+ this.emit('message', buf, false);
1472
+ this._state = GET_INFO;
1473
+ this.startLoop(cb);
1474
+ });
1424
1475
  }
1425
1476
  }
1426
-
1427
- this._state = WAIT_MICROTASK;
1428
1477
  }
1429
1478
 
1430
1479
  /**
@@ -1434,26 +1483,26 @@ let Receiver$1 = class Receiver extends Writable {
1434
1483
  * @return {(Error|RangeError|undefined)} A possible error
1435
1484
  * @private
1436
1485
  */
1437
- controlMessage(data) {
1486
+ controlMessage(data, cb) {
1438
1487
  if (this._opcode === 0x08) {
1439
- this._loop = false;
1440
-
1441
1488
  if (data.length === 0) {
1489
+ this._loop = false;
1442
1490
  this.emit('conclude', 1005, EMPTY_BUFFER$2);
1443
1491
  this.end();
1444
-
1445
- this._state = GET_INFO;
1446
1492
  } else {
1447
1493
  const code = data.readUInt16BE(0);
1448
1494
 
1449
1495
  if (!isValidStatusCode$1(code)) {
1450
- return error(
1496
+ const error = this.createError(
1451
1497
  RangeError,
1452
1498
  `invalid status code ${code}`,
1453
1499
  true,
1454
1500
  1002,
1455
1501
  'WS_ERR_INVALID_CLOSE_CODE'
1456
1502
  );
1503
+
1504
+ cb(error);
1505
+ return;
1457
1506
  }
1458
1507
 
1459
1508
  const buf = new FastBuffer(
@@ -1463,54 +1512,68 @@ let Receiver$1 = class Receiver extends Writable {
1463
1512
  );
1464
1513
 
1465
1514
  if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1466
- return error(
1515
+ const error = this.createError(
1467
1516
  Error,
1468
1517
  'invalid UTF-8 sequence',
1469
1518
  true,
1470
1519
  1007,
1471
1520
  'WS_ERR_INVALID_UTF8'
1472
1521
  );
1522
+
1523
+ cb(error);
1524
+ return;
1473
1525
  }
1474
1526
 
1527
+ this._loop = false;
1475
1528
  this.emit('conclude', code, buf);
1476
1529
  this.end();
1477
-
1478
- this._state = GET_INFO;
1479
1530
  }
1480
- } else if (this._opcode === 0x09) {
1481
- this.emit('ping', data);
1482
- this._state = WAIT_MICROTASK;
1531
+
1532
+ this._state = GET_INFO;
1533
+ return;
1534
+ }
1535
+
1536
+ if (this._allowSynchronousEvents) {
1537
+ this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);
1538
+ this._state = GET_INFO;
1483
1539
  } else {
1484
- this.emit('pong', data);
1485
- this._state = WAIT_MICROTASK;
1540
+ this._state = DEFER_EVENT;
1541
+ queueTask(() => {
1542
+ this.emit(this._opcode === 0x09 ? 'ping' : 'pong', data);
1543
+ this._state = GET_INFO;
1544
+ this.startLoop(cb);
1545
+ });
1486
1546
  }
1487
1547
  }
1488
- };
1489
1548
 
1490
- var receiver = Receiver$1;
1549
+ /**
1550
+ * Builds an error object.
1551
+ *
1552
+ * @param {function(new:Error|RangeError)} ErrorCtor The error constructor
1553
+ * @param {String} message The error message
1554
+ * @param {Boolean} prefix Specifies whether or not to add a default prefix to
1555
+ * `message`
1556
+ * @param {Number} statusCode The status code
1557
+ * @param {String} errorCode The exposed error code
1558
+ * @return {(Error|RangeError)} The error
1559
+ * @private
1560
+ */
1561
+ createError(ErrorCtor, message, prefix, statusCode, errorCode) {
1562
+ this._loop = false;
1563
+ this._errored = true;
1491
1564
 
1492
- /**
1493
- * Builds an error object.
1494
- *
1495
- * @param {function(new:Error|RangeError)} ErrorCtor The error constructor
1496
- * @param {String} message The error message
1497
- * @param {Boolean} prefix Specifies whether or not to add a default prefix to
1498
- * `message`
1499
- * @param {Number} statusCode The status code
1500
- * @param {String} errorCode The exposed error code
1501
- * @return {(Error|RangeError)} The error
1502
- * @private
1503
- */
1504
- function error(ErrorCtor, message, prefix, statusCode, errorCode) {
1505
- const err = new ErrorCtor(
1506
- prefix ? `Invalid WebSocket frame: ${message}` : message
1507
- );
1565
+ const err = new ErrorCtor(
1566
+ prefix ? `Invalid WebSocket frame: ${message}` : message
1567
+ );
1508
1568
 
1509
- Error.captureStackTrace(err, error);
1510
- err.code = errorCode;
1511
- err[kStatusCode$1] = statusCode;
1512
- return err;
1513
- }
1569
+ Error.captureStackTrace(err, this.createError);
1570
+ err.code = errorCode;
1571
+ err[kStatusCode$1] = statusCode;
1572
+ return err;
1573
+ }
1574
+ };
1575
+
1576
+ var receiver = Receiver$1;
1514
1577
 
1515
1578
  /**
1516
1579
  * A shim for `queueMicrotask()`.
@@ -2591,6 +2654,7 @@ let WebSocket$1 = class WebSocket extends EventEmitter$1 {
2591
2654
 
2592
2655
  initAsClient(this, address, protocols, options);
2593
2656
  } else {
2657
+ this._autoPong = options.autoPong;
2594
2658
  this._isServer = true;
2595
2659
  }
2596
2660
  }
@@ -2699,6 +2763,9 @@ let WebSocket$1 = class WebSocket extends EventEmitter$1 {
2699
2763
  * @param {Duplex} socket The network socket between the server and client
2700
2764
  * @param {Buffer} head The first packet of the upgraded stream
2701
2765
  * @param {Object} options Options object
2766
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
2767
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
2768
+ * multiple times in the same tick
2702
2769
  * @param {Function} [options.generateMask] The function used to generate the
2703
2770
  * masking key
2704
2771
  * @param {Number} [options.maxPayload=0] The maximum allowed message size
@@ -2708,6 +2775,7 @@ let WebSocket$1 = class WebSocket extends EventEmitter$1 {
2708
2775
  */
2709
2776
  setSocket(socket, head, options) {
2710
2777
  const receiver = new Receiver({
2778
+ allowSynchronousEvents: options.allowSynchronousEvents,
2711
2779
  binaryType: this.binaryType,
2712
2780
  extensions: this._extensions,
2713
2781
  isServer: this._isServer,
@@ -3125,6 +3193,13 @@ var websocket = WebSocket$1;
3125
3193
  * @param {(String|URL)} address The URL to which to connect
3126
3194
  * @param {Array} protocols The subprotocols
3127
3195
  * @param {Object} [options] Connection options
3196
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether any
3197
+ * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple
3198
+ * times in the same tick
3199
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
3200
+ * automatically send a pong in response to a ping
3201
+ * @param {Function} [options.finishRequest] A function which can be used to
3202
+ * customize the headers of each http request before it is sent
3128
3203
  * @param {Boolean} [options.followRedirects=false] Whether or not to follow
3129
3204
  * redirects
3130
3205
  * @param {Function} [options.generateMask] The function used to generate the
@@ -3147,6 +3222,8 @@ var websocket = WebSocket$1;
3147
3222
  */
3148
3223
  function initAsClient(websocket, address, protocols, options) {
3149
3224
  const opts = {
3225
+ allowSynchronousEvents: false,
3226
+ autoPong: true,
3150
3227
  protocolVersion: protocolVersions[1],
3151
3228
  maxPayload: 100 * 1024 * 1024,
3152
3229
  skipUTF8Validation: false,
@@ -3165,6 +3242,8 @@ function initAsClient(websocket, address, protocols, options) {
3165
3242
  port: undefined
3166
3243
  };
3167
3244
 
3245
+ websocket._autoPong = opts.autoPong;
3246
+
3168
3247
  if (!protocolVersions.includes(opts.protocolVersion)) {
3169
3248
  throw new RangeError(
3170
3249
  `Unsupported protocol version: ${opts.protocolVersion} ` +
@@ -3313,8 +3392,8 @@ function initAsClient(websocket, address, protocols, options) {
3313
3392
  ? opts.socketPath === websocket._originalHostOrSocketPath
3314
3393
  : false
3315
3394
  : websocket._originalIpc
3316
- ? false
3317
- : parsedUrl.host === websocket._originalHostOrSocketPath;
3395
+ ? false
3396
+ : parsedUrl.host === websocket._originalHostOrSocketPath;
3318
3397
 
3319
3398
  if (!isSameHost || (websocket._originalSecure && !isSecure)) {
3320
3399
  //
@@ -3498,6 +3577,7 @@ function initAsClient(websocket, address, protocols, options) {
3498
3577
  }
3499
3578
 
3500
3579
  websocket.setSocket(socket, head, {
3580
+ allowSynchronousEvents: opts.allowSynchronousEvents,
3501
3581
  generateMask: opts.generateMask,
3502
3582
  maxPayload: opts.maxPayload,
3503
3583
  skipUTF8Validation: opts.skipUTF8Validation
@@ -3708,7 +3788,7 @@ function receiverOnMessage(data, isBinary) {
3708
3788
  function receiverOnPing(data) {
3709
3789
  const websocket = this[kWebSocket$1];
3710
3790
 
3711
- websocket.pong(data, !websocket._isServer, NOOP);
3791
+ if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);
3712
3792
  websocket.emit('ping', data);
3713
3793
  }
3714
3794
 
@@ -3914,6 +3994,11 @@ class WebSocketServer extends EventEmitter {
3914
3994
  * Create a `WebSocketServer` instance.
3915
3995
  *
3916
3996
  * @param {Object} options Configuration options
3997
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
3998
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
3999
+ * multiple times in the same tick
4000
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
4001
+ * automatically send a pong in response to a ping
3917
4002
  * @param {Number} [options.backlog=511] The maximum length of the queue of
3918
4003
  * pending connections
3919
4004
  * @param {Boolean} [options.clientTracking=true] Specifies whether or not to
@@ -3940,6 +4025,8 @@ class WebSocketServer extends EventEmitter {
3940
4025
  super();
3941
4026
 
3942
4027
  options = {
4028
+ allowSynchronousEvents: false,
4029
+ autoPong: true,
3943
4030
  maxPayload: 100 * 1024 * 1024,
3944
4031
  skipUTF8Validation: false,
3945
4032
  perMessageDeflate: false,
@@ -4260,7 +4347,7 @@ class WebSocketServer extends EventEmitter {
4260
4347
  `Sec-WebSocket-Accept: ${digest}`
4261
4348
  ];
4262
4349
 
4263
- const ws = new this.options.WebSocket(null);
4350
+ const ws = new this.options.WebSocket(null, undefined, this.options);
4264
4351
 
4265
4352
  if (protocols.size) {
4266
4353
  //
@@ -4294,6 +4381,7 @@ class WebSocketServer extends EventEmitter {
4294
4381
  socket.removeListener('error', socketOnError);
4295
4382
 
4296
4383
  ws.setSocket(socket, head, {
4384
+ allowSynchronousEvents: this.options.allowSynchronousEvents,
4297
4385
  maxPayload: this.options.maxPayload,
4298
4386
  skipUTF8Validation: this.options.skipUTF8Validation
4299
4387
  });