diff --git a/.browserslistrc b/.browserslistrc index 11f2b01..80a929c 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. [production] node >= 20.9.0 diff --git a/.dockerignore b/.dockerignore index 3dc267b..c05e46a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. # Locals diff --git a/.env.vault b/.env.vault index 4d10edb..be9e49a 100644 --- a/.env.vault +++ b/.env.vault @@ -8,12 +8,12 @@ DOTENV_VAULT_MAIN="3rfi+ClkONvfHPiU9FTBcC1+Um/L8QeM9dRw1jFzEqzZXw==" DOTENV_VAULT_MAIN_VERSION=1 # dev -DOTENV_VAULT_DEV="fCmtXbhrizbJN9K3cu3hAX70BvX6I4xCY4ZJxwat0s28QNWyT0A0yoC0jPgC8riX+vlu82DeEc9ZfpwTyyN8B0CXT65Guu3hmdXx76nqiAPeDSNRQbOSMX7uggOIUp+0j7Ue4WcTBP0xQq1+ID7Q/DHNLHqcqP6jyg2cAxHXQ6W7FOfoo2OKMyyCxyWRRQd4N2hEUTo3ByBAYrTxszMBpz7SjwYbcDkP3T9rnOVzXeeiZckWGOpydKvAkaJZQOg8bA0BEip28p31v461MkGGXa08P1c2EX3bCcNnyPOmJal17iRRmzhxDYdGIMJbIhC3FBiocBp/yTdfose7TN6LYm8GSHoze69firTcMHg3ScBhTPiT8s0V2b7Z9dA8jo8J1zD0VJfS20tE76Kt/S6tbcLnqhButsl2my4HMwZYVB4VwxPFqJ0hh8rYgNF12uc3EjwBsqrOM6TI5HItDSMvneFh+JQJA6DdvghnGvCPXWJ1AxVwikHKAw8IcYWVjCBcE5zxNsE5G1CasxUaZKNXt2uOt3GNfDLTlCqlI5anjuCpehY+6IHul5OQkj2OLA0X2vFZWn9NLPtMnyEEMI4UR5U5/bc1oW3Pf77fLbIXKSCwWMah6W3I/IjdPNFLDBVAr4XdRk3Rasd9ObPtLYYeAve+H24zT904wN3qqimikBf7Srv8i06Gvh+nCi1UQsUM9YrXDJi7zGV+gnhsARkU32209Lx5pKeQrOpXWSxDr24xN9iLDZR1KgNA3XBqUXE9E5hL7nT1mo+WECFM+ReUi9sZ8Y64x4ntOsUppD6R7eCkjiB6+3IUl+rxp1xhQulbCFbVAup8/DZrCti4gah6lPSESvjPO2SOtrbvTssx8jYkHuNwik8WnOifGwm6" -DOTENV_VAULT_DEV_VERSION=255 +DOTENV_VAULT_DEV="j0pdIMi5eRbQg/VAF6SUfeZszgx4kmG2tqXiXo9Ilk2vD3cqqKRCC5RtZyENE+9O6ri7JOl2VRK/jv8GjFTwcOyJgqWiaApmZaTNcKfGy/5S+3eE7Ggz8d1J5LdLzT1v81x2bp3OsbZ0CJiMNbZRjQE6i6no0WgjLNTMxzod9oXMQY/I4xoY09sXPK4pmiK057PFnsmjjhcdEw8BW65ZH8q8SZsGHvTERJWX02Ycv106NotbYeV7HBvjrEqY9BqKjYhvoHT5NasnsBKVVAKmI41neV+X/+oQAJlMLbDe6G3V0rMZR9ii+bMVxfLtizPfQYr703znG07XzrSiFUgYPobsxvirDHXSuSTLju38K78qy5dT+DTA7olK8ksGhC/u1nryWUX+RG1CKuaRpMEa32DUtN4EKoI3NCa8jWfDEIsujm7pTJmt8vo6D/DkKC5K/6I9PBFV4Axh4HNOtll7q/bynqDEfyO/RENuSKvqbkSPctC6qMpqMH5OjAE8EM3hqKOW9wOre0LMl3tr13hkmDbufcKA8BrEb7Z1Mzecj/08sBVM7O5L4fR1gGCQp5dCV9ZvmkkF5GjHZAs+xiC2LyTXwMihhO4oPEYbQqd4RWtjwEyhEN11RQIwIPGUOCBf17/NsXRpXSTucO5xcw+PkaawSckpzkqI+VxAKKZU56pVMBsEJEbQBD2y3SF1OSPfKQ3HSgqgMOGO3qN9mKIJ1nlFIosaTcjqVRhCBsdB+oNUbPfpZqziG02VSKpXzCXAvzSgMMuc3l4Ex/vw4zInqTUc3JeEyIJeJpXoqsycjy4RUZ3rj8s40Frznz4lbZkMA5flnRepTh0II5oitKae1y3c87Kl2CNdiN+7ZLf2rwxxJ0NFm99q+3eFYvoM" +DOTENV_VAULT_DEV_VERSION=259 # ci -DOTENV_VAULT_CI="TwBy0z8FyLaiAQoCunI1d+T6TG74bhnKBISFSx97p6UdBqHvuiXLcsoRD3trIL7mxBIMMlkfYEchXmfGAu6fAqjVxdVkF+FqH6W2XUyCRBVsSOdr1qHz7oepfvffR13uhYtOIIJRXOJSQPPfLsXao0duMjMKx2AkF/PkDJfo51xoIaicj7j3a3IZxsKNpXGHdvGrIjWgvDyYbM5MUE8iWahbfgAE5bOZMivrBBT4m3EzyQWhUrZIXSwgN+1sGsoyXCJe49V9Jg+Rcrzu15CTelGrBEty2CW/Z86yi3ALVy/dV3MtbN6PjnwGAY4O393iHYuDhJui81FbW08XzUTcxdMApdl1BYryGQdYS1SGV7AmK7vMsAA7uspIuhx12ddxagpt3eMTt/ovb8GdghOmD1u4IIQ4NOT7qL2BkRQGqdlllLcq5rzRHL9wGTZ0z6ItUF1KSMfD0+jYZz3Rty32tug5ErYcgUhdnAKstnk9BabjScUcR9ztHzi78kbewWn2nzHTbJLggl+gkgGRGJQonrGx+2l5GGpC4Pv9t2be+88vRoylQo1zbNhJE1WnJW9CCbd+oc/XgVGdcKy6BWd3RgY0CqMHQXxteok7xbqgLaEXWIml7qi/JIyVwnGK65zb4Ozw+eUHRn59ZZV668WIzu7VOdBdTapxw/FwtjYI3U5oeV+/KHRPg8jHA8EdM04Yvm12CIpCXrhZSJ2RreYVvJ8NmT3e+Xk3mPkNcfV8ZKL2dLKMLgU0bkS8nn5NMD6gMhqdxh9W36nADzhZMmoy0Hg0eU9lHZJdSk2tsYxEpiR4/YqQG9uN5+K66YoH792nU15BNxskPR9zbTj/4Ao6XITDnn+Pei1FkONR7YWXJ8yNTMujbq7uKSNxSxWf" -DOTENV_VAULT_CI_VERSION=255 +DOTENV_VAULT_CI="AxWEiINIggdK0Ogakoxkj46YOosq1qpAf630IDArBDfKR0g9S9UwxvAiYnSzNPsrTSYdfGSHUtzlKIAC3OVLzCMQqHIkJM5u689mJ+K4mimW9Bb3npjoVtLveb4J7cqmoTyPyRfYPIY8rrA2ZQReO8D01/axrSehy9PE1nvAXz6tJNXvpn+5pm59wOwD5k68dtPmo7eLsgRAa2fzpm/tA58fgPmfhUplVtgFj2Y+DwDa2f8nnE9oHKiUbn35B04Bloi4YDwpJ7iJsozLIAuxWygl00h9Fb3OpSe3v50OM4dA1vHKBpd/lgw0zc8Se+TL3ACIDwYiW0EE9DkI+yB3irkqNButelqjTfKxc3fRHt6NTI7MBqrTSLieg1NQkU0HDOz+JoqRqGFiu4dlf9+tgy0Lp1hQq8ne4u9FL9yqmGFspIuiOgxoY8bqZKxYbpXAzJ9hGOCSOHSja+SeOG57xQD2XCFv/ECoz8swWSMdY20yIqQY8Vn5/DWLL8xdUg1b7cF47qNs1sGlAmLfX4Ryo1If5B8K9SS93sNlTZcodXp0+QsBQsjYyVl2knMsBl5uxnGPfyAAFfxzs+AfQU7Ci6+3XbIm0VFMj0GZSMKYUvLS2B3dcKUklyXZFPparGhbCAL0bf6UM4A18WDJ+8fCEMpfoZ/lyv2NCGhDVzhLOLTR4qwSD9A5vzqA0U/KVBykxsltLNJ/DwsJsTghrfVMpb2S/oPNcNoUsrj1MbAjJtqav43Sayq/11OEWedcmZn45eQdsyzXUq+ztbM8BBK2UQNXI1Rjx59s9Xz6aUw4YuVFcXB4rb1NS+qUTUEzG1YZSWXD/xMoZNgJu7oKH7kiVGKq6Lfcqhh/1a4HI5cWq3X0TCKvcrFXnW8xGZua" +DOTENV_VAULT_CI_VERSION=259 # stage DOTENV_VAULT_STAGE="bfqZYD8oVLWMZ0JR5LICV+sB/btaXavszxZLxTfwSH8U5fg=" diff --git a/.gitattributes b/.gitattributes index 53f2ef8..e50c79e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. # Default diff --git a/.gitignore b/.gitignore index 927fa9e..98878b7 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. # Locals diff --git a/.npmignore b/.npmignore index 8a4275d..2db4497 100644 --- a/.npmignore +++ b/.npmignore @@ -25,7 +25,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. # Locals diff --git a/.prettierignore b/.prettierignore index 977e991..5a9f8f9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. # Packages diff --git a/.vscode/settings.json b/.vscode/settings.json index 5463f26..fa55c3d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ * @note This entire file will be updated automatically. * @note Instead of editing here, please review `./settings.mjs`. * - * Last generated using `./settings.mjs` Mar 7, 2024 12:46 PM UTC. + * Last generated using `./settings.mjs` Mar 7, 2024 9:03 PM UTC. */ { "editor.formatOnType": false, diff --git a/.vscodeignore b/.vscodeignore index e480f7c..b93ace1 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Mar 7, 2024 12:46 PM UTC. +# Last generated Mar 7, 2024 9:03 PM UTC. # Locals diff --git a/package-lock.json b/package-lock.json index f3a3ff8..b2c02d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@clevercanyon/utilities.cfw", - "version": "1.0.280", + "version": "1.0.282", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@clevercanyon/utilities.cfw", - "version": "1.0.280", + "version": "1.0.282", "cpu": [ "x64", "arm64" @@ -27,7 +27,7 @@ "url": "https://github.com/sponsors/clevercanyon" }, "peerDependencies": { - "@clevercanyon/utilities": "^1.0.887", + "@clevercanyon/utilities": "^1.0.890", "@cloudflare/ai": "1.0.53", "@upstash/ratelimit": "1.0.0", "@upstash/redis": "1.28.0" @@ -1017,9 +1017,9 @@ } }, "node_modules/@clevercanyon/utilities": { - "version": "1.0.887", - "resolved": "https://registry.npmjs.org/@clevercanyon/utilities/-/utilities-1.0.887.tgz", - "integrity": "sha512-JsJof9A2ba2je/Ns0oj/SpDc3REdWrJ9v8ooGelfKvBl0fnXyh8OyYaZP5QevWiVh1W2SB1goup53ekI6onHmA==", + "version": "1.0.890", + "resolved": "https://registry.npmjs.org/@clevercanyon/utilities/-/utilities-1.0.890.tgz", + "integrity": "sha512-UCYaXqPZ9aQFse5tIozWwAXZxzWNDcHWFVuyhQyq+yHr0u1wlhgJHfVV5FyZ8T+mdcGYfPd7o452kCvMNE9XGA==", "cpu": [ "x64", "arm64" @@ -1103,9 +1103,9 @@ } }, "node_modules/@clevercanyon/utilities.cfw": { - "version": "1.0.280", - "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.cfw/-/utilities.cfw-1.0.280.tgz", - "integrity": "sha512-J3KCV7csP5rSsGxLEpVNeHw1l/fuJMsqhyf9QpNiOkrS7aue4SA0hRNOMQY+vz3lGamjGChL44SDeoJvQgMzkQ==", + "version": "1.0.281", + "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.cfw/-/utilities.cfw-1.0.281.tgz", + "integrity": "sha512-lueLk4mbt/c+cB2UWvVmeNYlN+tmkmKYJ80lptY9+FMtMI02/QG7IOhL3gJzhkUzwfv/FhgxQvbiwrSamIot4Q==", "cpu": [ "x64", "arm64" @@ -9518,9 +9518,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.695", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.695.tgz", - "integrity": "sha512-eMijZmeqPtm774pCZIOrfUHMs/7ls++W1sLhxwqgu8KQ8E2WmMtzwyqOMt0XXUJ3HTIPfuwlfwF+I5cwnfItBA==", + "version": "1.4.696", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.696.tgz", + "integrity": "sha512-SOr0bHP52OvYg2chCsz/0+FUSMGFm8L8HKwPpx3cbwRY24EOemVJtbgTm+IFO8LzhcnPy+hXmTq7ZcZ8uUuaYg==", "dev": true }, "node_modules/emittery": { diff --git a/package.json b/package.json index f516f94..62e5130 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.0.281", + "version": "1.0.283", "license": "GPL-3.0-or-later", "name": "@clevercanyon/utilities.cfw", "description": "Utilities for JavaScript apps running in a Cloudflare Worker environment.", @@ -64,7 +64,7 @@ }, "dependencies": {}, "peerDependencies": { - "@clevercanyon/utilities": "^1.0.887", + "@clevercanyon/utilities": "^1.0.890", "@cloudflare/ai": "1.0.53", "@upstash/ratelimit": "1.0.0", "@upstash/redis": "1.28.0" diff --git a/src/cfw.ts b/src/cfw.ts index 01628c7..b6ddbca 100644 --- a/src/cfw.ts +++ b/src/cfw.ts @@ -69,6 +69,7 @@ export type StdRequestContextData = Readonly<{ auditLogger: $type.LoggerInterface; consentLogger: $type.LoggerInterface; + subrequestCounter: { value: number }; }>; /** @@ -139,6 +140,7 @@ export const handleFetchEvent = async (ircData: InitialRequestContextData): Prom auditLogger, consentLogger, + subrequestCounter: { value: 0 }, }); let response: Promise<$type.cfw.Response>; // Initialize. @@ -327,6 +329,7 @@ const handleFetchCache = async (rcData: RequestContextData, route: Route): Promi } // Reads response for this request from HTTP cache. + rcData.subrequestCounter.value++; if ((cachedResponse = await caches.default.match(keyRequest, { ignoreMethod: true }))) { return $http.prepareCachedResponse(keyRequest, cachedResponse) as Promise<$type.cfw.Response>; } @@ -350,6 +353,7 @@ const handleFetchCache = async (rcData: RequestContextData, route: Route): Promi // Cloudflare will not actually cache if headers say not to; {@see https://o5p.me/gMv7W2}. const responseForCache = (await $http.prepareResponseForCache(keyRequest, response)) as $type.cfw.Response; await caches.default.put(keyRequest, responseForCache); + rcData.subrequestCounter.value++; })(), ); response.headers.set('x-cache-status', 'miss'); // i.e., Cache miss. diff --git a/src/proxy.ts b/src/proxy.ts index 1042a00..e112e4e 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -97,6 +97,7 @@ export const worker = async (rcData: $cfw.StdRequestContextData, requestInfo: $t } else if (requestInfo instanceof Request) { requestInfo = new Request($url.addQueryVar('url', requestInfo.url, proxyRoute), requestInfo); } + rcData.subrequestCounter.value++; return fetch(requestInfo, requestInit); }; @@ -146,6 +147,8 @@ const fetchꓺviaSocket = async (rcData: $cfw.StdRequestContextData, url: $type. // --- // Socket setup. + rcData.subrequestCounter.value++; + const socket = sockets.connect({ hostname: opts.proxy.host, port: opts.proxy.port, diff --git a/src/redis.ts b/src/redis.ts index 8e8760e..f26d110 100644 --- a/src/redis.ts +++ b/src/redis.ts @@ -92,7 +92,7 @@ export const instance = $fn.memo( enableTelemetry: false, // Just for good measure. The environment variable is what’s important. retry: { - retries: 5, + retries: 5, // Maximum upstash retry attempts. backoff: (retryAttempts: number) => Math.exp(retryAttempts) * 50, /** * Regarding retry attempts and timeouts. @@ -110,7 +110,6 @@ export const instance = $fn.memo( }, signal: undefined, // Not used at this time. }, - // Constructor always reads env variable for this specific setting. { UPSTASH_DISABLE_TELEMETRY: '1' }, // Don’t report back to Upstash. ); }, @@ -135,9 +134,11 @@ export const rateLimiter = (rcData: $cfw.StdRequestContextData, options?: RateLi limiter, // RateLimiterCore. async limit(...args: Parameters): ReturnType { + rcData.subrequestCounter.value += 2; // Possible read and write requests. const limiterResponse = await limiter.limit(...args); if ($is.promise(limiterResponse.pending)) { + rcData.subrequestCounter.value++; // Adds additional pending request to counter. ctx.waitUntil(limiterResponse.pending); // e.g., Analytics, multiregion sync. } if (!limiterResponse.success) { @@ -163,9 +164,11 @@ export const rateLimiter = (rcData: $cfw.StdRequestContextData, options?: RateLi return limiterResponse; }, async blockUntilReady(...args: Parameters): ReturnType { + rcData.subrequestCounter.value += 2; // Possible read and write requests. const limiterResponse = await limiter.blockUntilReady(...args); if ($is.promise(limiterResponse.pending)) { + rcData.subrequestCounter.value++; // Adds additional pending request to counter. ctx.waitUntil(limiterResponse.pending); // e.g., Analytics, multiregion sync. } if (!limiterResponse.success) { diff --git a/src/root.ts b/src/root.ts index f7d2aa0..98e791d 100644 --- a/src/root.ts +++ b/src/root.ts @@ -53,6 +53,7 @@ export const service = async (rcData: $cfw.StdRequestContextData, requestInfo: $ if (!rt) throw Error('Root service binding unavailable.'); + rcData.subrequestCounter.value++; return rt.fetch(await $cfw.serviceBindingRequest(rcData, requestInfo, requestInit)); }; service.isAvailable = (rcData: $cfw.StdRequestContextData): boolean => { @@ -147,6 +148,8 @@ kv.isAvailable = (rcData: $cfw.StdRequestContextData): boolean => { * @returns Promise of root UA headers. */ export const uaHeaders = async (rcData: $cfw.StdRequestContextData, options?: UAHeaderOptions): Promise => { + rcData.subrequestCounter.value++; + const opts = $obj.defaults({}, options || {}, { randomIndex: $crypto.randomNumber(1, 100) }) as Required, kvKey = 'ua-headers:' + String($to.integerBetween(opts.randomIndex, 1, 100)), headers = (await kv(rcData).get(kvKey, { type: 'json' })) as UAHeaders; @@ -170,20 +173,8 @@ uaHeaders.isAvailable = kv.isAvailable; * @returns Promise of root counter value. */ export const counter = async (rcData: $cfw.StdRequestContextData, key: string): Promise => { - return ( - ((await d1(rcData) - .prepare( - 'SELECT `value`' + - ' FROM `counters`' + - // - ' WHERE' + - ' `key` = ?1' + - // - ' LIMIT 1', - ) - .bind(key) - .first('value')) as number) || 0 - ); + rcData.subrequestCounter.value++; + return ((await d1(rcData).prepare('SELECT `value` FROM `counters` WHERE `key` = ?1 LIMIT 1').bind(key).first('value')) as number) || 0; }; counter.isAvailable = d1.isAvailable; // Powered by root D1 database. @@ -194,14 +185,6 @@ counter.isAvailable = d1.isAvailable; // Powered by root D1 database. * @param by By; default is `1`. */ export const bumpCounter = async (rcData: $cfw.StdRequestContextData, key: string, by: number = 1): Promise => { - await d1(rcData) - .prepare( - 'INSERT INTO `counters` (`key`, `value`)' + - ' VALUES(?1, ?2)' + - // - ' ON CONFLICT(`key`) DO UPDATE' + - ' SET `value` = `value` + ?2', - ) - .bind(key, by) - .run(); + rcData.subrequestCounter.value++; + await d1(rcData).prepare('INSERT INTO `counters` (`key`, `value`) VALUES(?1, ?2) ON CONFLICT(`key`) DO UPDATE SET `value` = `value` + ?2').bind(key, by).run(); }; diff --git a/src/tests/redis.ts b/src/tests/redis.ts index 7b90e56..8175331 100644 --- a/src/tests/redis.ts +++ b/src/tests/redis.ts @@ -30,6 +30,7 @@ describe('$redis', async () => { auditLogger: mockLoggerInterface, consentLogger: mockLoggerInterface, + subrequestCounter: { value: 0 }, }, redis = $redis.instance(); diff --git a/tsconfig.json b/tsconfig.json index 9344a71..fc473c4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ * @note This entire file will be updated automatically. * @note Instead of editing here, please review `./tsconfig.mjs`. * - * Last generated using `./tsconfig.mjs` Mar 7, 2024 12:46 PM UTC. + * Last generated using `./tsconfig.mjs` Mar 7, 2024 9:03 PM UTC. */ { "include": ["./src/**/*", "./dev-types.d.ts"], diff --git a/wrangler.toml b/wrangler.toml index b3ceb22..a122111 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -7,7 +7,7 @@ # @note This entire file will be updated automatically. # @note Instead of editing here, please review `./wrangler.mjs`. # -# Last generated using `./wrangler.mjs` Mar 7, 2024 12:46 PM UTC. +# Last generated using `./wrangler.mjs` Mar 7, 2024 9:03 PM UTC. ## send_metrics = false