Skip to content

Commit be93de3

Browse files
committed
Refactor bridge.js for lazy loading and boot sequence improvement
1 parent 836170e commit be93de3

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
strategy:
6161
fail-fast: false
6262
matrix:
63-
node-version: [16, 18]
63+
node-version: [16, 18, 22]
6464
os: [ubuntu-latest, windows-latest]
6565
include:
6666
- coverage: true

lib/bridge.js

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,35 @@ const Flatted = require('flatted'),
3131
3232
${bridgeClientCode()}
3333
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) {
3550
__uvm_addEventListener("message", function (e) {
3651
const { __emit_uvm, __id_uvm } = e?.data || e || {};
3752
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+
}
3958
}
4059
});
41-
}(__uvm_dispatch, "${id}"));
60+
}(__uvm_dispatch, __uvm_startBoot, "${id}"));
4261
__uvm_dispatch = null; delete __uvm_dispatch;
62+
__uvm_startBoot = null; delete __uvm_startBoot;
4363
__uvm_addEventListener = null; delete __uvm_addEventListener;
4464
4565
(function (self, bridge, setTimeout) {
@@ -48,16 +68,12 @@ const Flatted = require('flatted'),
4868
__self = null; delete __self;
4969
5070
// 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])}');
5976
__uvm_emit = null; delete __uvm_emit;
60-
__uvm_setTimeout = null; delete __uvm_setTimeout;
6177
`;
6278
};
6379

@@ -133,6 +149,17 @@ module.exports = function (bridge, options, callback) {
133149
callback(null, bridge);
134150
});
135151

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+
136163
// get firmware code string with boot code
137164
firmwareCode = sandboxFirmware(options.bootCode, id, options.debug);
138165

0 commit comments

Comments
 (0)