@swetrix/captcha 2.0.2 → 2.3.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.
- package/README.md +72 -5
- package/dist/captcha-loader.cjs +333 -0
- package/dist/captcha-loader.cjs.map +1 -0
- package/dist/captcha-loader.esm.js +327 -0
- package/dist/captcha-loader.esm.js.map +1 -0
- package/dist/captcha-loader.js +1 -1
- package/dist/captcha-loader.js.map +1 -1
- package/dist/captcha.js +1 -1
- package/dist/captcha.js.map +1 -1
- package/dist/esnext/captcha-loader.d.ts +10 -0
- package/dist/esnext/captcha-loader.js +315 -0
- package/dist/esnext/captcha-loader.js.map +1 -0
- package/dist/esnext/captcha.d.ts +10 -0
- package/dist/esnext/captcha.js +491 -0
- package/dist/esnext/captcha.js.map +1 -0
- package/dist/esnext/i18n.d.ts +22 -0
- package/dist/esnext/i18n.js +110 -0
- package/dist/esnext/i18n.js.map +1 -0
- package/dist/esnext/index.d.ts +7 -0
- package/dist/esnext/index.js +7 -0
- package/dist/esnext/index.js.map +1 -0
- package/dist/esnext/logger.d.ts +6 -0
- package/dist/esnext/logger.js +8 -0
- package/dist/esnext/logger.js.map +1 -0
- package/dist/esnext/pow-worker.d.ts +1 -0
- package/dist/esnext/pow-worker.js +127 -0
- package/dist/esnext/pow-worker.js.map +1 -0
- package/dist/pages/dark.html +461 -276
- package/dist/pages/light.html +463 -278
- package/dist/pages/test.html +26 -27
- package/package.json +58 -32
- package/.nvmrc +0 -1
- package/.prettierrc.js +0 -13
- package/dist/assets/logo_blue.png +0 -0
- package/dist/assets/logo_white.png +0 -0
- package/rollup.config.mjs +0 -83
- package/src/assets/logo_blue.png +0 -0
- package/src/assets/logo_white.png +0 -0
- package/src/captcha-loader.ts +0 -212
- package/src/captcha.ts +0 -358
- package/src/pages/dark.html +0 -284
- package/src/pages/light.html +0 -286
- package/src/pages/test.html +0 -33
- package/src/pow-worker.ts +0 -178
- package/tsconfig.esnext.json +0 -15
- package/tsconfig.json +0 -14
package/src/pages/light.html
DELETED
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8">
|
|
6
|
-
<title>Swetrix Captcha</title>
|
|
7
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
8
|
-
|
|
9
|
-
<style>
|
|
10
|
-
html {
|
|
11
|
-
font-family: '-apple-system', 'system-ui', 'BlinkMacSystemFont', 'Inter', 'Cantarell', 'Helvetica Neue', 'Roboto', 'Oxygen', 'Ubuntu', sans-serif;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
body {
|
|
17
|
-
margin: 0;
|
|
18
|
-
padding: 0;
|
|
19
|
-
height: auto;
|
|
20
|
-
overflow: auto;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
#swetrix-captcha {
|
|
24
|
-
display: flex;
|
|
25
|
-
justify-content: center;
|
|
26
|
-
align-items: center;
|
|
27
|
-
position: relative;
|
|
28
|
-
|
|
29
|
-
/* 300 - 20px (padding) */
|
|
30
|
-
width: 280px;
|
|
31
|
-
|
|
32
|
-
/* bg-gray-100 */
|
|
33
|
-
background-color: #f9fafb;
|
|
34
|
-
border: 1px solid #e9e9e9;
|
|
35
|
-
height: 64px;
|
|
36
|
-
-webkit-user-select: none;
|
|
37
|
-
user-select: none;
|
|
38
|
-
padding-left: 10px;
|
|
39
|
-
padding-right: 10px;
|
|
40
|
-
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
#swetrix-captcha:hover {
|
|
45
|
-
/* bg-gray-200 */
|
|
46
|
-
background-color: #f3f4f6;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
#challenge {
|
|
50
|
-
display: flex;
|
|
51
|
-
align-items: center;
|
|
52
|
-
cursor: pointer;
|
|
53
|
-
flex: 1;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
#action {
|
|
57
|
-
margin-right: 10px;
|
|
58
|
-
position: relative;
|
|
59
|
-
width: 28px;
|
|
60
|
-
height: 28px;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
#checkbox {
|
|
64
|
-
background-color: #fff;
|
|
65
|
-
border: 1px solid #c4c4c4;
|
|
66
|
-
height: 25px;
|
|
67
|
-
width: 25px;
|
|
68
|
-
border-radius: 3px;
|
|
69
|
-
position: absolute;
|
|
70
|
-
top: 50%;
|
|
71
|
-
left: 50%;
|
|
72
|
-
transform: translate(-50%, -50%);
|
|
73
|
-
transition: opacity 0.25s ease, transform 0.25s ease;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
#checkbox:hover {
|
|
77
|
-
border-color: #a0a0a0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#status {
|
|
81
|
-
font-size: 14px;
|
|
82
|
-
color: #0f0f0f;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
#status span {
|
|
86
|
-
transition: opacity 0.2s ease;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
#status-computing {
|
|
90
|
-
display: flex;
|
|
91
|
-
flex-direction: column;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.hidden {
|
|
95
|
-
display: none !important;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/* Fade out animation for hiding elements */
|
|
99
|
-
.fade-out {
|
|
100
|
-
opacity: 0 !important;
|
|
101
|
-
transform: translate(-50%, -50%) scale(0.8) !important;
|
|
102
|
-
pointer-events: none;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/* Fade in animation for showing elements */
|
|
106
|
-
.fade-in {
|
|
107
|
-
opacity: 1;
|
|
108
|
-
transform: translate(-50%, -50%) scale(1);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
#branding {
|
|
112
|
-
position: absolute;
|
|
113
|
-
bottom: 4px;
|
|
114
|
-
right: 10px;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#branding a {
|
|
118
|
-
font-size: 9px;
|
|
119
|
-
color: #6b7280;
|
|
120
|
-
text-decoration: none;
|
|
121
|
-
transition: color 0.2s ease;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
#branding a:hover {
|
|
125
|
-
color: #374151;
|
|
126
|
-
text-decoration: underline;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
#action svg {
|
|
130
|
-
width: 28px;
|
|
131
|
-
height: 28px;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
#failure > svg {
|
|
135
|
-
/* bg-red-500 */
|
|
136
|
-
color: #d6292a;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
#completed > svg {
|
|
140
|
-
/* bg-green-600 */
|
|
141
|
-
color: #16a24c;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
#completed,
|
|
145
|
-
#failure {
|
|
146
|
-
display: flex;
|
|
147
|
-
align-items: center;
|
|
148
|
-
justify-content: center;
|
|
149
|
-
position: absolute;
|
|
150
|
-
top: 50%;
|
|
151
|
-
left: 50%;
|
|
152
|
-
transform: translate(-50%, -50%) scale(0.8);
|
|
153
|
-
opacity: 0;
|
|
154
|
-
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
#completed.show,
|
|
158
|
-
#failure.show {
|
|
159
|
-
opacity: 1;
|
|
160
|
-
transform: translate(-50%, -50%) scale(1);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/* Checkmark draw animation */
|
|
164
|
-
#completed.show svg path {
|
|
165
|
-
stroke-dasharray: 24;
|
|
166
|
-
stroke-dashoffset: 24;
|
|
167
|
-
animation: drawCheck 0.4s ease forwards 0.1s;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
@keyframes drawCheck {
|
|
171
|
-
to {
|
|
172
|
-
stroke-dashoffset: 0;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/* Failure shake animation */
|
|
177
|
-
#failure.show {
|
|
178
|
-
animation: shake 0.4s ease;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@keyframes shake {
|
|
182
|
-
0%, 100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); }
|
|
183
|
-
25% { transform: translate(-50%, -50%) scale(1) rotate(-5deg); }
|
|
184
|
-
75% { transform: translate(-50%, -50%) scale(1) rotate(5deg); }
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/* Loading indicator - Material Design style spinner */
|
|
188
|
-
#loading {
|
|
189
|
-
position: absolute;
|
|
190
|
-
top: 50%;
|
|
191
|
-
left: 50%;
|
|
192
|
-
transform: translate(-50%, -50%);
|
|
193
|
-
width: 24px;
|
|
194
|
-
height: 24px;
|
|
195
|
-
opacity: 0;
|
|
196
|
-
transition: opacity 0.25s ease;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
#loading.show {
|
|
200
|
-
opacity: 1;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
#loading svg {
|
|
204
|
-
width: 24px;
|
|
205
|
-
height: 24px;
|
|
206
|
-
animation: rotate 1.4s linear infinite;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
#loading svg circle {
|
|
210
|
-
stroke: #3b82f6;
|
|
211
|
-
stroke-linecap: round;
|
|
212
|
-
animation: dash 1.4s ease-in-out infinite;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
@keyframes rotate {
|
|
216
|
-
100% {
|
|
217
|
-
transform: rotate(360deg);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
@keyframes dash {
|
|
222
|
-
0% {
|
|
223
|
-
stroke-dasharray: 1, 150;
|
|
224
|
-
stroke-dashoffset: 0;
|
|
225
|
-
}
|
|
226
|
-
50% {
|
|
227
|
-
stroke-dasharray: 90, 150;
|
|
228
|
-
stroke-dashoffset: -35;
|
|
229
|
-
}
|
|
230
|
-
100% {
|
|
231
|
-
stroke-dasharray: 90, 150;
|
|
232
|
-
stroke-dashoffset: -124;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
</style>
|
|
236
|
-
<script>
|
|
237
|
-
window.__SWETRIX_CAPTCHA_THEME = 'light'
|
|
238
|
-
const urlParams = new URLSearchParams(window.location.search)
|
|
239
|
-
const pid = urlParams.get('pid')
|
|
240
|
-
const cid = urlParams.get('cid')
|
|
241
|
-
|
|
242
|
-
window.__SWETRIX_CAPTCHA_ID = cid
|
|
243
|
-
window.__SWETRIX_PROJECT_ID = pid
|
|
244
|
-
</script>
|
|
245
|
-
<script src="../captcha.js" defer></script>
|
|
246
|
-
</head>
|
|
247
|
-
|
|
248
|
-
<body>
|
|
249
|
-
<div id="swetrix-captcha">
|
|
250
|
-
<div id="challenge">
|
|
251
|
-
<div id="action">
|
|
252
|
-
<!-- Can contain a checkbox itself / a red cross (with a retry action) / a green check mark -->
|
|
253
|
-
<div id="checkbox"></div>
|
|
254
|
-
<div id="failure">
|
|
255
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
256
|
-
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/>
|
|
257
|
-
<path d="M12 9v4"/>
|
|
258
|
-
<path d="M12 17h.01"/>
|
|
259
|
-
</svg>
|
|
260
|
-
</div>
|
|
261
|
-
<div id="completed">
|
|
262
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
263
|
-
<path d="M20 6 9 17l-5-5"/>
|
|
264
|
-
</svg>
|
|
265
|
-
</div>
|
|
266
|
-
<div id="loading">
|
|
267
|
-
<svg viewBox="0 0 50 50">
|
|
268
|
-
<circle cx="25" cy="25" r="20" fill="none" stroke-width="4"></circle>
|
|
269
|
-
</svg>
|
|
270
|
-
</div>
|
|
271
|
-
</div>
|
|
272
|
-
<div id="status">
|
|
273
|
-
<span id="status-default">I am human</span>
|
|
274
|
-
<span id="status-failure" class="hidden">Failure, please retry</span>
|
|
275
|
-
<span id="status-computing" class="hidden">
|
|
276
|
-
<span>Verifying...</span>
|
|
277
|
-
</span>
|
|
278
|
-
</div>
|
|
279
|
-
</div>
|
|
280
|
-
<div id="branding">
|
|
281
|
-
<a href="https://swetrix.com/captcha" target="_blank" rel="noopener noreferrer">Swetrix Captcha</a>
|
|
282
|
-
</div>
|
|
283
|
-
</div>
|
|
284
|
-
</body>
|
|
285
|
-
|
|
286
|
-
</html>
|
package/src/pages/test.html
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
<!-- Generate a form with several inputs -->
|
|
2
|
-
<html>
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8">
|
|
6
|
-
<title>Test</title>
|
|
7
|
-
<style>
|
|
8
|
-
.form {
|
|
9
|
-
display: flex;
|
|
10
|
-
flex-direction: column;
|
|
11
|
-
width: 400px;
|
|
12
|
-
margin: 0 auto;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.form>* {
|
|
16
|
-
margin-top: 10px;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
19
|
-
|
|
20
|
-
<script src="../../dist/captcha-loader.js" defer></script>
|
|
21
|
-
</head>
|
|
22
|
-
|
|
23
|
-
<body>
|
|
24
|
-
<form class="form" action="test.html" method="post">
|
|
25
|
-
<input type="text" name="name" value="name">
|
|
26
|
-
<input type="text" name="email" value="email">
|
|
27
|
-
<input type="number" name="number" value="number">
|
|
28
|
-
<div class="swecaptcha" data-project-id="AP00000000000" data-theme="light"></div>
|
|
29
|
-
<input type="submit" value="Submit">
|
|
30
|
-
</form>
|
|
31
|
-
</body>
|
|
32
|
-
|
|
33
|
-
</html>
|
package/src/pow-worker.ts
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
export {}
|
|
2
|
-
|
|
3
|
-
// PoW Worker - Computes the proof-of-work solution in a background thread
|
|
4
|
-
|
|
5
|
-
// Maximum allowed difficulty to prevent excessive computation
|
|
6
|
-
const MAX_DIFFICULTY = 32
|
|
7
|
-
|
|
8
|
-
// Default maximum iterations to prevent infinite loops (100 million)
|
|
9
|
-
const DEFAULT_MAX_ITERATIONS = 100_000_000
|
|
10
|
-
|
|
11
|
-
interface PowChallenge {
|
|
12
|
-
challenge: string
|
|
13
|
-
difficulty: number
|
|
14
|
-
maxIterations?: number // Optional: maximum iterations before timeout (default: 100 million)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface PowResult {
|
|
18
|
-
type: 'result'
|
|
19
|
-
nonce: number
|
|
20
|
-
solution: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface PowProgress {
|
|
24
|
-
type: 'progress'
|
|
25
|
-
attempts: number
|
|
26
|
-
hashRate: number
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface PowTimeout {
|
|
30
|
-
type: 'timeout'
|
|
31
|
-
reason: string
|
|
32
|
-
attempts: number
|
|
33
|
-
elapsedMs: number
|
|
34
|
-
hashRate: number
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface PowError {
|
|
38
|
-
type: 'error'
|
|
39
|
-
message: string
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
type PowMessage = PowResult | PowProgress | PowTimeout | PowError
|
|
43
|
-
|
|
44
|
-
// SHA-256 implementation using SubtleCrypto
|
|
45
|
-
async function sha256(message: string): Promise<string> {
|
|
46
|
-
const encoder = new TextEncoder()
|
|
47
|
-
const data = encoder.encode(message)
|
|
48
|
-
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
|
|
49
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
|
50
|
-
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Check if hash has required number of leading zeros
|
|
54
|
-
function hasValidPrefix(hash: string, difficulty: number): boolean {
|
|
55
|
-
for (let i = 0; i < difficulty; i++) {
|
|
56
|
-
if (hash[i] !== '0') {
|
|
57
|
-
return false
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return true
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Solve the PoW challenge
|
|
64
|
-
async function solveChallenge(challenge: string, difficulty: number, maxIterations: number): Promise<void> {
|
|
65
|
-
let nonce = 0
|
|
66
|
-
const startTime = Date.now()
|
|
67
|
-
const progressInterval = 10000 // Report progress every 10k attempts
|
|
68
|
-
|
|
69
|
-
while (nonce < maxIterations) {
|
|
70
|
-
const input = `${challenge}:${nonce}`
|
|
71
|
-
const hash = await sha256(input)
|
|
72
|
-
|
|
73
|
-
if (hasValidPrefix(hash, difficulty)) {
|
|
74
|
-
// Found the solution!
|
|
75
|
-
const result: PowResult = {
|
|
76
|
-
type: 'result',
|
|
77
|
-
nonce,
|
|
78
|
-
solution: hash,
|
|
79
|
-
}
|
|
80
|
-
self.postMessage(result)
|
|
81
|
-
return
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
nonce++
|
|
85
|
-
|
|
86
|
-
// Report progress periodically
|
|
87
|
-
if (nonce % progressInterval === 0) {
|
|
88
|
-
const elapsedMs = Date.now() - startTime
|
|
89
|
-
const elapsed = elapsedMs / 1000
|
|
90
|
-
const hashRate = Math.round(nonce / elapsed)
|
|
91
|
-
const progress: PowProgress = {
|
|
92
|
-
type: 'progress',
|
|
93
|
-
attempts: nonce,
|
|
94
|
-
hashRate,
|
|
95
|
-
}
|
|
96
|
-
self.postMessage(progress)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Max iterations reached - send timeout message
|
|
101
|
-
const elapsedMs = Date.now() - startTime
|
|
102
|
-
const elapsed = elapsedMs / 1000
|
|
103
|
-
const hashRate = elapsed > 0 ? Math.round(nonce / elapsed) : 0
|
|
104
|
-
const timeout: PowTimeout = {
|
|
105
|
-
type: 'timeout',
|
|
106
|
-
reason: `Maximum iterations reached (${maxIterations.toLocaleString()})`,
|
|
107
|
-
attempts: nonce,
|
|
108
|
-
elapsedMs,
|
|
109
|
-
hashRate,
|
|
110
|
-
}
|
|
111
|
-
self.postMessage(timeout)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Listen for messages from the main thread
|
|
115
|
-
self.onmessage = async (event: MessageEvent<PowChallenge>) => {
|
|
116
|
-
// Validate event.data exists
|
|
117
|
-
if (!event.data) {
|
|
118
|
-
const error: PowError = {
|
|
119
|
-
type: 'error',
|
|
120
|
-
message: 'Invalid message: event.data is missing or empty',
|
|
121
|
-
}
|
|
122
|
-
self.postMessage(error)
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const { challenge, difficulty, maxIterations } = event.data
|
|
127
|
-
|
|
128
|
-
// Validate challenge is provided and is a non-empty string
|
|
129
|
-
if (typeof challenge !== 'string' || challenge.length === 0) {
|
|
130
|
-
const error: PowError = {
|
|
131
|
-
type: 'error',
|
|
132
|
-
message: 'Invalid message: challenge must be a non-empty string',
|
|
133
|
-
}
|
|
134
|
-
self.postMessage(error)
|
|
135
|
-
return
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Validate difficulty is a positive integer within acceptable range
|
|
139
|
-
if (typeof difficulty !== 'number' || !Number.isInteger(difficulty)) {
|
|
140
|
-
const error: PowError = {
|
|
141
|
-
type: 'error',
|
|
142
|
-
message: 'Invalid message: difficulty must be an integer',
|
|
143
|
-
}
|
|
144
|
-
self.postMessage(error)
|
|
145
|
-
return
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (difficulty < 1 || difficulty > MAX_DIFFICULTY) {
|
|
149
|
-
const error: PowError = {
|
|
150
|
-
type: 'error',
|
|
151
|
-
message: `Invalid message: difficulty must be between 1 and ${MAX_DIFFICULTY}`,
|
|
152
|
-
}
|
|
153
|
-
self.postMessage(error)
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Validate maxIterations if provided
|
|
158
|
-
const effectiveMaxIterations = maxIterations ?? DEFAULT_MAX_ITERATIONS
|
|
159
|
-
if (typeof effectiveMaxIterations !== 'number' || !Number.isInteger(effectiveMaxIterations)) {
|
|
160
|
-
const error: PowError = {
|
|
161
|
-
type: 'error',
|
|
162
|
-
message: 'Invalid message: maxIterations must be an integer',
|
|
163
|
-
}
|
|
164
|
-
self.postMessage(error)
|
|
165
|
-
return
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (effectiveMaxIterations < 1) {
|
|
169
|
-
const error: PowError = {
|
|
170
|
-
type: 'error',
|
|
171
|
-
message: 'Invalid message: maxIterations must be at least 1',
|
|
172
|
-
}
|
|
173
|
-
self.postMessage(error)
|
|
174
|
-
return
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
await solveChallenge(challenge, difficulty, effectiveMaxIterations)
|
|
178
|
-
}
|
package/tsconfig.esnext.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"moduleResolution": "node",
|
|
4
|
-
"target": "ES2020",
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"lib": ["ES2020", "DOM"],
|
|
7
|
-
"strict": true,
|
|
8
|
-
"sourceMap": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"outDir": "dist/esnext",
|
|
11
|
-
"typeRoots": ["node_modules/@types"],
|
|
12
|
-
"skipLibCheck": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src"]
|
|
15
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"moduleResolution": "node",
|
|
4
|
-
"target": "ES2018",
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"lib": ["ES2018", "DOM"],
|
|
7
|
-
"strict": true,
|
|
8
|
-
"sourceMap": true,
|
|
9
|
-
"declaration": false,
|
|
10
|
-
"allowSyntheticDefaultImports": true,
|
|
11
|
-
"skipLibCheck": true
|
|
12
|
-
},
|
|
13
|
-
"include": ["src"]
|
|
14
|
-
}
|