summaryrefslogtreecommitdiff
path: root/ext/node/01_node.js
blob: 4ed5b3edab4f428cfaf7f984d0bf93a1f66de031 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.

// deno-lint-ignore-file

"use strict";

((window) => {
  const {
    ArrayPrototypePush,
    ArrayPrototypeFilter,
    ObjectEntries,
    ObjectCreate,
    ObjectDefineProperty,
    Proxy,
    ReflectDefineProperty,
    ReflectGetOwnPropertyDescriptor,
    ReflectOwnKeys,
    Set,
    SetPrototypeHas,
  } = window.__bootstrap.primordials;

  function assert(cond) {
    if (!cond) {
      throw Error("assert");
    }
  }

  let initialized = false;
  const nodeGlobals = {};
  const nodeGlobalThis = new Proxy(globalThis, {
    get(_target, prop, _receiver) {
      if (prop in nodeGlobals) {
        return nodeGlobals[prop];
      } else {
        return globalThis[prop];
      }
    },
    set(_target, prop, value) {
      if (prop in nodeGlobals) {
        nodeGlobals[prop] = value;
      } else {
        globalThis[prop] = value;
      }
      return true;
    },
    deleteProperty(_target, prop) {
      let success = false;
      if (prop in nodeGlobals) {
        delete nodeGlobals[prop];
        success = true;
      }
      if (prop in globalThis) {
        delete globalThis[prop];
        success = true;
      }
      return success;
    },
    ownKeys(_target) {
      const globalThisKeys = ReflectOwnKeys(globalThis);
      const nodeGlobalsKeys = ReflectOwnKeys(nodeGlobals);
      const nodeGlobalsKeySet = new Set(nodeGlobalsKeys);
      return [
        ...ArrayPrototypeFilter(
          globalThisKeys,
          (k) => !SetPrototypeHas(nodeGlobalsKeySet, k),
        ),
        ...nodeGlobalsKeys,
      ];
    },
    defineProperty(_target, prop, desc) {
      if (prop in nodeGlobals) {
        return ReflectDefineProperty(nodeGlobals, prop, desc);
      } else {
        return ReflectDefineProperty(globalThis, prop, desc);
      }
    },
    getOwnPropertyDescriptor(_target, prop) {
      if (prop in nodeGlobals) {
        return ReflectGetOwnPropertyDescriptor(nodeGlobals, prop);
      } else {
        return ReflectGetOwnPropertyDescriptor(globalThis, prop);
      }
    },
    has(_target, prop) {
      return prop in nodeGlobals || prop in globalThis;
    },
  });

  const nativeModuleExports = ObjectCreate(null);
  const builtinModules = [];

  function initialize(nodeModules, nodeGlobalThisName) {
    assert(!initialized);
    initialized = true;
    for (const [name, exports] of ObjectEntries(nodeModules)) {
      nativeModuleExports[name] = exports;
      ArrayPrototypePush(builtinModules, name);
    }
    nodeGlobals.Buffer = nativeModuleExports["buffer"].Buffer;
    nodeGlobals.clearImmediate = nativeModuleExports["timers"].clearImmediate;
    nodeGlobals.clearInterval = nativeModuleExports["timers"].clearInterval;
    nodeGlobals.clearTimeout = nativeModuleExports["timers"].clearTimeout;
    nodeGlobals.console = nativeModuleExports["console"];
    nodeGlobals.global = nodeGlobalThis;
    nodeGlobals.process = nativeModuleExports["process"];
    nodeGlobals.setImmediate = nativeModuleExports["timers"].setImmediate;
    nodeGlobals.setInterval = nativeModuleExports["timers"].setInterval;
    nodeGlobals.setTimeout = nativeModuleExports["timers"].setTimeout;

    // add a hidden global for the esm code to use in order to reliably
    // get node's globalThis
    ObjectDefineProperty(globalThis, nodeGlobalThisName, {
      enumerable: false,
      writable: false,
      value: nodeGlobalThis,
    });
  }

  window.__bootstrap.internals = {
    ...window.__bootstrap.internals ?? {},
    node: {
      globalThis: nodeGlobalThis,
      initialize,
      nativeModuleExports,
      builtinModules,
    },
  };
})(globalThis);