@prosopo/provider 5.3.6 → 5.3.8

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.
Files changed (32) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +8 -8
  2. package/.turbo/turbo-build$colon$tsc.log +25 -25
  3. package/.turbo/turbo-build.log +8 -8
  4. package/CHANGELOG.md +22 -0
  5. package/dist/cjs/tasks/client/clientTasks.cjs +26 -10
  6. package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +75 -14
  7. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +10 -1
  8. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +10 -1
  9. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +10 -1
  10. package/dist/cjs/tasks/tasks.cjs +1 -1
  11. package/dist/tasks/client/clientTasks.d.ts.map +1 -1
  12. package/dist/tasks/client/clientTasks.js +26 -10
  13. package/dist/tasks/client/clientTasks.js.map +1 -1
  14. package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts +3 -0
  15. package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts.map +1 -1
  16. package/dist/tasks/decisionMachine/decisionMachineRunner.js +74 -15
  17. package/dist/tasks/decisionMachine/decisionMachineRunner.js.map +1 -1
  18. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
  19. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +10 -1
  20. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
  21. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  22. package/dist/tasks/powCaptcha/powTasks.js +10 -1
  23. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  24. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
  25. package/dist/tasks/puzzleCaptcha/puzzleTasks.js +10 -1
  26. package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
  27. package/dist/tasks/tasks.js +1 -1
  28. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +20 -0
  29. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
  30. package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js +128 -1
  31. package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js.map +1 -1
  32. package/package.json +6 -6
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/provider@5.3.6 build:cjs
2
+ > @prosopo/provider@5.3.8 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -136,7 +136,7 @@ dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs 4
136
136
  dist/cjs/api/captcha.cjs 4.51 kB │ gzip: 1.40 kB
137
137
  dist/cjs/index.cjs 4.72 kB │ gzip: 0.98 kB
138
138
  dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs 4.84 kB │ gzip: 1.74 kB
139
- dist/cjs/tasks/tasks.cjs 5.07 kB │ gzip: 1.56 kB
139
+ dist/cjs/tasks/tasks.cjs 5.07 kB │ gzip: 1.57 kB
140
140
  dist/cjs/util/usageCounters.cjs 5.72 kB │ gzip: 2.03 kB
141
141
  dist/cjs/tasks/puzzle/puzzleRenderer.cjs 5.87 kB │ gzip: 2.13 kB
142
142
  dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs 6.13 kB │ gzip: 1.79 kB
@@ -146,24 +146,24 @@ dist/cjs/api/metrics.cjs 7
146
146
  dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs 7.55 kB │ gzip: 2.35 kB
147
147
  dist/cjs/tasks/spam/checkTrafficFilter.cjs 7.65 kB │ gzip: 2.55 kB
148
148
  dist/cjs/tasks/detection/bundlePool.cjs 8.72 kB │ gzip: 3.26 kB
149
- dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs 9.67 kB │ gzip: 2.91 kB
150
149
  dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs 11.45 kB │ gzip: 2.16 kB
151
150
  dist/cjs/api/startProviderApi.cjs 11.62 kB │ gzip: 3.70 kB
152
151
  dist/cjs/api/blacklistRequestInspector.cjs 12.28 kB │ gzip: 4.29 kB
153
- dist/cjs/tasks/client/clientTasks.cjs 12.86 kB │ gzip: 3.10 kB
152
+ dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs 12.32 kB │ gzip: 3.81 kB
154
153
  dist/cjs/util.cjs 13.25 kB │ gzip: 3.22 kB
155
154
  dist/cjs/api/verify.cjs 13.66 kB │ gzip: 2.57 kB
155
+ dist/cjs/tasks/client/clientTasks.cjs 13.81 kB │ gzip: 3.46 kB
156
156
  dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs 17.55 kB │ gzip: 4.15 kB
157
157
  dist/cjs/tasks/frictionless/frictionlessTasks.cjs 18.88 kB │ gzip: 5.03 kB
158
- dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs 21.96 kB │ gzip: 4.76 kB
159
158
  dist/cjs/tasks/captchaManager.cjs 22.21 kB │ gzip: 6.33 kB
160
- dist/cjs/tasks/powCaptcha/powTasks.cjs 23.18 kB │ gzip: 5.61 kB
161
- dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs 26.66 kB │ gzip: 6.18 kB
159
+ dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs 22.33 kB │ gzip: 4.84 kB
160
+ dist/cjs/tasks/powCaptcha/powTasks.cjs 23.54 kB │ gzip: 5.69 kB
161
+ dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs 27.03 kB │ gzip: 6.27 kB
162
162
  dist/cjs/tasks/detection/decodeBehavior.cjs 32.24 kB │ gzip: 10.32 kB
163
163
  dist/cjs/tasks/detection/decodeSimd.cjs 36.03 kB │ gzip: 11.96 kB
164
164
  dist/cjs/tasks/detection/decodePayload.cjs 49.79 kB │ gzip: 16.98 kB
165
165
 
166
- ✓ built in 166ms
166
+ ✓ built in 161ms
167
167
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeBehavior.js to /home/runner/work/captcha/captcha/packages/provider/dist/cjs/tasks/detection/decodeBehavior.js
168
168
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodePayload.js to /home/runner/work/captcha/captcha/packages/provider/dist/cjs/tasks/detection/decodePayload.js
169
169
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeSimd.js to /home/runner/work/captcha/captcha/packages/provider/dist/cjs/tasks/detection/decodeSimd.js
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/provider@5.3.6 build:tsc
2
+ > @prosopo/provider@5.3.8 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 12:31:48 PM - Projects in this build:
5
+ 8:35:42 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../util/tsconfig.json
8
8
  * ../logger/tsconfig.json
@@ -26,49 +26,49 @@
26
26
  * ../puzzle-assets/tsconfig.json
27
27
  * tsconfig.json
28
28
 
29
- 12:31:48 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
29
+ 8:35:42 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
30
30
 
31
- 12:31:48 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
31
+ 8:35:42 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
32
32
 
33
- 12:31:48 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/tests/loggerBrowser.unit.test.ts' is older than output '../logger/tsconfig.tsbuildinfo'
33
+ 8:35:42 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
34
34
 
35
- 12:31:48 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
35
+ 8:35:42 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
36
36
 
37
- 12:31:48 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
37
+ 8:35:42 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
38
38
 
39
- 12:31:48 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
39
+ 8:35:42 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
40
40
 
41
- 12:31:48 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/index.ts' is older than output '../types/tsconfig.tsbuildinfo'
41
+ 8:35:42 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
42
42
 
43
- 12:31:48 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
43
+ 8:35:42 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
44
44
 
45
- 12:31:48 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/types.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
45
+ 8:35:42 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/index.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
46
46
 
47
- 12:31:48 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/redisClient.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
47
+ 8:35:42 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
48
48
 
49
- 12:31:48 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
49
+ 8:35:42 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
50
50
 
51
- 12:31:48 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/ruleRecord.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
51
+ 8:35:42 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
52
52
 
53
- 12:31:48 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/types.test-d.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
53
+ 8:35:42 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/index.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
54
54
 
55
- 12:31:48 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/mongoGlobalSetup.ts' is older than output '../database/tsconfig.tsbuildinfo'
55
+ 8:35:42 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/unit/redisCacheEscalation.unit.test.ts' is older than output '../database/tsconfig.tsbuildinfo'
56
56
 
57
- 12:31:48 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/keyring/keyring.test.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
57
+ 8:35:42 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
58
58
 
59
- 12:31:48 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/index.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
59
+ 8:35:42 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/env.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
60
60
 
61
- 12:31:48 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/index.ts' is older than output '../env/tsconfig.tsbuildinfo'
61
+ 8:35:42 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/env.ts' is older than output '../env/tsconfig.tsbuildinfo'
62
62
 
63
- 12:31:48 PM - Project '../api-express-router/tsconfig.json' is up to date because newest input '../api-express-router/src/apiExpressRouterFactory.ts' is older than output '../api-express-router/tsconfig.tsbuildinfo'
63
+ 8:35:42 PM - Project '../api-express-router/tsconfig.json' is up to date because newest input '../api-express-router/src/middlewares/requestLoggerMiddleware.ts' is older than output '../api-express-router/tsconfig.tsbuildinfo'
64
64
 
65
- 12:31:48 PM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/tests/dataset.unit.test.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
65
+ 8:35:42 PM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/tests/dataset.unit.test.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
66
66
 
67
- 12:31:48 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
67
+ 8:35:42 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
68
68
 
69
- 12:31:48 PM - Project '../puzzle-assets/tsconfig.json' is up to date because newest input '../puzzle-assets/src/background.ts' is older than output '../puzzle-assets/tsconfig.tsbuildinfo'
69
+ 8:35:42 PM - Project '../puzzle-assets/tsconfig.json' is up to date because newest input '../puzzle-assets/src/background.ts' is older than output '../puzzle-assets/tsconfig.tsbuildinfo'
70
70
 
71
- 12:31:48 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
71
+ 8:35:42 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
72
72
 
73
- 12:31:48 PM - Building project '/home/runner/work/captcha/captcha/packages/provider/tsconfig.json'...
73
+ 8:35:42 PM - Building project '/home/runner/work/captcha/captcha/packages/provider/tsconfig.json'...
74
74
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/provider@5.3.6 build
2
+ > @prosopo/provider@5.3.8 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/provider@5.3.6 build:cross-env
6
+ > @prosopo/provider@5.3.8 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -150,24 +150,24 @@ dist/api/metrics.js 6.96 k
150
150
  dist/api/captcha/submitPoWCaptchaSolution.js 7.15 kB │ gzip: 2.31 kB
151
151
  dist/tasks/spam/checkTrafficFilter.js 7.32 kB │ gzip: 2.53 kB
152
152
  dist/tasks/detection/bundlePool.js 8.30 kB │ gzip: 3.21 kB
153
- dist/tasks/decisionMachine/decisionMachineRunner.js 9.40 kB │ gzip: 2.86 kB
154
153
  dist/api/startProviderApi.js 9.93 kB │ gzip: 3.42 kB
155
154
  dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js 10.48 kB │ gzip: 2.13 kB
156
155
  dist/api/blacklistRequestInspector.js 11.72 kB │ gzip: 4.25 kB
157
- dist/tasks/client/clientTasks.js 12.33 kB │ gzip: 3.07 kB
156
+ dist/tasks/decisionMachine/decisionMachineRunner.js 11.93 kB │ gzip: 3.75 kB
158
157
  dist/api/verify.js 12.34 kB │ gzip: 2.47 kB
159
158
  dist/util.js 12.57 kB │ gzip: 3.17 kB
159
+ dist/tasks/client/clientTasks.js 13.27 kB │ gzip: 3.43 kB
160
160
  dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js 16.41 kB │ gzip: 4.06 kB
161
161
  dist/tasks/frictionless/frictionlessTasks.js 18.47 kB │ gzip: 5.01 kB
162
- dist/tasks/puzzleCaptcha/puzzleTasks.js 20.67 kB │ gzip: 4.71 kB
162
+ dist/tasks/puzzleCaptcha/puzzleTasks.js 21.03 kB │ gzip: 4.80 kB
163
163
  dist/tasks/captchaManager.js 21.73 kB │ gzip: 6.27 kB
164
- dist/tasks/powCaptcha/powTasks.js 21.89 kB │ gzip: 5.56 kB
165
- dist/tasks/imgCaptcha/imgCaptchaTasks.js 25.32 kB │ gzip: 6.13 kB
164
+ dist/tasks/powCaptcha/powTasks.js 22.25 kB │ gzip: 5.64 kB
165
+ dist/tasks/imgCaptcha/imgCaptchaTasks.js 25.68 kB │ gzip: 6.22 kB
166
166
  dist/tasks/detection/decodeBehavior.js 32.26 kB │ gzip: 10.34 kB
167
167
  dist/tasks/detection/decodeSimd.js 36.06 kB │ gzip: 12.00 kB
168
168
  dist/tasks/detection/decodePayload.js 49.69 kB │ gzip: 16.96 kB
169
169
 
170
- ✓ built in 128ms
170
+ ✓ built in 134ms
171
171
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeBehavior.js to /home/runner/work/captcha/captcha/packages/provider/dist/tasks/detection/decodeBehavior.js
172
172
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodePayload.js to /home/runner/work/captcha/captcha/packages/provider/dist/tasks/detection/decodePayload.js
173
173
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeSimd.js to /home/runner/work/captcha/captcha/packages/provider/dist/tasks/detection/decodeSimd.js
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @prosopo/provider
2
2
 
3
+ ## 5.3.8
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [127985f]
7
+ - @prosopo/database@4.0.16
8
+ - @prosopo/env@3.6.39
9
+ - @prosopo/api-express-router@3.1.70
10
+
11
+ ## 5.3.7
12
+ ### Patch Changes
13
+
14
+ - 1afe466: Cache compiled decision-machine sandboxes; keyset-paginate the pending-stage sweep.
15
+
16
+ - `DecisionMachineRunner` now hits `vm.createContext` + `new vm.Script` at most once per source blob (keyed by SHA-256). Exports `invalidateDecisionMachineScriptCache` and `invalidateAllDecisionMachineArtifactCaches`, both called from `updateDecisionMachine` after any artifact upload.
17
+ - `getUnstoredDappUserCommitments` / `getUnstoredDappUserPoWCommitments` / `getUnstoredSessionRecords` switch from `skip(N)` pagination to keyset (`_id > afterId`). Compound partial index `{pendingStage:1, _id:1}` on all four collections so filter + sort ride one index. Fixes the sweep that was scanning 470k–1.2M docs per page under a large pending backlog.
18
+ - Updated dependencies [1afe466]
19
+ - @prosopo/database@4.0.15
20
+ - @prosopo/types-database@5.1.9
21
+ - @prosopo/env@3.6.38
22
+ - @prosopo/types-env@2.10.34
23
+ - @prosopo/api-express-router@3.1.69
24
+
3
25
  ## 5.3.6
4
26
  ### Patch Changes
5
27
 
@@ -1,4 +1,5 @@
1
1
  const require_validateAddress = require("../../api/validateAddress.cjs");
2
+ const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
2
3
  let _prosopo_common = require("@prosopo/common");
3
4
  let _prosopo_database = require("@prosopo/database");
4
5
  let _prosopo_types = require("@prosopo/types");
@@ -37,32 +38,32 @@ var ClientTaskManager = class {
37
38
  const captchaDB = this.getCaptchaDB(this.config.mongoCaptchaUri);
38
39
  const sweepStartedAt = /* @__PURE__ */ new Date();
39
40
  let processedCommitments = 0;
40
- await this.processBatchesWithCursor(async (skip) => await this.providerDB.getUnstoredDappUserCommitments(BATCH_SIZE, skip), async (batch) => {
41
+ await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserCommitments(BATCH_SIZE, afterId), async (batch) => {
41
42
  const filteredBatch = (lastTask?.updated ? batch.filter((commitment) => this.isRecordUpdated(commitment)) : batch).filter((commitment) => commitment.id !== "");
42
43
  if (filteredBatch.length > 0) {
43
44
  await captchaDB.saveCaptchas([], filteredBatch, []);
44
45
  await this.providerDB.markDappUserCommitmentsStored(filteredBatch.map((commitment) => commitment.id), sweepStartedAt);
45
46
  }
46
47
  processedCommitments += filteredBatch.length;
47
- });
48
+ }, (row) => row._id);
48
49
  let processedPowRecords = 0;
49
- await this.processBatchesWithCursor(async (skip) => await this.providerDB.getUnstoredDappUserPoWCommitments(BATCH_SIZE, skip), async (batch) => {
50
+ await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserPoWCommitments(BATCH_SIZE, afterId), async (batch) => {
50
51
  const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
51
52
  if (filteredBatch.length > 0) {
52
53
  await captchaDB.saveCaptchas([], [], filteredBatch);
53
54
  await this.providerDB.markDappUserPoWCommitmentsStored(filteredBatch.map((record) => record.challenge), sweepStartedAt);
54
55
  }
55
56
  processedPowRecords += filteredBatch.length;
56
- });
57
+ }, (row) => row._id);
57
58
  let processedSessionRecords = 0;
58
- await this.processBatchesWithCursor(async (skip) => await this.providerDB.getUnstoredSessionRecords(BATCH_SIZE, skip), async (batch) => {
59
+ await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredSessionRecords(BATCH_SIZE, afterId), async (batch) => {
59
60
  const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
60
61
  if (filteredBatch.length > 0) {
61
62
  await captchaDB.saveCaptchas(filteredBatch, [], []);
62
63
  await this.providerDB.markSessionRecordsStored(filteredBatch.map((record) => record.sessionId), sweepStartedAt);
63
64
  }
64
65
  processedSessionRecords += filteredBatch.length;
65
- });
66
+ }, (row) => row._id);
66
67
  await this.providerDB.updateScheduledTaskStatus(taskID, _prosopo_types.ScheduledTaskStatus.Completed, { data: {
67
68
  processedSessionRecords,
68
69
  processedCommitments,
@@ -205,6 +206,8 @@ var ClientTaskManager = class {
205
206
  createdAt: now,
206
207
  updatedAt: now
207
208
  });
209
+ require_decisionMachineRunner.invalidateAllDecisionMachineArtifactCaches();
210
+ require_decisionMachineRunner.invalidateDecisionMachineScriptCache();
208
211
  return {
209
212
  scope,
210
213
  dappAccount,
@@ -307,13 +310,26 @@ var ClientTaskManager = class {
307
310
  const { lastUpdatedTimestamp, storedAtTimestamp } = record;
308
311
  return !lastUpdatedTimestamp || !storedAtTimestamp || lastUpdatedTimestamp.getTime() > storedAtTimestamp.getTime();
309
312
  }
310
- async processBatchesWithCursor(fetchBatch, processBatch) {
311
- let skip = 0;
313
+ /**
314
+ * Drive a keyset-paginated sweep. Each iteration passes the `_id` of the
315
+ * previous batch's last row to `fetchBatch` so the query resumes from
316
+ * `_id > afterId` — see `getUnstoredDappUserCommitments` for why we
317
+ * moved off `skip(N)`. `getLastId` extracts the resumption cursor from
318
+ * a batch row; both `PoWCaptchaRecord` and `UserCommitmentRecord` are
319
+ * `mongoose.Document` subtypes so `_id` is always present at runtime
320
+ * even though our stored types don't spell it out.
321
+ */
322
+ async processBatchesWithCursor(fetchBatch, processBatch, getLastId) {
323
+ let afterId;
312
324
  while (true) {
313
- const batch = await fetchBatch(skip);
325
+ const batch = await fetchBatch(afterId);
314
326
  if (!batch.length) break;
315
327
  await processBatch(batch);
316
- skip += batch.length;
328
+ const last = batch[batch.length - 1];
329
+ if (last === void 0) break;
330
+ const nextId = getLastId(last);
331
+ if (nextId === void 0) break;
332
+ afterId = nextId;
317
333
  }
318
334
  }
319
335
  };
@@ -1,19 +1,81 @@
1
1
  const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
2
  let _prosopo_types = require("@prosopo/types");
3
+ let node_crypto = require("node:crypto");
3
4
  let node_vm = require("node:vm");
4
5
  node_vm = require_runtime.__toESM(node_vm, 1);
5
6
  let zod = require("zod");
6
7
  //#region src/tasks/decisionMachine/decisionMachineRunner.ts
7
8
  var LOAD_TIMEOUT_MS = Number.parseInt(process.env.DECISION_MACHINE_LOAD_TIMEOUT_MS ?? "", 10) || 1e3;
8
9
  var EXEC_TIMEOUT_MS = Number.parseInt(process.env.DECISION_MACHINE_EXEC_TIMEOUT_MS ?? "", 10) || 2e3;
10
+ var machineCache = /* @__PURE__ */ new Map();
11
+ var hashSource = (source) => (0, node_crypto.createHash)("sha256").update(source).digest("hex");
12
+ /**
13
+ * Compile + execute the artifact source in a fresh vm sandbox on first use,
14
+ * then reuse the resulting `module.exports` for every subsequent invocation
15
+ * of the same source. See {@link machineCache}.
16
+ */
17
+ var loadMachine = (source) => {
18
+ const key = hashSource(source);
19
+ const cached = machineCache.get(key);
20
+ if (cached) return cached;
21
+ const sandbox = {
22
+ module: { exports: {} },
23
+ exports: {}
24
+ };
25
+ const context = node_vm.default.createContext(sandbox);
26
+ new node_vm.default.Script(source, { filename: "decision-machine.js" }).runInContext(context, { timeout: LOAD_TIMEOUT_MS });
27
+ const exported = sandbox.module.exports;
28
+ const entry = { exports: typeof exported === "function" ? { default: exported } : exported && typeof exported === "object" ? exported : {} };
29
+ machineCache.set(key, entry);
30
+ return entry;
31
+ };
32
+ /**
33
+ * Clear the module-level script cache. Call after any decision-machine
34
+ * artifact upload so the new source is executed on the next request instead
35
+ * of waiting for the artifact TTL. Also clear every `DecisionMachineRunner`
36
+ * instance's artifact cache — see {@link DecisionMachineRunner.invalidateAllArtifactCaches}.
37
+ */
38
+ var invalidateDecisionMachineScriptCache = () => {
39
+ machineCache.clear();
40
+ };
9
41
  /** How long cached artifacts are considered fresh (ms). */
10
42
  var ARTIFACT_CACHE_TTL_MS = Number.parseInt(process.env.DECISION_MACHINE_ARTIFACT_CACHE_TTL_MS ?? "", 10) || 300 * 1e3;
11
43
  var DEFAULT_DECISION = { decision: _prosopo_types.DecisionMachineDecision.Allow };
12
44
  var RequiredCountersSchema = zod.z.array(_prosopo_types.CounterSpecSchema);
45
+ /**
46
+ * WeakSet-style registry of every live runner. Populated in the constructor
47
+ * and consulted by {@link invalidateAllDecisionMachineArtifactCaches} so an
48
+ * artifact upload can flush every runner's in-memory artifact cache in one
49
+ * call. Held as `WeakRef` so a runner that goes out of scope is garbage
50
+ * collected — this map only ever grows in prod (runners are constructed
51
+ * per task class at process start and live for the process's lifetime) so
52
+ * a plain array would also work, but `WeakRef` is defensive.
53
+ */
54
+ var liveRunners = /* @__PURE__ */ new Set();
55
+ /**
56
+ * Flush every runner's in-memory artifact cache. Companion to
57
+ * {@link invalidateDecisionMachineScriptCache}. Call both after any
58
+ * `upsertDecisionMachineArtifact` upload.
59
+ */
60
+ var invalidateAllDecisionMachineArtifactCaches = () => {
61
+ for (const ref of liveRunners) {
62
+ const runner = ref.deref();
63
+ if (runner === void 0) {
64
+ liveRunners.delete(ref);
65
+ continue;
66
+ }
67
+ runner.invalidateArtifactCache();
68
+ }
69
+ };
13
70
  var DecisionMachineRunner = class DecisionMachineRunner {
14
71
  constructor(db) {
15
72
  this.db = db;
16
73
  this.artifactCache = /* @__PURE__ */ new Map();
74
+ liveRunners.add(new WeakRef(this));
75
+ }
76
+ /** Drop every entry in this runner's artifact cache. */
77
+ invalidateArtifactCache() {
78
+ this.artifactCache.clear();
17
79
  }
18
80
  /** Build a cache key for a given scope + kind + dappAccount tuple. */
19
81
  static cacheKey(scope, kind, dappAccount) {
@@ -168,22 +230,19 @@ var DecisionMachineRunner = class DecisionMachineRunner {
168
230
  return artifact.captchaType === captchaType;
169
231
  }
170
232
  /**
171
- * Load the artifact source into a fresh vm sandbox, locate a callable
172
- * matching one of {exportNames} (or `module.exports` itself if it's a
173
- * function), invoke it with {input}, and validate the result with
174
- * {schema}. Returns undefined when {options.optional} is true and no
175
- * matching export exists. Otherwise throws on missing export, invalid
176
- * output, or sandbox failure.
233
+ * Look up the (cached) module exports for `artifact.source`, locate a
234
+ * callable matching one of {exportNames} (or the cached `default` slot
235
+ * if `module.exports` was itself a function), invoke it with {input},
236
+ * and validate the result with {schema}. Returns undefined when
237
+ * {options.optional} is true and no matching export exists. Otherwise
238
+ * throws on missing export, invalid output, or sandbox failure.
239
+ *
240
+ * The vm.Script compilation + top-level `runInContext` runs at most
241
+ * once per source blob (see {@link loadMachine} / {@link machineCache}).
177
242
  */
178
243
  async runArtifactExport(artifact, exportNames, options, schema) {
179
- const sandbox = {
180
- module: { exports: {} },
181
- exports: {}
182
- };
183
- const context = node_vm.default.createContext(sandbox);
184
- new node_vm.default.Script(artifact.source, { filename: "decision-machine.js" }).runInContext(context, { timeout: LOAD_TIMEOUT_MS });
185
- const exported = sandbox.module.exports;
186
- const named = this.findExport(exported, exportNames);
244
+ const { exports } = loadMachine(artifact.source);
245
+ const named = this.findExport(exports, exportNames);
187
246
  if (!named) {
188
247
  if (options.optional) return void 0;
189
248
  throw new Error(`Decision machine must export one of: ${exportNames.join(", ")}`);
@@ -220,3 +279,5 @@ var DecisionMachineRunner = class DecisionMachineRunner {
220
279
  };
221
280
  //#endregion
222
281
  exports.DecisionMachineRunner = DecisionMachineRunner;
282
+ exports.invalidateAllDecisionMachineArtifactCaches = invalidateAllDecisionMachineArtifactCaches;
283
+ exports.invalidateDecisionMachineScriptCache = invalidateDecisionMachineScriptCache;
@@ -526,7 +526,16 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
526
526
  ruleType: sessionRecord?.ruleType,
527
527
  webView: sessionRecord?.webView,
528
528
  iFrame: sessionRecord?.iFrame,
529
- coords: solution.coords
529
+ coords: solution.coords,
530
+ synNs: sessionRecord?.synNs,
531
+ synackNs: sessionRecord?.synackNs,
532
+ ackNs: sessionRecord?.ackNs,
533
+ observedTtl: sessionRecord?.observedTtl,
534
+ tcpMss: sessionRecord?.tcpMss,
535
+ tcpWscale: sessionRecord?.tcpWscale,
536
+ tcpOptsFlags: sessionRecord?.tcpOptsFlags,
537
+ tcpOptsOrder: sessionRecord?.tcpOptsOrder,
538
+ tcpWindow: sessionRecord?.tcpWindow
530
539
  };
531
540
  try {
532
541
  const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
@@ -475,7 +475,16 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
475
475
  ruleType: sessionRecord?.ruleType,
476
476
  webView: sessionRecord?.webView,
477
477
  iFrame: sessionRecord?.iFrame,
478
- coords: challengeRecord.coords
478
+ coords: challengeRecord.coords,
479
+ synNs: sessionRecord?.synNs,
480
+ synackNs: sessionRecord?.synackNs,
481
+ ackNs: sessionRecord?.ackNs,
482
+ observedTtl: sessionRecord?.observedTtl,
483
+ tcpMss: sessionRecord?.tcpMss,
484
+ tcpWscale: sessionRecord?.tcpWscale,
485
+ tcpOptsFlags: sessionRecord?.tcpOptsFlags,
486
+ tcpOptsOrder: sessionRecord?.tcpOptsOrder,
487
+ tcpWindow: sessionRecord?.tcpWindow
479
488
  };
480
489
  const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
481
490
  if (decision.decision === _prosopo_types.DecisionMachineDecision.Deny) {
@@ -435,7 +435,16 @@ var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
435
435
  webView: sessionRecord?.webView,
436
436
  iFrame: sessionRecord?.iFrame,
437
437
  coords: challengeRecord.coords,
438
- puzzleEvents: challengeRecord.puzzleEvents
438
+ puzzleEvents: challengeRecord.puzzleEvents,
439
+ synNs: sessionRecord?.synNs,
440
+ synackNs: sessionRecord?.synackNs,
441
+ ackNs: sessionRecord?.ackNs,
442
+ observedTtl: sessionRecord?.observedTtl,
443
+ tcpMss: sessionRecord?.tcpMss,
444
+ tcpWscale: sessionRecord?.tcpWscale,
445
+ tcpOptsFlags: sessionRecord?.tcpOptsFlags,
446
+ tcpOptsOrder: sessionRecord?.tcpOptsOrder,
447
+ tcpWindow: sessionRecord?.tcpWindow
439
448
  };
440
449
  const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
441
450
  if (decision.decision === _prosopo_types.DecisionMachineDecision.Deny) {
@@ -1,7 +1,7 @@
1
1
  const require_usageCounters = require("../util/usageCounters.cjs");
2
+ const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
2
3
  const require_clientTasks = require("./client/clientTasks.cjs");
3
4
  const require_datasetTasks = require("./dataset/datasetTasks.cjs");
4
- const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
5
5
  const require_frictionlessTasks = require("./frictionless/frictionlessTasks.cjs");
6
6
  const require_imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
7
7
  const require_powTasks = require("./powCaptcha/powTasks.cjs");
@@ -1 +1 @@
1
- {"version":3,"file":"clientTasks.d.ts","sourceRoot":"","sources":["../../../src/tasks/client/clientTasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clientTasks.d.ts","sourceRoot":"","sources":["../../../src/tasks/client/clientTasks.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { validateSiteKey } from "../../api/validateAddress.js";
2
+ import { invalidateAllDecisionMachineArtifactCaches, invalidateDecisionMachineScriptCache } from "../decisionMachine/decisionMachineRunner.js";
2
3
  import { ProsopoApiError } from "@prosopo/common";
3
4
  import { CaptchaDatabase, ClientDatabase } from "@prosopo/database";
4
5
  import { DecisionMachineScope, ScheduledTaskNames, ScheduledTaskStatus, Tier } from "@prosopo/types";
@@ -37,32 +38,32 @@ var ClientTaskManager = class {
37
38
  const captchaDB = this.getCaptchaDB(this.config.mongoCaptchaUri);
38
39
  const sweepStartedAt = /* @__PURE__ */ new Date();
39
40
  let processedCommitments = 0;
40
- await this.processBatchesWithCursor(async (skip) => await this.providerDB.getUnstoredDappUserCommitments(BATCH_SIZE, skip), async (batch) => {
41
+ await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserCommitments(BATCH_SIZE, afterId), async (batch) => {
41
42
  const filteredBatch = (lastTask?.updated ? batch.filter((commitment) => this.isRecordUpdated(commitment)) : batch).filter((commitment) => commitment.id !== "");
42
43
  if (filteredBatch.length > 0) {
43
44
  await captchaDB.saveCaptchas([], filteredBatch, []);
44
45
  await this.providerDB.markDappUserCommitmentsStored(filteredBatch.map((commitment) => commitment.id), sweepStartedAt);
45
46
  }
46
47
  processedCommitments += filteredBatch.length;
47
- });
48
+ }, (row) => row._id);
48
49
  let processedPowRecords = 0;
49
- await this.processBatchesWithCursor(async (skip) => await this.providerDB.getUnstoredDappUserPoWCommitments(BATCH_SIZE, skip), async (batch) => {
50
+ await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserPoWCommitments(BATCH_SIZE, afterId), async (batch) => {
50
51
  const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
51
52
  if (filteredBatch.length > 0) {
52
53
  await captchaDB.saveCaptchas([], [], filteredBatch);
53
54
  await this.providerDB.markDappUserPoWCommitmentsStored(filteredBatch.map((record) => record.challenge), sweepStartedAt);
54
55
  }
55
56
  processedPowRecords += filteredBatch.length;
56
- });
57
+ }, (row) => row._id);
57
58
  let processedSessionRecords = 0;
58
- await this.processBatchesWithCursor(async (skip) => await this.providerDB.getUnstoredSessionRecords(BATCH_SIZE, skip), async (batch) => {
59
+ await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredSessionRecords(BATCH_SIZE, afterId), async (batch) => {
59
60
  const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
60
61
  if (filteredBatch.length > 0) {
61
62
  await captchaDB.saveCaptchas(filteredBatch, [], []);
62
63
  await this.providerDB.markSessionRecordsStored(filteredBatch.map((record) => record.sessionId), sweepStartedAt);
63
64
  }
64
65
  processedSessionRecords += filteredBatch.length;
65
- });
66
+ }, (row) => row._id);
66
67
  await this.providerDB.updateScheduledTaskStatus(taskID, ScheduledTaskStatus.Completed, { data: {
67
68
  processedSessionRecords,
68
69
  processedCommitments,
@@ -205,6 +206,8 @@ var ClientTaskManager = class {
205
206
  createdAt: now,
206
207
  updatedAt: now
207
208
  });
209
+ invalidateAllDecisionMachineArtifactCaches();
210
+ invalidateDecisionMachineScriptCache();
208
211
  return {
209
212
  scope,
210
213
  dappAccount,
@@ -306,13 +309,26 @@ var ClientTaskManager = class {
306
309
  const { lastUpdatedTimestamp, storedAtTimestamp } = record;
307
310
  return !lastUpdatedTimestamp || !storedAtTimestamp || lastUpdatedTimestamp.getTime() > storedAtTimestamp.getTime();
308
311
  }
309
- async processBatchesWithCursor(fetchBatch, processBatch) {
310
- let skip = 0;
312
+ /**
313
+ * Drive a keyset-paginated sweep. Each iteration passes the `_id` of the
314
+ * previous batch's last row to `fetchBatch` so the query resumes from
315
+ * `_id > afterId` — see `getUnstoredDappUserCommitments` for why we
316
+ * moved off `skip(N)`. `getLastId` extracts the resumption cursor from
317
+ * a batch row; both `PoWCaptchaRecord` and `UserCommitmentRecord` are
318
+ * `mongoose.Document` subtypes so `_id` is always present at runtime
319
+ * even though our stored types don't spell it out.
320
+ */
321
+ async processBatchesWithCursor(fetchBatch, processBatch, getLastId) {
322
+ let afterId;
311
323
  while (true) {
312
- const batch = await fetchBatch(skip);
324
+ const batch = await fetchBatch(afterId);
313
325
  if (!batch.length) break;
314
326
  await processBatch(batch);
315
- skip += batch.length;
327
+ const last = batch[batch.length - 1];
328
+ if (last === void 0) break;
329
+ const nextId = getLastId(last);
330
+ if (nextId === void 0) break;
331
+ afterId = nextId;
316
332
  }
317
333
  }
318
334
  };