@@ -31,15 +31,35 @@ const Flatted = require('flatted'),
31
31
32
32
${ bridgeClientCode ( ) }
33
33
34
- (function (emit, id) {
34
+ __uvm_startBoot = (function (uvmEmit, uvmTimeout) {
35
+ return function () {
36
+ // A 5ms delay is added to ensure the required modules are loaded.
37
+ uvmTimeout(() => {
38
+ try {
39
+ ${ bootCode } ;
40
+ } catch (error) {
41
+ uvmTimeout(() => { throw error; }, 0);
42
+ }
43
+ uvmEmit('${ Flatted . stringify ( [ 'load.' + id ] ) } ');
44
+ }, 5);
45
+
46
+ };
47
+ }(__uvm_emit, setTimeout));
48
+
49
+ (function (emit, boot, id) {
35
50
__uvm_addEventListener("message", function (e) {
36
51
const { __emit_uvm, __id_uvm } = e?.data || e || {};
37
52
if (typeof __emit_uvm === 'string' && __id_uvm === id) {
38
- emit(__emit_uvm);
53
+ if (__emit_uvm === '${ Flatted . stringify ( [ 'boot-start' ] ) } ') {
54
+ boot();
55
+ } else {
56
+ emit(__emit_uvm);
57
+ }
39
58
}
40
59
});
41
- }(__uvm_dispatch, "${ id } "));
60
+ }(__uvm_dispatch, __uvm_startBoot, "${ id } "));
42
61
__uvm_dispatch = null; delete __uvm_dispatch;
62
+ __uvm_startBoot = null; delete __uvm_startBoot;
43
63
__uvm_addEventListener = null; delete __uvm_addEventListener;
44
64
45
65
(function (self, bridge, setTimeout) {
@@ -48,16 +68,12 @@ const Flatted = require('flatted'),
48
68
__self = null; delete __self;
49
69
50
70
// boot code starts hereafter
51
- __uvm_setTimeout = setTimeout;
52
- try {
53
- ${ bootCode } ;
54
- } catch (error) {
55
- __uvm_setTimeout(() => { throw error; }, 0);
56
- }
57
-
58
- __uvm_emit('${ Flatted . stringify ( [ 'load.' + id ] ) } ');
71
+ // Post node v22.3.0, node uses undici's MessageEvent class which is
72
+ // loaded lazily and reads certain modules from the global scope when loaded.
73
+ // We are doing a round trip to main thread to ensure the everything required
74
+ // for uvm to work is loaded before running the boot code, which might mutate the global scope.
75
+ __uvm_emit('${ Flatted . stringify ( [ 'boot-ready.' + id ] ) } ');
59
76
__uvm_emit = null; delete __uvm_emit;
60
- __uvm_setTimeout = null; delete __uvm_setTimeout;
61
77
` ;
62
78
} ;
63
79
@@ -133,6 +149,17 @@ module.exports = function (bridge, options, callback) {
133
149
callback ( null , bridge ) ;
134
150
} ) ;
135
151
152
+ bridge . once ( 'boot-ready.' + id , ( ) => {
153
+ if ( ! worker ) {
154
+ return callback ( new Error ( 'uvm : boot sequence failed due to worker termination.' ) ) ;
155
+ }
156
+
157
+ worker . postMessage ( {
158
+ __emit_uvm : Flatted . stringify ( [ 'boot-start' ] ) ,
159
+ __id_uvm : id
160
+ } ) ;
161
+ } ) ;
162
+
136
163
// get firmware code string with boot code
137
164
firmwareCode = sandboxFirmware ( options . bootCode , id , options . debug ) ;
138
165
0 commit comments