[{"data":1,"prerenderedAt":1770},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Futils":64,"navigation":263,"navLinks_footer":835,"\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker_page":848,"\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker_surround":1393,"\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker":1396},{"id":4,"extension":5,"links":6,"meta":61,"stem":62,"__hash__":63},"navigationMenu\u002Fnavigation.json","json",[7,52,57],{"nested":8,"label":9,"icon":10,"to":11,"children":12},true,"Docs","i-lucide-book-open","\u002Fdocs\u002Fgetting-started",[13,19,26,32,39,45],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},"Getting Started","i-lucide-rocket","An introduction to help you understand the core components.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fdocshub","Start Here",{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},"Auth H3 Client","i-lucide-key-round","\u002Fdocs\u002Fauth-h3client","Seamlessly enforce OAuth 2.0 authentication and session management integrated directly as the client of the IAM module.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth-h3client","Core",{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},"IAM","i-lucide-shield-check","\u002Fdocs\u002Fiam","Identity and Access Management featuring granular roles, permissions, and security policies.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth",{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},"Bot Detection","i-lucide-cpu","\u002Fdocs\u002Fbot-detection","Advanced behavioral analysis and request fingerprinting to stop malicious automated traffic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fbot-detector","Security",{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},"Shield Base","i-lucide-database-zap","\u002Fdocs\u002Fshield-base","CLI and programmatic toolkit for compiling offline-ready IP intelligence databases from BGP, GeoIP, Tor, FireHOL, and other public threat feeds.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fshield-base-cli",{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},"Utils","i-lucide-wrench","\u002Fdocs\u002Futils","A standard library of highly optimized helpers for formatting, validation, and core logic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Futils","Library",{"nested":53,"label":54,"icon":55,"to":56},false,"Blog","i-lucide-pen-line","\u002Fblog",{"nested":53,"label":58,"icon":59,"to":60},"Website","lucide:app-window-mac","https:\u002F\u002Friavzon.com",{},"navigation","gkaQ0xRGxSLrLyM3kttLe0oBwkrR1EBjlepF8LSbwF8",[65],{"title":9,"path":66,"stem":67,"children":68,"page":53},"\u002Fdocs","docs",[69],{"title":70,"path":48,"stem":71,"children":72},"Utilities","docs\u002Futils\u002Findex",[73,74,91,124,221],{"title":70,"path":48,"stem":71},{"title":75,"path":76,"stem":77,"children":78,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[79,83,87],{"title":80,"path":81,"stem":82},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":84,"path":85,"stem":86},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":88,"path":89,"stem":90},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":92,"path":93,"stem":94,"children":95,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[96,100,104,108,112,116,120],{"title":97,"path":98,"stem":99},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":101,"path":102,"stem":103},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":105,"path":106,"stem":107},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":109,"path":110,"stem":111},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":113,"path":114,"stem":115},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":117,"path":118,"stem":119},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":121,"path":122,"stem":123},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":125,"path":126,"stem":127,"children":128,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,193,197,201,205,209,213,217],{"title":130,"path":131,"stem":132},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":134,"path":135,"stem":136},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":138,"path":139,"stem":140},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":142,"path":143,"stem":144},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":146,"path":147,"stem":148},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":150,"path":151,"stem":152},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":154,"path":155,"stem":156},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":158,"path":159,"stem":160},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":162,"path":163,"stem":164},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":166,"path":167,"stem":168},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":170,"path":171,"stem":172},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":174,"path":175,"stem":176},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":178,"path":179,"stem":180},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":182,"path":183,"stem":184},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":186,"path":187,"stem":188},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":190,"path":191,"stem":192},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":194,"path":195,"stem":196},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":198,"path":199,"stem":200},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":202,"path":203,"stem":204},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":206,"path":207,"stem":208},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":210,"path":211,"stem":212},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":214,"path":215,"stem":216},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":218,"path":219,"stem":220},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":222,"path":223,"stem":224,"children":225},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[226,227,231,235,239,243,247,251,255,259],{"title":222,"path":223,"stem":224},{"title":228,"path":229,"stem":230},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":232,"path":233,"stem":234},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":236,"path":237,"stem":238},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":240,"path":241,"stem":242},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":244,"path":245,"stem":246},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":248,"path":249,"stem":250},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":252,"path":253,"stem":254},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":256,"path":257,"stem":258},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":260,"path":261,"stem":262},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",[264],{"title":9,"path":66,"stem":67,"children":265,"page":53},[266,413,531,536,714,781],{"title":20,"path":22,"stem":267,"children":268},"docs\u002Fauth-h3client\u002Findex",[269,270,279,316,342,364,367,388,392],{"title":20,"path":22,"stem":267},{"title":14,"path":271,"stem":272,"children":273},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[274,275],{"title":14,"path":271,"stem":272},{"title":276,"path":277,"stem":278},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":280,"path":281,"stem":282,"children":283},"Essentials","\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[284,285,289,293,297,301,305,308,312],{"title":280,"path":281,"stem":282},{"title":286,"path":287,"stem":288},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":290,"path":291,"stem":292},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":294,"path":295,"stem":296},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":298,"path":299,"stem":300},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":302,"path":303,"stem":304},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":306,"stem":307},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":309,"path":310,"stem":311},"Cookies","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":313,"path":314,"stem":315},"Logging","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":317,"path":318,"stem":319,"children":320},"MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[321,322,326,330,334,338],{"title":317,"path":318,"stem":319},{"title":323,"path":324,"stem":325},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":327,"path":328,"stem":329},"Password Reset","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":331,"path":332,"stem":333},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":335,"path":336,"stem":337},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":339,"path":340,"stem":341},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":343,"path":344,"stem":345,"children":346},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[347,348,352,356,360],{"title":343,"path":344,"stem":345},{"title":349,"path":350,"stem":351},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":353,"path":354,"stem":355},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":357,"path":358,"stem":359},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":361,"path":362,"stem":363},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":365,"stem":366},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":368,"path":369,"stem":370,"children":371,"page":53},"Guides","\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[372,376,380,384],{"title":373,"path":374,"stem":375},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":377,"path":378,"stem":379},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":381,"path":382,"stem":383},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":385,"path":386,"stem":387},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":389,"path":390,"stem":391},"Configuration","\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":393,"path":394,"stem":395,"children":396},"API Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[397,398,402,406,410],{"title":393,"path":394,"stem":395},{"title":399,"path":400,"stem":401},"Routes Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":403,"path":404,"stem":405},"Middleware Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":407,"path":408,"stem":409},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":70,"path":411,"stem":412},"\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",{"title":414,"path":35,"stem":415,"children":416},"Bot Detector","docs\u002Fbot-detection\u002Findex",[417,418,421,425,429,448,522,525,528],{"title":414,"path":35,"stem":415},{"title":14,"path":419,"stem":420},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":422,"path":423,"stem":424},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":426,"path":427,"stem":428},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":368,"path":430,"stem":431,"children":432,"page":53},"\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[433,437,441,444],{"title":434,"path":435,"stem":436},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":438,"path":439,"stem":440},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":313,"path":442,"stem":443},"\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":445,"path":446,"stem":447},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":449,"path":450,"stem":451,"children":452},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[453,454,458,462,466,470,474,478,482,486,490,494,498,502,506,510,514,518],{"title":449,"path":450,"stem":451},{"title":455,"path":456,"stem":457},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":459,"path":460,"stem":461},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":463,"path":464,"stem":465},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":467,"path":468,"stem":469},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":471,"path":472,"stem":473},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":475,"path":476,"stem":477},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":479,"path":480,"stem":481},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":483,"path":484,"stem":485},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":487,"path":488,"stem":489},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":491,"path":492,"stem":493},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":495,"path":496,"stem":497},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":499,"path":500,"stem":501},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":503,"path":504,"stem":505},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":507,"path":508,"stem":509},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":511,"path":512,"stem":513},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":515,"path":516,"stem":517},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":519,"path":520,"stem":521},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":523,"stem":524},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":393,"path":526,"stem":527},"\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":389,"path":529,"stem":530},"\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",{"title":532,"path":11,"stem":533,"children":534},"Introduction","docs\u002Fgetting-started\u002Findex",[535],{"title":532,"path":11,"stem":533},{"title":27,"path":29,"stem":537,"children":538},"docs\u002Fiam\u002Findex",[539,540,543,678,681,697,700],{"title":27,"path":29,"stem":537},{"title":14,"path":541,"stem":542},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":280,"path":544,"stem":545,"children":546},"\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[547,548,552,556,560,564,568,572,576,580,584,588,591,595,599,603,607,610,614,618,621,625,628],{"title":280,"path":544,"stem":545},{"title":549,"path":550,"stem":551},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":553,"path":554,"stem":555},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":557,"path":558,"stem":559},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":561,"path":562,"stem":563},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":565,"path":566,"stem":567},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":569,"path":570,"stem":571},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":573,"path":574,"stem":575},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":577,"path":578,"stem":579},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":581,"path":582,"stem":583},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":585,"path":586,"stem":587},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":317,"path":589,"stem":590},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":592,"path":593,"stem":594},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":596,"path":597,"stem":598},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":600,"path":601,"stem":602},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":604,"path":605,"stem":606},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":313,"path":608,"stem":609},"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":611,"path":612,"stem":613},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":615,"path":616,"stem":617},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":309,"path":619,"stem":620},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":622,"path":623,"stem":624},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":327,"path":626,"stem":627},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":629,"path":630,"stem":631,"children":632},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[633,634,638,642,672,675],{"title":629,"path":630,"stem":631},{"title":635,"path":636,"stem":637},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":639,"path":640,"stem":641},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":643,"path":644,"stem":645,"children":646},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[647,648,652,656,660,664,668],{"title":643,"path":644,"stem":645},{"title":649,"path":650,"stem":651},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":653,"path":654,"stem":655},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":657,"path":658,"stem":659},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":661,"path":662,"stem":663},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":665,"path":666,"stem":667},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":669,"path":670,"stem":671},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":611,"path":673,"stem":674},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":676,"stem":677},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":679,"stem":680},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":368,"path":682,"stem":683,"children":684,"page":53},"\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[685,689,693],{"title":686,"path":687,"stem":688},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":690,"path":691,"stem":692},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":694,"path":695,"stem":696},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":389,"path":698,"stem":699},"\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":701,"path":702,"stem":703,"children":704,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[705,708,711],{"title":393,"path":706,"stem":707},"\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":403,"path":709,"stem":710},"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":399,"path":712,"stem":713},"\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",{"title":40,"path":42,"stem":715,"children":716},"docs\u002Fshield-base\u002Findex",[717,718,721,725,766,770,774,778],{"title":40,"path":42,"stem":715},{"title":14,"path":719,"stem":720},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":722,"path":723,"stem":724},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":426,"path":726,"stem":727,"children":728},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[729,730,734,738,742,746,750,754,758,762],{"title":426,"path":726,"stem":727},{"title":731,"path":732,"stem":733},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":735,"path":736,"stem":737},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":739,"path":740,"stem":741},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":743,"path":744,"stem":745},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":747,"path":748,"stem":749},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":751,"path":752,"stem":753},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":755,"path":756,"stem":757},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":759,"path":760,"stem":761},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":763,"path":764,"stem":765},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":767,"path":768,"stem":769},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":771,"path":772,"stem":773},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":775,"path":776,"stem":777},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":393,"path":779,"stem":780},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":70,"path":48,"stem":71,"children":782},[783,784,789,798,823],{"title":70,"path":48,"stem":71},{"title":75,"path":76,"stem":77,"children":785,"page":53},[786,787,788],{"title":80,"path":81,"stem":82},{"title":84,"path":85,"stem":86},{"title":88,"path":89,"stem":90},{"title":92,"path":93,"stem":94,"children":790,"page":53},[791,792,793,794,795,796,797],{"title":97,"path":98,"stem":99},{"title":101,"path":102,"stem":103},{"title":105,"path":106,"stem":107},{"title":109,"path":110,"stem":111},{"title":113,"path":114,"stem":115},{"title":117,"path":118,"stem":119},{"title":121,"path":122,"stem":123},{"title":125,"path":126,"stem":127,"children":799,"page":53},[800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822],{"title":130,"path":131,"stem":132},{"title":134,"path":135,"stem":136},{"title":138,"path":139,"stem":140},{"title":142,"path":143,"stem":144},{"title":146,"path":147,"stem":148},{"title":150,"path":151,"stem":152},{"title":154,"path":155,"stem":156},{"title":158,"path":159,"stem":160},{"title":162,"path":163,"stem":164},{"title":166,"path":167,"stem":168},{"title":170,"path":171,"stem":172},{"title":174,"path":175,"stem":176},{"title":178,"path":179,"stem":180},{"title":182,"path":183,"stem":184},{"title":186,"path":187,"stem":188},{"title":190,"path":191,"stem":192},{"title":194,"path":195,"stem":196},{"title":198,"path":199,"stem":200},{"title":202,"path":203,"stem":204},{"title":206,"path":207,"stem":208},{"title":210,"path":211,"stem":212},{"title":214,"path":215,"stem":216},{"title":218,"path":219,"stem":220},{"title":222,"path":223,"stem":224,"children":824},[825,826,827,828,829,830,831,832,833,834],{"title":222,"path":223,"stem":224},{"title":228,"path":229,"stem":230},{"title":232,"path":233,"stem":234},{"title":236,"path":237,"stem":238},{"title":240,"path":241,"stem":242},{"title":244,"path":245,"stem":246},{"title":248,"path":249,"stem":250},{"title":252,"path":253,"stem":254},{"title":256,"path":257,"stem":258},{"title":260,"path":261,"stem":262},{"id":4,"extension":5,"links":836,"meta":847,"stem":62,"__hash__":63},[837,845,846],{"nested":8,"label":9,"icon":10,"to":11,"children":838},[839,840,841,842,843,844],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},{"nested":53,"label":54,"icon":55,"to":56},{"nested":53,"label":58,"icon":59,"to":60},{},{"id":849,"title":194,"body":850,"description":1385,"extension":1386,"icon":1387,"meta":1388,"module":1389,"navigation":8,"path":195,"rawbody":1390,"seo":1391,"stem":196,"__hash__":1392},"docs\u002Fdocs\u002Futils\u002Fshared\u002FpromiseLocker.md",{"type":851,"value":852,"toc":1379},"minimark",[853,874,881,886,889,911,915,1047,1051,1149,1153,1156,1369,1375],[854,855,858],"callout",{"color":856,"icon":857},"info","i-lucide-info",[859,860,861,865,866,873],"p",{},[862,863,864],"strong",{},"Advanced Utility",": This function is designed for high-concurrency environments to solve the ",[867,868,872],"a",{"href":869,"rel":870},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCache_stampede",[871],"nofollow","Cache Stampede"," problem by deduplicating in-flight asynchronous operations.",[859,875,876,877,880],{},"The ",[878,879,194],"code",{}," utility is a tool for managing concurrent asynchronous operations. It prevents duplicate execution of expensive actions (like refreshing a token or fetching a singleton resource) by using a \"leader\" pattern.",[882,883,885],"h2",{"id":884},"behavior","Behavior",[859,887,888],{},"When multiple concurrent calls are made with the same token:",[890,891,892,899,905],"ol",{},[893,894,895,898],"li",{},[862,896,897],{},"Cache Check",": If a fresh result exists in the short-term cache, it's returned immediately.",[893,900,901,904],{},[862,902,903],{},"Lock Check",": If the action is already being executed by another caller, the current caller waits for that same promise to resolve.",[893,906,907,910],{},[862,908,909],{},"Leader Execution",": If no lock or cache exists, the current caller becomes the \"leader\", starts the execution, and shares the resulting promise with all subsequent callers.",[882,912,914],{"id":913},"definition","Definition",[916,917,923],"pre",{"className":918,"code":919,"filename":920,"language":921,"meta":922,"style":922},"language-ts shiki shiki-themes light-plus light-plus dracula","export async function safeAction\u003CT>(\n    token: string,\n    action: () => Promise\u003CT>,\n    recentResultsTTL = 3000,\n    log: pino.Logger\n): Promise\u003CT>\n","promiseLocker.ts","ts","",[878,924,925,956,974,998,1013,1030],{"__ignoreMap":922},[926,927,930,934,938,941,945,949,953],"span",{"class":928,"line":929},"line",1,[926,931,933],{"class":932},"sZ328","export",[926,935,937],{"class":936},"sl46w"," async",[926,939,940],{"class":936}," function",[926,942,944],{"class":943},"sHOzp"," safeAction",[926,946,948],{"class":947},"sDd4n","\u003C",[926,950,952],{"class":951},"sW-rI","T",[926,954,955],{"class":947},">(\n",[926,957,959,963,967,971],{"class":928,"line":958},2,[926,960,962],{"class":961},"sygFZ","    token",[926,964,966],{"class":965},"saOXh",":",[926,968,970],{"class":969},"sFs1U"," string",[926,972,973],{"class":947},",\n",[926,975,977,980,982,985,988,991,993,995],{"class":928,"line":976},3,[926,978,979],{"class":943},"    action",[926,981,966],{"class":965},[926,983,984],{"class":947}," () ",[926,986,987],{"class":936},"=>",[926,989,990],{"class":969}," Promise",[926,992,948],{"class":947},[926,994,952],{"class":951},[926,996,997],{"class":947},">,\n",[926,999,1001,1004,1007,1011],{"class":928,"line":1000},4,[926,1002,1003],{"class":961},"    recentResultsTTL",[926,1005,1006],{"class":965}," =",[926,1008,1010],{"class":1009},"spgvN"," 3000",[926,1012,973],{"class":947},[926,1014,1016,1019,1021,1024,1027],{"class":928,"line":1015},5,[926,1017,1018],{"class":961},"    log",[926,1020,966],{"class":965},[926,1022,1023],{"class":969}," pino",[926,1025,1026],{"class":947},".",[926,1028,1029],{"class":969},"Logger\n",[926,1031,1033,1036,1038,1040,1042,1044],{"class":928,"line":1032},6,[926,1034,1035],{"class":947},")",[926,1037,966],{"class":965},[926,1039,990],{"class":969},[926,1041,948],{"class":947},[926,1043,952],{"class":951},[926,1045,1046],{"class":947},">\n",[882,1048,1050],{"id":1049},"parameters","Parameters",[1052,1053,1054,1073],"table",{},[1055,1056,1057],"thead",{},[1058,1059,1060,1064,1067,1070],"tr",{},[1061,1062,1063],"th",{},"Parameter",[1061,1065,1066],{},"Type",[1061,1068,1069],{},"Default",[1061,1071,1072],{},"Description",[1074,1075,1076,1095,1112,1132],"tbody",{},[1058,1077,1078,1084,1089,1092],{},[1079,1080,1081],"td",{},[878,1082,1083],{},"token",[1079,1085,1086],{},[878,1087,1088],{},"string",[1079,1090,1091],{},"-",[1079,1093,1094],{},"A unique key used for locking and caching the operation.",[1058,1096,1097,1102,1107,1109],{},[1079,1098,1099],{},[878,1100,1101],{},"action",[1079,1103,1104],{},[878,1105,1106],{},"() => Promise\u003CT>",[1079,1108,1091],{},[1079,1110,1111],{},"The asynchronous function to perform if no lock or cache is found.",[1058,1113,1114,1119,1124,1129],{},[1079,1115,1116],{},[878,1117,1118],{},"recentResultsTTL",[1079,1120,1121],{},[878,1122,1123],{},"number",[1079,1125,1126],{},[878,1127,1128],{},"3000",[1079,1130,1131],{},"Duration (in ms) to cache the completed result after the lock is released.",[1058,1133,1134,1139,1144,1146],{},[1079,1135,1136],{},[878,1137,1138],{},"log",[1079,1140,1141],{},[878,1142,1143],{},"pino.Logger",[1079,1145,1091],{},[1079,1147,1148],{},"A Pino logger instance for tracking execution flow and cache status.",[882,1150,1152],{"id":1151},"example-usage","Example Usage",[859,1154,1155],{},"This is perfect for preventing redundant heavy requests to external APIs or databases.",[916,1157,1162],{"className":1158,"code":1159,"filename":1160,"language":1161,"meta":922,"style":922},"language-typescript shiki shiki-themes light-plus light-plus dracula","import { safeAction } from '@riavzon\u002Futils'\nimport pino from 'pino'\n\nconst logger = pino();\n\nasync function refreshToken() {\n  console.log('Refreshing token...');\n  return await api.post('\u002Frefresh');\n}\n\n\u002F\u002F Even if 100 requests call this simultaneously:\n\u002F\u002F Only ONE 'Refreshing token...' log will appear.\n\u002F\u002F All 100 callers will receive the exact same result.\nconst token = await safeAction('auth-refresh', refreshToken, 5000, logger);\n","example.ts","typescript",[878,1163,1164,1192,1208,1213,1229,1233,1246,1270,1298,1304,1309,1316,1322,1328],{"__ignoreMap":922},[926,1165,1166,1169,1172,1175,1178,1181,1185,1189],{"class":928,"line":929},[926,1167,1168],{"class":932},"import",[926,1170,1171],{"class":947}," { ",[926,1173,194],{"class":1174},"sjsA6",[926,1176,1177],{"class":947}," } ",[926,1179,1180],{"class":932},"from",[926,1182,1184],{"class":1183},"sFkSl"," '",[926,1186,1188],{"class":1187},"sFB1V","@riavzon\u002Futils",[926,1190,1191],{"class":1183},"'\n",[926,1193,1194,1196,1198,1201,1203,1206],{"class":928,"line":958},[926,1195,1168],{"class":932},[926,1197,1023],{"class":1174},[926,1199,1200],{"class":932}," from",[926,1202,1184],{"class":1183},[926,1204,1205],{"class":1187},"pino",[926,1207,1191],{"class":1183},[926,1209,1210],{"class":928,"line":976},[926,1211,1212],{"emptyLinePlaceholder":8},"\n",[926,1214,1215,1218,1222,1224,1226],{"class":928,"line":1000},[926,1216,1217],{"class":936},"const",[926,1219,1221],{"class":1220},"s3JHE"," logger",[926,1223,1006],{"class":965},[926,1225,1023],{"class":943},[926,1227,1228],{"class":947},"();\n",[926,1230,1231],{"class":928,"line":1015},[926,1232,1212],{"emptyLinePlaceholder":8},[926,1234,1235,1238,1240,1243],{"class":928,"line":1032},[926,1236,1237],{"class":936},"async",[926,1239,940],{"class":936},[926,1241,1242],{"class":943}," refreshToken",[926,1244,1245],{"class":947},"() {\n",[926,1247,1249,1252,1254,1256,1259,1262,1265,1267],{"class":928,"line":1248},7,[926,1250,1251],{"class":1174},"  console",[926,1253,1026],{"class":947},[926,1255,1138],{"class":943},[926,1257,1258],{"class":947},"(",[926,1260,1261],{"class":1183},"'",[926,1263,1264],{"class":1187},"Refreshing token...",[926,1266,1261],{"class":1183},[926,1268,1269],{"class":947},");\n",[926,1271,1273,1276,1279,1282,1284,1287,1289,1291,1294,1296],{"class":928,"line":1272},8,[926,1274,1275],{"class":932},"  return",[926,1277,1278],{"class":932}," await",[926,1280,1281],{"class":1174}," api",[926,1283,1026],{"class":947},[926,1285,1286],{"class":943},"post",[926,1288,1258],{"class":947},[926,1290,1261],{"class":1183},[926,1292,1293],{"class":1187},"\u002Frefresh",[926,1295,1261],{"class":1183},[926,1297,1269],{"class":947},[926,1299,1301],{"class":928,"line":1300},9,[926,1302,1303],{"class":947},"}\n",[926,1305,1307],{"class":928,"line":1306},10,[926,1308,1212],{"emptyLinePlaceholder":8},[926,1310,1312],{"class":928,"line":1311},11,[926,1313,1315],{"class":1314},"sghk6","\u002F\u002F Even if 100 requests call this simultaneously:\n",[926,1317,1319],{"class":928,"line":1318},12,[926,1320,1321],{"class":1314},"\u002F\u002F Only ONE 'Refreshing token...' log will appear.\n",[926,1323,1325],{"class":928,"line":1324},13,[926,1326,1327],{"class":1314},"\u002F\u002F All 100 callers will receive the exact same result.\n",[926,1329,1331,1333,1336,1338,1340,1342,1344,1346,1349,1351,1354,1357,1359,1362,1364,1367],{"class":928,"line":1330},14,[926,1332,1217],{"class":936},[926,1334,1335],{"class":1220}," token",[926,1337,1006],{"class":965},[926,1339,1278],{"class":932},[926,1341,944],{"class":943},[926,1343,1258],{"class":947},[926,1345,1261],{"class":1183},[926,1347,1348],{"class":1187},"auth-refresh",[926,1350,1261],{"class":1183},[926,1352,1353],{"class":947},", ",[926,1355,1356],{"class":1174},"refreshToken",[926,1358,1353],{"class":947},[926,1360,1361],{"class":1009},"5000",[926,1363,1353],{"class":947},[926,1365,1366],{"class":1174},"logger",[926,1368,1269],{"class":947},[854,1370,1372],{"color":1371,"icon":28},"success",[859,1373,1374],{},"This utility is especially powerful in microservices or high-concurrency environments to ensure consistency and reduce load on external services.",[1376,1377,1378],"style",{},"html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sW-rI, html code.shiki .sW-rI{--shiki-light:#267F99;--shiki-light-font-style:inherit;--shiki-default:#267F99;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .sygFZ, html code.shiki .sygFZ{--shiki-light:#001080;--shiki-light-font-style:inherit;--shiki-default:#001080;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .sFs1U, html code.shiki .sFs1U{--shiki-light:#267F99;--shiki-light-font-style:inherit;--shiki-default:#267F99;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .spgvN, html code.shiki .spgvN{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#BD93F9}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .s3JHE, html code.shiki .s3JHE{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#F8F8F2}html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}",{"title":922,"searchDepth":958,"depth":958,"links":1380},[1381,1382,1383,1384],{"id":884,"depth":958,"text":885},{"id":913,"depth":958,"text":914},{"id":1049,"depth":958,"text":1050},{"id":1151,"depth":958,"text":1152},"Implements deduplication and short-term caching for concurrent asynchronous actions.","md","i-lucide-lock",{},null,"---\ntitle: safeAction\ndescription: Implements deduplication and short-term caching for concurrent asynchronous actions.\nicon: i-lucide-lock\n---\n\n::callout{icon=\"i-lucide-info\" color=\"info\"}\n**Advanced Utility**: This function is designed for high-concurrency environments to solve the [Cache Stampede](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCache_stampede) problem by deduplicating in-flight asynchronous operations.\n::\n\nThe `safeAction` utility is a tool for managing concurrent asynchronous operations. It prevents duplicate execution of expensive actions (like refreshing a token or fetching a singleton resource) by using a \"leader\" pattern.\n\n## Behavior\n\nWhen multiple concurrent calls are made with the same token:\n1. **Cache Check**: If a fresh result exists in the short-term cache, it's returned immediately.\n2. **Lock Check**: If the action is already being executed by another caller, the current caller waits for that same promise to resolve.\n3. **Leader Execution**: If no lock or cache exists, the current caller becomes the \"leader\", starts the execution, and shares the resulting promise with all subsequent callers.\n\n## Definition\n\n```ts [promiseLocker.ts]\nexport async function safeAction\u003CT>(\n    token: string,\n    action: () => Promise\u003CT>,\n    recentResultsTTL = 3000,\n    log: pino.Logger\n): Promise\u003CT>\n```\n\n## Parameters\n| Parameter | Type | Default | Description |\n| --- | --- | --- | --- |\n| `token` | `string` | - | A unique key used for locking and caching the operation. |\n| `action` | `() => Promise\u003CT>` | - | The asynchronous function to perform if no lock or cache is found. |\n| `recentResultsTTL` | `number` | `3000` | Duration (in ms) to cache the completed result after the lock is released. |\n| `log` | `pino.Logger` | - | A Pino logger instance for tracking execution flow and cache status. |\n\n## Example Usage\n\nThis is perfect for preventing redundant heavy requests to external APIs or databases.\n\n```typescript [example.ts]\nimport { safeAction } from '@riavzon\u002Futils'\nimport pino from 'pino'\n\nconst logger = pino();\n\nasync function refreshToken() {\n  console.log('Refreshing token...');\n  return await api.post('\u002Frefresh');\n}\n\n\u002F\u002F Even if 100 requests call this simultaneously:\n\u002F\u002F Only ONE 'Refreshing token...' log will appear.\n\u002F\u002F All 100 callers will receive the exact same result.\nconst token = await safeAction('auth-refresh', refreshToken, 5000, logger);\n```\n\n::callout{icon=\"i-lucide-shield-check\" color=\"success\"}\nThis utility is especially powerful in microservices or high-concurrency environments to ensure consistency and reduce load on external services.\n::\n",{"title":194,"description":1385},"DY2pJ-Bux0LmoZafspCFPcAZVyUSMh9iUZs7LaNiZlE",[1394,1395],{"title":190,"path":191,"stem":192,"children":-1},{"title":198,"path":199,"stem":200,"children":-1},{"id":849,"title":194,"body":1397,"description":1385,"extension":1386,"icon":1387,"meta":1768,"module":1389,"navigation":8,"path":195,"rawbody":1390,"seo":1769,"stem":196,"__hash__":1392},{"type":851,"value":1398,"toc":1762},[1399,1408,1412,1414,1416,1430,1432,1516,1518,1592,1594,1596,1756,1760],[854,1400,1401],{"color":856,"icon":857},[859,1402,1403,865,1405,873],{},[862,1404,864],{},[867,1406,872],{"href":869,"rel":1407},[871],[859,1409,876,1410,880],{},[878,1411,194],{},[882,1413,885],{"id":884},[859,1415,888],{},[890,1417,1418,1422,1426],{},[893,1419,1420,898],{},[862,1421,897],{},[893,1423,1424,904],{},[862,1425,903],{},[893,1427,1428,910],{},[862,1429,909],{},[882,1431,914],{"id":913},[916,1433,1434],{"className":918,"code":919,"filename":920,"language":921,"meta":922,"style":922},[878,1435,1436,1452,1462,1480,1490,1502],{"__ignoreMap":922},[926,1437,1438,1440,1442,1444,1446,1448,1450],{"class":928,"line":929},[926,1439,933],{"class":932},[926,1441,937],{"class":936},[926,1443,940],{"class":936},[926,1445,944],{"class":943},[926,1447,948],{"class":947},[926,1449,952],{"class":951},[926,1451,955],{"class":947},[926,1453,1454,1456,1458,1460],{"class":928,"line":958},[926,1455,962],{"class":961},[926,1457,966],{"class":965},[926,1459,970],{"class":969},[926,1461,973],{"class":947},[926,1463,1464,1466,1468,1470,1472,1474,1476,1478],{"class":928,"line":976},[926,1465,979],{"class":943},[926,1467,966],{"class":965},[926,1469,984],{"class":947},[926,1471,987],{"class":936},[926,1473,990],{"class":969},[926,1475,948],{"class":947},[926,1477,952],{"class":951},[926,1479,997],{"class":947},[926,1481,1482,1484,1486,1488],{"class":928,"line":1000},[926,1483,1003],{"class":961},[926,1485,1006],{"class":965},[926,1487,1010],{"class":1009},[926,1489,973],{"class":947},[926,1491,1492,1494,1496,1498,1500],{"class":928,"line":1015},[926,1493,1018],{"class":961},[926,1495,966],{"class":965},[926,1497,1023],{"class":969},[926,1499,1026],{"class":947},[926,1501,1029],{"class":969},[926,1503,1504,1506,1508,1510,1512,1514],{"class":928,"line":1032},[926,1505,1035],{"class":947},[926,1507,966],{"class":965},[926,1509,990],{"class":969},[926,1511,948],{"class":947},[926,1513,952],{"class":951},[926,1515,1046],{"class":947},[882,1517,1050],{"id":1049},[1052,1519,1520,1532],{},[1055,1521,1522],{},[1058,1523,1524,1526,1528,1530],{},[1061,1525,1063],{},[1061,1527,1066],{},[1061,1529,1069],{},[1061,1531,1072],{},[1074,1533,1534,1548,1562,1578],{},[1058,1535,1536,1540,1544,1546],{},[1079,1537,1538],{},[878,1539,1083],{},[1079,1541,1542],{},[878,1543,1088],{},[1079,1545,1091],{},[1079,1547,1094],{},[1058,1549,1550,1554,1558,1560],{},[1079,1551,1552],{},[878,1553,1101],{},[1079,1555,1556],{},[878,1557,1106],{},[1079,1559,1091],{},[1079,1561,1111],{},[1058,1563,1564,1568,1572,1576],{},[1079,1565,1566],{},[878,1567,1118],{},[1079,1569,1570],{},[878,1571,1123],{},[1079,1573,1574],{},[878,1575,1128],{},[1079,1577,1131],{},[1058,1579,1580,1584,1588,1590],{},[1079,1581,1582],{},[878,1583,1138],{},[1079,1585,1586],{},[878,1587,1143],{},[1079,1589,1091],{},[1079,1591,1148],{},[882,1593,1152],{"id":1151},[859,1595,1155],{},[916,1597,1598],{"className":1158,"code":1159,"filename":1160,"language":1161,"meta":922,"style":922},[878,1599,1600,1618,1632,1636,1648,1652,1662,1680,1702,1706,1710,1714,1718,1722],{"__ignoreMap":922},[926,1601,1602,1604,1606,1608,1610,1612,1614,1616],{"class":928,"line":929},[926,1603,1168],{"class":932},[926,1605,1171],{"class":947},[926,1607,194],{"class":1174},[926,1609,1177],{"class":947},[926,1611,1180],{"class":932},[926,1613,1184],{"class":1183},[926,1615,1188],{"class":1187},[926,1617,1191],{"class":1183},[926,1619,1620,1622,1624,1626,1628,1630],{"class":928,"line":958},[926,1621,1168],{"class":932},[926,1623,1023],{"class":1174},[926,1625,1200],{"class":932},[926,1627,1184],{"class":1183},[926,1629,1205],{"class":1187},[926,1631,1191],{"class":1183},[926,1633,1634],{"class":928,"line":976},[926,1635,1212],{"emptyLinePlaceholder":8},[926,1637,1638,1640,1642,1644,1646],{"class":928,"line":1000},[926,1639,1217],{"class":936},[926,1641,1221],{"class":1220},[926,1643,1006],{"class":965},[926,1645,1023],{"class":943},[926,1647,1228],{"class":947},[926,1649,1650],{"class":928,"line":1015},[926,1651,1212],{"emptyLinePlaceholder":8},[926,1653,1654,1656,1658,1660],{"class":928,"line":1032},[926,1655,1237],{"class":936},[926,1657,940],{"class":936},[926,1659,1242],{"class":943},[926,1661,1245],{"class":947},[926,1663,1664,1666,1668,1670,1672,1674,1676,1678],{"class":928,"line":1248},[926,1665,1251],{"class":1174},[926,1667,1026],{"class":947},[926,1669,1138],{"class":943},[926,1671,1258],{"class":947},[926,1673,1261],{"class":1183},[926,1675,1264],{"class":1187},[926,1677,1261],{"class":1183},[926,1679,1269],{"class":947},[926,1681,1682,1684,1686,1688,1690,1692,1694,1696,1698,1700],{"class":928,"line":1272},[926,1683,1275],{"class":932},[926,1685,1278],{"class":932},[926,1687,1281],{"class":1174},[926,1689,1026],{"class":947},[926,1691,1286],{"class":943},[926,1693,1258],{"class":947},[926,1695,1261],{"class":1183},[926,1697,1293],{"class":1187},[926,1699,1261],{"class":1183},[926,1701,1269],{"class":947},[926,1703,1704],{"class":928,"line":1300},[926,1705,1303],{"class":947},[926,1707,1708],{"class":928,"line":1306},[926,1709,1212],{"emptyLinePlaceholder":8},[926,1711,1712],{"class":928,"line":1311},[926,1713,1315],{"class":1314},[926,1715,1716],{"class":928,"line":1318},[926,1717,1321],{"class":1314},[926,1719,1720],{"class":928,"line":1324},[926,1721,1327],{"class":1314},[926,1723,1724,1726,1728,1730,1732,1734,1736,1738,1740,1742,1744,1746,1748,1750,1752,1754],{"class":928,"line":1330},[926,1725,1217],{"class":936},[926,1727,1335],{"class":1220},[926,1729,1006],{"class":965},[926,1731,1278],{"class":932},[926,1733,944],{"class":943},[926,1735,1258],{"class":947},[926,1737,1261],{"class":1183},[926,1739,1348],{"class":1187},[926,1741,1261],{"class":1183},[926,1743,1353],{"class":947},[926,1745,1356],{"class":1174},[926,1747,1353],{"class":947},[926,1749,1361],{"class":1009},[926,1751,1353],{"class":947},[926,1753,1366],{"class":1174},[926,1755,1269],{"class":947},[854,1757,1758],{"color":1371,"icon":28},[859,1759,1374],{},[1376,1761,1378],{},{"title":922,"searchDepth":958,"depth":958,"links":1763},[1764,1765,1766,1767],{"id":884,"depth":958,"text":885},{"id":913,"depth":958,"text":914},{"id":1049,"depth":958,"text":1050},{"id":1151,"depth":958,"text":1152},{},{"title":194,"description":1385},1780436297653]