@yolo-croket-dev/core 1.7.31 → 1.7.32-slowquery.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare class ContextPromisePatch {
|
|
2
|
-
private static originalPromise;
|
|
3
2
|
private static isPatched;
|
|
3
|
+
private static originalPromise;
|
|
4
|
+
private static originalSetTimeout;
|
|
4
5
|
static patch(): void;
|
|
6
|
+
private static patchPromise;
|
|
7
|
+
private static patchSetTimeout;
|
|
5
8
|
static unpatch(): void;
|
|
6
9
|
}
|
|
@@ -8,41 +8,145 @@ class ContextPromisePatch {
|
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
this.originalPromise = global.Promise;
|
|
11
|
-
|
|
11
|
+
this.patchPromise();
|
|
12
|
+
this.patchSetTimeout();
|
|
13
|
+
this.isPatched = true;
|
|
14
|
+
}
|
|
15
|
+
static patchPromise() {
|
|
16
|
+
// Promise 생성자 패치
|
|
12
17
|
global.Promise = new Proxy(global.Promise, {
|
|
13
18
|
construct(target, args) {
|
|
19
|
+
// 현재 컨텍스트 확인
|
|
14
20
|
const currentContext = abort_context_1.AbortContext.getCurrentContext();
|
|
15
21
|
// 컨텍스트가 없으면 원본 Promise 사용
|
|
16
22
|
if (!currentContext) {
|
|
17
23
|
return Reflect.construct(target, args);
|
|
18
24
|
}
|
|
19
25
|
const abortSignal = currentContext.abortSignal;
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
const contextId = currentContext.requestId;
|
|
27
|
+
// 이미 중단된 경우
|
|
28
|
+
if (abortSignal.aborted) {
|
|
29
|
+
return Promise.reject(new Error(`REQUEST_ABORTED: Promise가 중단되었습니다 (${contextId})`));
|
|
22
30
|
}
|
|
23
|
-
// eslint-disable-next-line new-cap
|
|
24
31
|
const promise = Reflect.construct(target, args);
|
|
25
|
-
//
|
|
32
|
+
// Promise 체인에 자동으로 중단 확인 추가
|
|
26
33
|
return promise.then((result) => {
|
|
34
|
+
// 컨텍스트가 여전히 유효한지 확인
|
|
35
|
+
const currentContextCheck = abort_context_1.AbortContext.getCurrentContext();
|
|
36
|
+
if (!currentContextCheck || currentContextCheck.requestId !== contextId) {
|
|
37
|
+
// 컨텍스트가 변경되었으면 원본 결과 반환
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
27
40
|
if (abortSignal.aborted) {
|
|
28
|
-
throw new Error(
|
|
41
|
+
throw new Error(`REQUEST_ABORTED: Promise 실행 중 중단되었습니다 (${contextId})`);
|
|
29
42
|
}
|
|
30
43
|
return result;
|
|
31
44
|
}, (error) => {
|
|
45
|
+
// 컨텍스트가 여전히 유효한지 확인
|
|
46
|
+
const currentContextCheck = abort_context_1.AbortContext.getCurrentContext();
|
|
47
|
+
if (!currentContextCheck || currentContextCheck.requestId !== contextId) {
|
|
48
|
+
// 컨텍스트가 변경되었으면 원본 에러 반환
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
32
51
|
if (abortSignal.aborted) {
|
|
33
|
-
throw new Error(
|
|
52
|
+
throw new Error(`REQUEST_ABORTED: Promise 실행 중 중단되었습니다 (${contextId})`);
|
|
34
53
|
}
|
|
35
54
|
throw error;
|
|
36
55
|
});
|
|
37
56
|
},
|
|
38
57
|
});
|
|
39
|
-
|
|
58
|
+
// Promise.resolve 패치
|
|
59
|
+
const originalResolve = global.Promise.resolve;
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
global.Promise.resolve = (value) => {
|
|
62
|
+
const currentContext = abort_context_1.AbortContext.getCurrentContext();
|
|
63
|
+
if (!currentContext) {
|
|
64
|
+
return originalResolve.call(global.Promise, value);
|
|
65
|
+
}
|
|
66
|
+
const abortSignal = currentContext.abortSignal;
|
|
67
|
+
const contextId = currentContext.requestId;
|
|
68
|
+
if (abortSignal.aborted) {
|
|
69
|
+
return Promise.reject(new Error(`REQUEST_ABORTED: Promise.resolve가 중단되었습니다 (${contextId})`));
|
|
70
|
+
}
|
|
71
|
+
const promise = originalResolve.call(global.Promise, value);
|
|
72
|
+
return promise.then((result) => {
|
|
73
|
+
const currentContextCheck = abort_context_1.AbortContext.getCurrentContext();
|
|
74
|
+
if (!currentContextCheck || currentContextCheck.requestId !== contextId) {
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
if (abortSignal.aborted) {
|
|
78
|
+
throw new Error(`REQUEST_ABORTED: Promise.resolve 실행 중 중단되었습니다 (${contextId})`);
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}, (error) => {
|
|
82
|
+
const currentContextCheck = abort_context_1.AbortContext.getCurrentContext();
|
|
83
|
+
if (!currentContextCheck || currentContextCheck.requestId !== contextId) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
if (abortSignal.aborted) {
|
|
87
|
+
throw new Error(`REQUEST_ABORTED: Promise.resolve 실행 중 중단되었습니다 (${contextId})`);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
// Promise.reject 패치
|
|
93
|
+
const originalReject = global.Promise.reject;
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
95
|
+
global.Promise.reject = (reason) => {
|
|
96
|
+
const currentContext = abort_context_1.AbortContext.getCurrentContext();
|
|
97
|
+
if (!currentContext) {
|
|
98
|
+
return originalReject.call(global.Promise, reason);
|
|
99
|
+
}
|
|
100
|
+
const abortSignal = currentContext.abortSignal;
|
|
101
|
+
if (abortSignal.aborted) {
|
|
102
|
+
return Promise.reject(new Error(`REQUEST_ABORTED: Promise.reject가 중단되었습니다 (${currentContext.requestId})`));
|
|
103
|
+
}
|
|
104
|
+
return originalReject.call(global.Promise, reason);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
static patchSetTimeout() {
|
|
108
|
+
this.originalSetTimeout = global.setTimeout;
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
global.setTimeout = (callback, delay, ...args) => {
|
|
111
|
+
const currentContext = abort_context_1.AbortContext.getCurrentContext();
|
|
112
|
+
if (!currentContext) {
|
|
113
|
+
return this.originalSetTimeout(callback, delay, ...args);
|
|
114
|
+
}
|
|
115
|
+
const abortSignal = currentContext.abortSignal;
|
|
116
|
+
const contextId = currentContext.requestId;
|
|
117
|
+
if (abortSignal.aborted) {
|
|
118
|
+
throw new Error(`REQUEST_ABORTED: setTimeout이 중단되었습니다 (${contextId})`);
|
|
119
|
+
}
|
|
120
|
+
const wrappedCallback = () => {
|
|
121
|
+
// 컨텍스트가 여전히 유효한지 확인
|
|
122
|
+
const currentContextCheck = abort_context_1.AbortContext.getCurrentContext();
|
|
123
|
+
if (!currentContextCheck || currentContextCheck.requestId !== contextId) {
|
|
124
|
+
// 컨텍스트가 변경되었으면 원본 콜백 실행
|
|
125
|
+
// eslint-disable-next-line prefer-spread
|
|
126
|
+
callback.apply(null, args);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (abortSignal.aborted) {
|
|
130
|
+
throw new Error(`REQUEST_ABORTED: setTimeout 콜백이 중단되었습니다 (${contextId})`);
|
|
131
|
+
}
|
|
132
|
+
// eslint-disable-next-line prefer-spread
|
|
133
|
+
callback.apply(null, args);
|
|
134
|
+
};
|
|
135
|
+
const timerId = this.originalSetTimeout(wrappedCallback, delay, ...args);
|
|
136
|
+
// 중단 이벤트 리스너 등록
|
|
137
|
+
const abortHandler = () => {
|
|
138
|
+
clearTimeout(timerId);
|
|
139
|
+
};
|
|
140
|
+
abortSignal.addEventListener('abort', abortHandler, { once: true });
|
|
141
|
+
return timerId;
|
|
142
|
+
};
|
|
40
143
|
}
|
|
41
144
|
static unpatch() {
|
|
42
145
|
if (!this.isPatched) {
|
|
43
146
|
return;
|
|
44
147
|
}
|
|
45
148
|
global.Promise = this.originalPromise;
|
|
149
|
+
global.setTimeout = this.originalSetTimeout;
|
|
46
150
|
this.isPatched = false;
|
|
47
151
|
}
|
|
48
152
|
}
|