summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/domain.ts
blob: 70937799668bf252bf9e8bbde14edd85cdcdb18c (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
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// This code has been inspired by https://github.com/bevry/domain-browser/commit/8bce7f4a093966ca850da75b024239ad5d0b33c6

import { primordials } from "ext:core/mod.js";
const {
  ArrayPrototypeSlice,
  FunctionPrototypeBind,
  FunctionPrototypeCall,
  FunctionPrototypeApply,
} = primordials;
import { EventEmitter } from "node:events";

function emitError(e) {
  this.emit("error", e);
}

// TODO(bartlomieju): maybe use this one
// deno-lint-ignore prefer-const
let stack = [];
export const _stack = stack;
export const active = null;

export function create() {
  return new Domain();
}

export function createDomain() {
  return new Domain();
}

export class Domain extends EventEmitter {
  #handler;

  constructor() {
    super();
    this.#handler = FunctionPrototypeBind(emitError, this);
  }

  add(emitter) {
    emitter.on("error", this.#handler);
  }

  remove(emitter) {
    emitter.off("error", this.#handler);
  }

  bind(fn) {
    // deno-lint-ignore no-this-alias
    const self = this;
    return function () {
      try {
        FunctionPrototypeApply(fn, null, ArrayPrototypeSlice(arguments));
      } catch (e) {
        FunctionPrototypeCall(emitError, self, e);
      }
    };
  }

  intercept(fn) {
    // deno-lint-ignore no-this-alias
    const self = this;
    return function (e) {
      if (e) {
        FunctionPrototypeCall(emitError, self, e);
      } else {
        try {
          FunctionPrototypeApply(fn, null, ArrayPrototypeSlice(arguments, 1));
        } catch (e) {
          FunctionPrototypeCall(emitError, self, e);
        }
      }
    };
  }

  run(fn) {
    try {
      fn();
    } catch (e) {
      FunctionPrototypeCall(emitError, this, e);
    }
    return this;
  }

  dispose() {
    this.removeAllListeners();
    return this;
  }

  enter() {
    return this;
  }

  exit() {
    return this;
  }
}
export default {
  _stack,
  create,
  active,
  createDomain,
  Domain,
};