node-entry.mjs raw
1 // Node.js entry wrapper for the moxiejs-compiled mlsinterop binary.
2 //
3 // The moxiejs runtime index re-exports sw.mjs, which has top-level
4 // `self.addEventListener(...)` calls designed for a Service Worker scope.
5 // Under Node, those globals don't exist. We polyfill a minimum viable
6 // ServiceWorkerGlobalScope before importing the entry module so those
7 // registrations are no-ops.
8 //
9 // Usage:
10 // node web/mlsinterop/node-entry.mjs
11 //
12 // Expects the compiled output at ./web/mlsinterop/static/$entry.mjs
13 // (build command in scripts/mls-interop-test.sh).
14
15 const g = globalThis;
16
17 if (typeof g.self === 'undefined') {
18 g.self = g;
19 }
20
21 if (typeof g.self.addEventListener !== 'function') {
22 g.self.addEventListener = () => {};
23 g.self.removeEventListener = () => {};
24 }
25
26 if (typeof g.self.skipWaiting !== 'function') {
27 g.self.skipWaiting = () => Promise.resolve();
28 }
29
30 if (!g.self.clients) {
31 g.self.clients = {
32 claim: () => Promise.resolve(),
33 matchAll: () => Promise.resolve([]),
34 get: () => Promise.resolve(null),
35 };
36 }
37
38 if (!g.self.registration) {
39 g.self.registration = {
40 scope: 'node://mlsinterop',
41 active: null,
42 waiting: null,
43 installing: null,
44 update: () => Promise.resolve(),
45 unregister: () => Promise.resolve(true),
46 showNotification: () => Promise.resolve(),
47 };
48 }
49
50 if (!g.self.location) {
51 g.self.location = { origin: 'node://mlsinterop', href: 'node://mlsinterop/' };
52 }
53
54 if (typeof g.caches === 'undefined') {
55 g.caches = {
56 open: () => Promise.resolve({
57 match: () => Promise.resolve(undefined),
58 put: () => Promise.resolve(),
59 delete: () => Promise.resolve(true),
60 keys: () => Promise.resolve([]),
61 }),
62 match: () => Promise.resolve(undefined),
63 has: () => Promise.resolve(false),
64 delete: () => Promise.resolve(true),
65 keys: () => Promise.resolve([]),
66 };
67 }
68
69 if (typeof g.IDBDatabase === 'undefined') {
70 // IndexedDB is not provided; the mlsinterop binary does not use it, but
71 // idb.mjs may reference `indexedDB` at call time. Leave it undefined so
72 // attempted use surfaces loudly rather than silently no-op.
73 }
74
75 // Surface unhandled rejections on stderr so a misrouted Promise from
76 // inside a stdin callback is visible instead of swallowed.
77 process.on('unhandledRejection', (reason) => {
78 process.stderr.write('[mlsinterop] unhandled rejection: ' + (reason && reason.stack || reason) + '\n');
79 });
80
81 await import('./static/$entry.mjs');
82