[{"data":1,"prerenderedAt":3658},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Futils":64,"navigation":263,"navLinks_footer":835,"\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue_page":848,"\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue_surround":2423,"\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue":2426},{"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":130,"body":850,"description":2415,"extension":2416,"icon":2417,"meta":2418,"module":2419,"navigation":8,"path":131,"rawbody":2420,"seo":2421,"stem":132,"__hash__":2422},"docs\u002Fdocs\u002Futils\u002Fshared\u002FbatchQueue.md",{"type":851,"value":852,"toc":2404},"minimark",[853,876,888,903,908,1298,1302,1367,1370,1469,1473,1480,1486,1504,1510,1520,1525,1556,1559,1565,1579,1583,1586,2093,2096,2389,2400],[854,855,856,859,860,863,864,867,868,871,872,875],"p",{},[857,858,130],"code",{}," collects jobs in an internal buffer and flushes them in bulk. A flush triggers automatically when a job is added with ",[857,861,862],{},"'immediate'"," priority, when the buffer reaches ",[857,865,866],{},"maxBufferSize",", or when ",[857,869,870],{},"flushIntervalMs"," elapses. Failed flushes retry up to ",[857,873,874],{},"maxRetries"," times before the batch is discarded.",[854,877,878,880,881,884,885,887],{},[857,879,130],{}," deduplicates by job ",[857,882,883],{},"id",". When a job with the same ",[857,886,883],{}," is enqueued multiple times before a flush, the latest payload overwrites the earlier one. For example, if a user's bot score is updated three times per second but the queue flushes every three seconds, the database receives exactly one write for that user — containing the most recent score.",[854,889,890,891,895,896,899,900,902],{},"Every job has a ",[892,893,894],"strong",{},"priority",". ",[857,897,898],{},"'deferred'"," jobs accumulate in the buffer and flush together when the timer fires or the buffer fills — this is the normal mode that provides the batching benefit. ",[857,901,862],{}," jobs bypass the wait and trigger a flush right away, for high-urgency writes that cannot be delayed.",[904,905,907],"h2",{"id":906},"definition","Definition",[909,910,916],"pre",{"className":911,"code":912,"filename":913,"language":914,"meta":915,"style":915},"language-ts shiki shiki-themes light-plus light-plus dracula","export type Priority = 'immediate' | 'deferred'\n\nexport interface BatchQueueOptions {\n  \u002F** Maximum queued jobs before an automatic flush. @default 100 *\u002F\n  maxBufferSize?: number\n  \u002F** Milliseconds before flushing a non-full buffer. @default 5000 *\u002F\n  flushIntervalMs?: number\n  \u002F** Retry attempts on flush failure before discarding the batch. @default 3 *\u002F\n  maxRetries?: number\n  \u002F** Logger with `error` and `info` methods. @default console *\u002F\n  logger?: Pick\u003CConsole, 'error' | 'info'>\n}\n\nexport class BatchQueue\u003CT> {\n  constructor(\n    processor: (params: T) => Promise\u003Cvoid>,\n    options?: BatchQueueOptions\n  )\n\n  add(id: string, params: T, priority?: Priority): Promise\u003Cvoid>\n  flush(): Promise\u003Cvoid>\n  shutdown(): Promise\u003Cvoid>\n}\n","batchQueue.ts","ts","",[857,917,918,961,967,982,999,1012,1025,1035,1048,1058,1071,1111,1117,1122,1142,1151,1189,1200,1206,1211,1256,1275,1293],{"__ignoreMap":915},[919,920,923,927,931,935,939,943,947,950,953,955,958],"span",{"class":921,"line":922},"line",1,[919,924,926],{"class":925},"sZ328","export",[919,928,930],{"class":929},"sl46w"," type",[919,932,934],{"class":933},"sFs1U"," Priority",[919,936,938],{"class":937},"saOXh"," =",[919,940,942],{"class":941},"sFkSl"," '",[919,944,946],{"class":945},"sFB1V","immediate",[919,948,949],{"class":941},"'",[919,951,952],{"class":937}," |",[919,954,942],{"class":941},[919,956,957],{"class":945},"deferred",[919,959,960],{"class":941},"'\n",[919,962,964],{"class":921,"line":963},2,[919,965,966],{"emptyLinePlaceholder":8},"\n",[919,968,970,972,975,978],{"class":921,"line":969},3,[919,971,926],{"class":925},[919,973,974],{"class":929}," interface",[919,976,977],{"class":933}," BatchQueueOptions",[919,979,981],{"class":980},"sDd4n"," {\n",[919,983,985,989,992,996],{"class":921,"line":984},4,[919,986,988],{"class":987},"sghk6","  \u002F** Maximum queued jobs before an automatic flush. ",[919,990,991],{"class":929},"@default",[919,993,995],{"class":994},"sygFZ"," 100",[919,997,998],{"class":987}," *\u002F\n",[919,1000,1002,1006,1009],{"class":921,"line":1001},5,[919,1003,1005],{"class":1004},"sjsA6","  maxBufferSize",[919,1007,1008],{"class":937},"?:",[919,1010,1011],{"class":933}," number\n",[919,1013,1015,1018,1020,1023],{"class":921,"line":1014},6,[919,1016,1017],{"class":987},"  \u002F** Milliseconds before flushing a non-full buffer. ",[919,1019,991],{"class":929},[919,1021,1022],{"class":994}," 5000",[919,1024,998],{"class":987},[919,1026,1028,1031,1033],{"class":921,"line":1027},7,[919,1029,1030],{"class":1004},"  flushIntervalMs",[919,1032,1008],{"class":937},[919,1034,1011],{"class":933},[919,1036,1038,1041,1043,1046],{"class":921,"line":1037},8,[919,1039,1040],{"class":987},"  \u002F** Retry attempts on flush failure before discarding the batch. ",[919,1042,991],{"class":929},[919,1044,1045],{"class":994}," 3",[919,1047,998],{"class":987},[919,1049,1051,1054,1056],{"class":921,"line":1050},9,[919,1052,1053],{"class":1004},"  maxRetries",[919,1055,1008],{"class":937},[919,1057,1011],{"class":933},[919,1059,1061,1064,1066,1069],{"class":921,"line":1060},10,[919,1062,1063],{"class":987},"  \u002F** Logger with `error` and `info` methods. ",[919,1065,991],{"class":929},[919,1067,1068],{"class":994}," console",[919,1070,998],{"class":987},[919,1072,1074,1077,1079,1082,1085,1089,1092,1094,1097,1099,1101,1103,1106,1108],{"class":921,"line":1073},11,[919,1075,1076],{"class":1004},"  logger",[919,1078,1008],{"class":937},[919,1080,1081],{"class":933}," Pick",[919,1083,1084],{"class":980},"\u003C",[919,1086,1088],{"class":1087},"sW-rI","Console",[919,1090,1091],{"class":980},", ",[919,1093,949],{"class":941},[919,1095,1096],{"class":945},"error",[919,1098,949],{"class":941},[919,1100,952],{"class":937},[919,1102,942],{"class":941},[919,1104,1105],{"class":945},"info",[919,1107,949],{"class":941},[919,1109,1110],{"class":980},">\n",[919,1112,1114],{"class":921,"line":1113},12,[919,1115,1116],{"class":980},"}\n",[919,1118,1120],{"class":921,"line":1119},13,[919,1121,966],{"emptyLinePlaceholder":8},[919,1123,1125,1127,1130,1134,1136,1139],{"class":921,"line":1124},14,[919,1126,926],{"class":925},[919,1128,1129],{"class":929}," class",[919,1131,1133],{"class":1132},"s5jk-"," BatchQueue",[919,1135,1084],{"class":980},[919,1137,1138],{"class":1087},"T",[919,1140,1141],{"class":980},"> {\n",[919,1143,1145,1148],{"class":921,"line":1144},15,[919,1146,1147],{"class":929},"  constructor",[919,1149,1150],{"class":980},"(\n",[919,1152,1154,1158,1161,1164,1167,1169,1172,1175,1178,1181,1183,1186],{"class":921,"line":1153},16,[919,1155,1157],{"class":1156},"sHOzp","    processor",[919,1159,1160],{"class":937},":",[919,1162,1163],{"class":980}," (",[919,1165,1166],{"class":994},"params",[919,1168,1160],{"class":937},[919,1170,1171],{"class":933}," T",[919,1173,1174],{"class":980},") ",[919,1176,1177],{"class":929},"=>",[919,1179,1180],{"class":933}," Promise",[919,1182,1084],{"class":980},[919,1184,1185],{"class":933},"void",[919,1187,1188],{"class":980},">,\n",[919,1190,1192,1195,1197],{"class":921,"line":1191},17,[919,1193,1194],{"class":994},"    options",[919,1196,1008],{"class":937},[919,1198,1199],{"class":933}," BatchQueueOptions\n",[919,1201,1203],{"class":921,"line":1202},18,[919,1204,1205],{"class":980},"  )\n",[919,1207,1209],{"class":921,"line":1208},19,[919,1210,966],{"emptyLinePlaceholder":8},[919,1212,1214,1217,1220,1222,1224,1227,1229,1231,1233,1235,1237,1239,1241,1243,1246,1248,1250,1252,1254],{"class":921,"line":1213},20,[919,1215,1216],{"class":1156},"  add",[919,1218,1219],{"class":980},"(",[919,1221,883],{"class":994},[919,1223,1160],{"class":937},[919,1225,1226],{"class":933}," string",[919,1228,1091],{"class":980},[919,1230,1166],{"class":994},[919,1232,1160],{"class":937},[919,1234,1171],{"class":933},[919,1236,1091],{"class":980},[919,1238,894],{"class":994},[919,1240,1008],{"class":937},[919,1242,934],{"class":933},[919,1244,1245],{"class":980},")",[919,1247,1160],{"class":937},[919,1249,1180],{"class":933},[919,1251,1084],{"class":980},[919,1253,1185],{"class":933},[919,1255,1110],{"class":980},[919,1257,1259,1262,1265,1267,1269,1271,1273],{"class":921,"line":1258},21,[919,1260,1261],{"class":1156},"  flush",[919,1263,1264],{"class":980},"()",[919,1266,1160],{"class":937},[919,1268,1180],{"class":933},[919,1270,1084],{"class":980},[919,1272,1185],{"class":933},[919,1274,1110],{"class":980},[919,1276,1278,1281,1283,1285,1287,1289,1291],{"class":921,"line":1277},22,[919,1279,1280],{"class":1156},"  shutdown",[919,1282,1264],{"class":980},[919,1284,1160],{"class":937},[919,1286,1180],{"class":933},[919,1288,1084],{"class":980},[919,1290,1185],{"class":933},[919,1292,1110],{"class":980},[919,1294,1296],{"class":921,"line":1295},23,[919,1297,1116],{"class":980},[904,1299,1301],{"id":1300},"constructor-parameters","Constructor Parameters",[1303,1304,1305,1324],"table",{},[1306,1307,1308],"thead",{},[1309,1310,1311,1315,1318,1321],"tr",{},[1312,1313,1314],"th",{},"Parameter",[1312,1316,1317],{},"Type",[1312,1319,1320],{},"Required",[1312,1322,1323],{},"Description",[1325,1326,1327,1349],"tbody",{},[1309,1328,1329,1335,1340,1343],{},[1330,1331,1332],"td",{},[857,1333,1334],{},"processor",[1330,1336,1337],{},[857,1338,1339],{},"(params: T) => Promise\u003Cvoid>",[1330,1341,1342],{},"Yes",[1330,1344,1345,1346,1348],{},"Called once per job during a flush. Receives the job's ",[857,1347,1166],{}," object.",[1309,1350,1351,1356,1361,1364],{},[1330,1352,1353],{},[857,1354,1355],{},"options",[1330,1357,1358],{},[857,1359,1360],{},"BatchQueueOptions",[1330,1362,1363],{},"No",[1330,1365,1366],{},"Optional tuning parameters. See Options table.",[904,1368,1369],{"id":1355},"Options",[1303,1371,1372,1386],{},[1306,1373,1374],{},[1309,1375,1376,1379,1381,1384],{},[1312,1377,1378],{},"Option",[1312,1380,1317],{},[1312,1382,1383],{},"Default",[1312,1385,1323],{},[1325,1387,1388,1407,1425,1443],{},[1309,1389,1390,1394,1399,1404],{},[1330,1391,1392],{},[857,1393,866],{},[1330,1395,1396],{},[857,1397,1398],{},"number",[1330,1400,1401],{},[857,1402,1403],{},"100",[1330,1405,1406],{},"Flush when this many jobs are queued.",[1309,1408,1409,1413,1417,1422],{},[1330,1410,1411],{},[857,1412,870],{},[1330,1414,1415],{},[857,1416,1398],{},[1330,1418,1419],{},[857,1420,1421],{},"5000",[1330,1423,1424],{},"Flush after this many milliseconds of inactivity.",[1309,1426,1427,1431,1435,1440],{},[1330,1428,1429],{},[857,1430,874],{},[1330,1432,1433],{},[857,1434,1398],{},[1330,1436,1437],{},[857,1438,1439],{},"3",[1330,1441,1442],{},"Retry a failed flush this many times, with a 1-second delay between each attempt.",[1309,1444,1445,1450,1455,1460],{},[1330,1446,1447],{},[857,1448,1449],{},"logger",[1330,1451,1452],{},[857,1453,1454],{},"Pick\u003CConsole, 'error' | 'info'>",[1330,1456,1457],{},[857,1458,1459],{},"console",[1330,1461,1462,1463,1465,1466,1468],{},"Any logger with ",[857,1464,1096],{}," and ",[857,1467,1105],{}," methods, such as a pino child logger.",[904,1470,1472],{"id":1471},"methods","Methods",[1474,1475,1477],"h3",{"id":1476},"addid-params-priority",[857,1478,1479],{},"add(id, params, priority?)",[854,1481,1482,1483,1485],{},"Enqueues a job. A job with the same ",[857,1484,883],{}," already in the buffer is overwritten — the latest payload wins and the earlier one is discarded. This prevents stale data from being written when the same entity is updated multiple times before a flush.",[1487,1488,1489,1497],"ul",{},[1490,1491,1492,1496],"li",{},[892,1493,1494],{},[857,1495,898],{}," — Adds the job to the buffer. Starts the timer if it is not already running. Flushes when the timer fires or the buffer fills.",[1490,1498,1499,1503],{},[892,1500,1501],{},[857,1502,862],{}," — Adds the job and flushes the entire queue before returning. Use this for high-urgency events where waiting for the next timed or size-triggered flush is not acceptable.",[1474,1505,1507],{"id":1506},"flush",[857,1508,1509],{},"flush()",[854,1511,1512,1513,1515,1516,1519],{},"Forces all queued jobs to be processed, calling ",[857,1514,1334],{}," for each job in parallel via ",[857,1517,1518],{},"Promise.all",".",[854,1521,1522,1524],{},[857,1523,1509],{}," uses a while-loop guard to handle concurrent callers without losing jobs. Here is what happens when two callers overlap:",[1526,1527,1528,1534,1537,1543,1546],"ol",{},[1490,1529,1530,1531,1533],{},"Caller A calls ",[857,1532,1509],{},", snapshots the current batch, and clears the buffer.",[1490,1535,1536],{},"New jobs arrive in the buffer while Caller A is still processing.",[1490,1538,1539,1540,1542],{},"Caller B calls ",[857,1541,1509],{},", sees that a flush is already in progress, and waits.",[1490,1544,1545],{},"Caller A's flush completes. The while loop checks again — new jobs exist in the buffer.",[1490,1547,1548,1549,1551,1552,1555],{},"Those jobs are processed in a second pass. ",[857,1550,1509],{}," only returns once the in-flight promise is null ",[892,1553,1554],{},"and"," the buffer is empty.",[854,1557,1558],{},"No jobs are skipped regardless of how many callers overlap.",[1474,1560,1562],{"id":1561},"shutdown",[857,1563,1564],{},"shutdown()",[854,1566,1567,1568,1570,1571,1574,1575,1578],{},"Calls ",[857,1569,1509],{}," once and returns after all pending jobs are processed. Register this on ",[857,1572,1573],{},"SIGTERM"," or ",[857,1576,1577],{},"beforeExit"," to avoid dropping jobs when the process exits.",[904,1580,1582],{"id":1581},"example-usage","Example Usage",[854,1584,1585],{},"The most common use case is batching high-frequency database writes so each incoming request does not incur its own round-trip:",[909,1587,1592],{"className":1588,"code":1589,"filename":1590,"language":1591,"meta":915,"style":915},"language-typescript shiki shiki-themes light-plus light-plus dracula","import { BatchQueue } from '@riavzon\u002Futils'\n\ninterface VisitorUpdate {\n  userId: string\n  score: number\n  isBot: boolean\n}\n\n\u002F\u002F Called once per job when the batch flushes.\nasync function saveVisitor({ userId, score, isBot }: VisitorUpdate) {\n  await db.query(\n    'UPDATE visitors SET score = $1, is_bot = $2 WHERE id = $3',\n    [score, isBot, userId]\n  )\n}\n\nconst visitorQueue = new BatchQueue\u003CVisitorUpdate>(saveVisitor, {\n  maxBufferSize: 200,\n  flushIntervalMs: 3000,\n  maxRetries: 3,\n  logger: logger.child({ service: 'visitorQueue' }),\n})\n\n\u002F\u002F Duplicate ids are deduplicated — the second call replaces the first.\nawait visitorQueue.add(`visitor:${userId}`, { userId, score: 0.9, isBot: false })\nawait visitorQueue.add(`visitor:${userId}`, { userId, score: 0.95, isBot: false })\n\n\u002F\u002F Force an immediate flush for a confirmed ban.\nawait visitorQueue.add(`visitor:${userId}`, { userId, score: 1, isBot: true }, 'immediate')\n\n\u002F\u002F Drain on shutdown so no jobs are lost.\nprocess.on('SIGTERM', () => visitorQueue.shutdown())\n","visitorQueue.ts","typescript",[857,1593,1594,1617,1621,1631,1641,1650,1660,1664,1668,1673,1710,1725,1738,1756,1760,1764,1768,1799,1812,1823,1833,1864,1869,1873,1879,1935,1981,1986,1992,2049,2054,2060],{"__ignoreMap":915},[919,1595,1596,1599,1602,1604,1607,1610,1612,1615],{"class":921,"line":922},[919,1597,1598],{"class":925},"import",[919,1600,1601],{"class":980}," { ",[919,1603,130],{"class":1004},[919,1605,1606],{"class":980}," } ",[919,1608,1609],{"class":925},"from",[919,1611,942],{"class":941},[919,1613,1614],{"class":945},"@riavzon\u002Futils",[919,1616,960],{"class":941},[919,1618,1619],{"class":921,"line":963},[919,1620,966],{"emptyLinePlaceholder":8},[919,1622,1623,1626,1629],{"class":921,"line":969},[919,1624,1625],{"class":929},"interface",[919,1627,1628],{"class":933}," VisitorUpdate",[919,1630,981],{"class":980},[919,1632,1633,1636,1638],{"class":921,"line":984},[919,1634,1635],{"class":1004},"  userId",[919,1637,1160],{"class":937},[919,1639,1640],{"class":933}," string\n",[919,1642,1643,1646,1648],{"class":921,"line":1001},[919,1644,1645],{"class":1004},"  score",[919,1647,1160],{"class":937},[919,1649,1011],{"class":933},[919,1651,1652,1655,1657],{"class":921,"line":1014},[919,1653,1654],{"class":1004},"  isBot",[919,1656,1160],{"class":937},[919,1658,1659],{"class":933}," boolean\n",[919,1661,1662],{"class":921,"line":1027},[919,1663,1116],{"class":980},[919,1665,1666],{"class":921,"line":1037},[919,1667,966],{"emptyLinePlaceholder":8},[919,1669,1670],{"class":921,"line":1050},[919,1671,1672],{"class":987},"\u002F\u002F Called once per job when the batch flushes.\n",[919,1674,1675,1678,1681,1684,1687,1690,1692,1695,1697,1700,1703,1705,1707],{"class":921,"line":1060},[919,1676,1677],{"class":929},"async",[919,1679,1680],{"class":929}," function",[919,1682,1683],{"class":1156}," saveVisitor",[919,1685,1686],{"class":980},"({ ",[919,1688,1689],{"class":994},"userId",[919,1691,1091],{"class":980},[919,1693,1694],{"class":994},"score",[919,1696,1091],{"class":980},[919,1698,1699],{"class":994},"isBot",[919,1701,1702],{"class":980}," }",[919,1704,1160],{"class":937},[919,1706,1628],{"class":933},[919,1708,1709],{"class":980},") {\n",[919,1711,1712,1715,1718,1720,1723],{"class":921,"line":1073},[919,1713,1714],{"class":925},"  await",[919,1716,1717],{"class":1004}," db",[919,1719,1519],{"class":980},[919,1721,1722],{"class":1156},"query",[919,1724,1150],{"class":980},[919,1726,1727,1730,1733,1735],{"class":921,"line":1113},[919,1728,1729],{"class":941},"    '",[919,1731,1732],{"class":945},"UPDATE visitors SET score = $1, is_bot = $2 WHERE id = $3",[919,1734,949],{"class":941},[919,1736,1737],{"class":980},",\n",[919,1739,1740,1743,1745,1747,1749,1751,1753],{"class":921,"line":1119},[919,1741,1742],{"class":980},"    [",[919,1744,1694],{"class":1004},[919,1746,1091],{"class":980},[919,1748,1699],{"class":1004},[919,1750,1091],{"class":980},[919,1752,1689],{"class":1004},[919,1754,1755],{"class":980},"]\n",[919,1757,1758],{"class":921,"line":1124},[919,1759,1205],{"class":980},[919,1761,1762],{"class":921,"line":1144},[919,1763,1116],{"class":980},[919,1765,1766],{"class":921,"line":1153},[919,1767,966],{"emptyLinePlaceholder":8},[919,1769,1770,1773,1777,1779,1783,1785,1787,1790,1793,1796],{"class":921,"line":1191},[919,1771,1772],{"class":929},"const",[919,1774,1776],{"class":1775},"s3JHE"," visitorQueue",[919,1778,938],{"class":937},[919,1780,1782],{"class":1781},"sakC6"," new",[919,1784,1133],{"class":1156},[919,1786,1084],{"class":980},[919,1788,1789],{"class":1087},"VisitorUpdate",[919,1791,1792],{"class":980},">(",[919,1794,1795],{"class":1004},"saveVisitor",[919,1797,1798],{"class":980},", {\n",[919,1800,1801,1803,1806,1810],{"class":921,"line":1202},[919,1802,1005],{"class":1004},[919,1804,1160],{"class":1805},"s34zl",[919,1807,1809],{"class":1808},"spgvN"," 200",[919,1811,1737],{"class":980},[919,1813,1814,1816,1818,1821],{"class":921,"line":1208},[919,1815,1030],{"class":1004},[919,1817,1160],{"class":1805},[919,1819,1820],{"class":1808}," 3000",[919,1822,1737],{"class":980},[919,1824,1825,1827,1829,1831],{"class":921,"line":1213},[919,1826,1053],{"class":1004},[919,1828,1160],{"class":1805},[919,1830,1045],{"class":1808},[919,1832,1737],{"class":980},[919,1834,1835,1837,1839,1842,1844,1847,1849,1852,1854,1856,1859,1861],{"class":921,"line":1258},[919,1836,1076],{"class":1004},[919,1838,1160],{"class":1805},[919,1840,1841],{"class":1004}," logger",[919,1843,1519],{"class":980},[919,1845,1846],{"class":1156},"child",[919,1848,1686],{"class":980},[919,1850,1851],{"class":1004},"service",[919,1853,1160],{"class":1805},[919,1855,942],{"class":941},[919,1857,1858],{"class":945},"visitorQueue",[919,1860,949],{"class":941},[919,1862,1863],{"class":980}," }),\n",[919,1865,1866],{"class":921,"line":1277},[919,1867,1868],{"class":980},"})\n",[919,1870,1871],{"class":921,"line":1295},[919,1872,966],{"emptyLinePlaceholder":8},[919,1874,1876],{"class":921,"line":1875},24,[919,1877,1878],{"class":987},"\u002F\u002F Duplicate ids are deduplicated — the second call replaces the first.\n",[919,1880,1882,1885,1887,1889,1892,1894,1897,1900,1902,1905,1908,1911,1913,1915,1917,1919,1922,1924,1926,1928,1932],{"class":921,"line":1881},25,[919,1883,1884],{"class":925},"await",[919,1886,1776],{"class":1004},[919,1888,1519],{"class":980},[919,1890,1891],{"class":1156},"add",[919,1893,1219],{"class":980},[919,1895,1896],{"class":945},"`visitor:",[919,1898,1899],{"class":929},"${",[919,1901,1689],{"class":1004},[919,1903,1904],{"class":929},"}",[919,1906,1907],{"class":945},"`",[919,1909,1910],{"class":980},", { ",[919,1912,1689],{"class":1004},[919,1914,1091],{"class":980},[919,1916,1694],{"class":1004},[919,1918,1160],{"class":1805},[919,1920,1921],{"class":1808}," 0.9",[919,1923,1091],{"class":980},[919,1925,1699],{"class":1004},[919,1927,1160],{"class":1805},[919,1929,1931],{"class":1930},"sjR7W"," false",[919,1933,1934],{"class":980}," })\n",[919,1936,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956,1958,1960,1962,1964,1966,1968,1971,1973,1975,1977,1979],{"class":921,"line":1937},26,[919,1939,1884],{"class":925},[919,1941,1776],{"class":1004},[919,1943,1519],{"class":980},[919,1945,1891],{"class":1156},[919,1947,1219],{"class":980},[919,1949,1896],{"class":945},[919,1951,1899],{"class":929},[919,1953,1689],{"class":1004},[919,1955,1904],{"class":929},[919,1957,1907],{"class":945},[919,1959,1910],{"class":980},[919,1961,1689],{"class":1004},[919,1963,1091],{"class":980},[919,1965,1694],{"class":1004},[919,1967,1160],{"class":1805},[919,1969,1970],{"class":1808}," 0.95",[919,1972,1091],{"class":980},[919,1974,1699],{"class":1004},[919,1976,1160],{"class":1805},[919,1978,1931],{"class":1930},[919,1980,1934],{"class":980},[919,1982,1984],{"class":921,"line":1983},27,[919,1985,966],{"emptyLinePlaceholder":8},[919,1987,1989],{"class":921,"line":1988},28,[919,1990,1991],{"class":987},"\u002F\u002F Force an immediate flush for a confirmed ban.\n",[919,1993,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015,2017,2019,2021,2023,2025,2028,2030,2032,2034,2037,2040,2042,2044,2046],{"class":921,"line":1994},29,[919,1996,1884],{"class":925},[919,1998,1776],{"class":1004},[919,2000,1519],{"class":980},[919,2002,1891],{"class":1156},[919,2004,1219],{"class":980},[919,2006,1896],{"class":945},[919,2008,1899],{"class":929},[919,2010,1689],{"class":1004},[919,2012,1904],{"class":929},[919,2014,1907],{"class":945},[919,2016,1910],{"class":980},[919,2018,1689],{"class":1004},[919,2020,1091],{"class":980},[919,2022,1694],{"class":1004},[919,2024,1160],{"class":1805},[919,2026,2027],{"class":1808}," 1",[919,2029,1091],{"class":980},[919,2031,1699],{"class":1004},[919,2033,1160],{"class":1805},[919,2035,2036],{"class":1930}," true",[919,2038,2039],{"class":980}," }, ",[919,2041,949],{"class":941},[919,2043,946],{"class":945},[919,2045,949],{"class":941},[919,2047,2048],{"class":980},")\n",[919,2050,2052],{"class":921,"line":2051},30,[919,2053,966],{"emptyLinePlaceholder":8},[919,2055,2057],{"class":921,"line":2056},31,[919,2058,2059],{"class":987},"\u002F\u002F Drain on shutdown so no jobs are lost.\n",[919,2061,2063,2066,2068,2071,2073,2075,2077,2079,2082,2084,2086,2088,2090],{"class":921,"line":2062},32,[919,2064,2065],{"class":1004},"process",[919,2067,1519],{"class":980},[919,2069,2070],{"class":1156},"on",[919,2072,1219],{"class":980},[919,2074,949],{"class":941},[919,2076,1573],{"class":945},[919,2078,949],{"class":941},[919,2080,2081],{"class":980},", () ",[919,2083,1177],{"class":929},[919,2085,1776],{"class":1004},[919,2087,1519],{"class":980},[919,2089,1561],{"class":1156},[919,2091,2092],{"class":980},"())\n",[854,2094,2095],{},"Multiple queues with different job shapes can coexist independently:",[909,2097,2100],{"className":1588,"code":2098,"filename":2099,"language":1591,"meta":915,"style":915},"import { BatchQueue } from '@riavzon\u002Futils'\n\ninterface EmailJob  { to: string; subject: string; body: string }\ninterface MetricJob { name: string; value: number; tags: string[] }\n\nconst emailQueue = new BatchQueue\u003CEmailJob>(\n  async ({ to, subject, body }) => mailer.send(to, subject, body),\n  { maxBufferSize: 50, flushIntervalMs: 5000 }\n)\n\nconst metricsQueue = new BatchQueue\u003CMetricJob>(\n  async ({ name, value, tags }) => statsd.gauge(name, value, tags),\n  { maxBufferSize: 500, flushIntervalMs: 1000 }\n)\n","queues.ts",[857,2101,2102,2120,2124,2163,2201,2205,2226,2272,2293,2297,2301,2321,2363,2385],{"__ignoreMap":915},[919,2103,2104,2106,2108,2110,2112,2114,2116,2118],{"class":921,"line":922},[919,2105,1598],{"class":925},[919,2107,1601],{"class":980},[919,2109,130],{"class":1004},[919,2111,1606],{"class":980},[919,2113,1609],{"class":925},[919,2115,942],{"class":941},[919,2117,1614],{"class":945},[919,2119,960],{"class":941},[919,2121,2122],{"class":921,"line":963},[919,2123,966],{"emptyLinePlaceholder":8},[919,2125,2126,2128,2131,2134,2137,2139,2141,2144,2147,2149,2151,2153,2156,2158,2160],{"class":921,"line":969},[919,2127,1625],{"class":929},[919,2129,2130],{"class":933}," EmailJob",[919,2132,2133],{"class":980},"  { ",[919,2135,2136],{"class":1004},"to",[919,2138,1160],{"class":937},[919,2140,1226],{"class":933},[919,2142,2143],{"class":980},"; ",[919,2145,2146],{"class":1004},"subject",[919,2148,1160],{"class":937},[919,2150,1226],{"class":933},[919,2152,2143],{"class":980},[919,2154,2155],{"class":1004},"body",[919,2157,1160],{"class":937},[919,2159,1226],{"class":933},[919,2161,2162],{"class":980}," }\n",[919,2164,2165,2167,2170,2172,2175,2177,2179,2181,2184,2186,2189,2191,2194,2196,2198],{"class":921,"line":984},[919,2166,1625],{"class":929},[919,2168,2169],{"class":933}," MetricJob",[919,2171,1601],{"class":980},[919,2173,2174],{"class":1004},"name",[919,2176,1160],{"class":937},[919,2178,1226],{"class":933},[919,2180,2143],{"class":980},[919,2182,2183],{"class":1004},"value",[919,2185,1160],{"class":937},[919,2187,2188],{"class":933}," number",[919,2190,2143],{"class":980},[919,2192,2193],{"class":1004},"tags",[919,2195,1160],{"class":937},[919,2197,1226],{"class":933},[919,2199,2200],{"class":980},"[] }\n",[919,2202,2203],{"class":921,"line":1001},[919,2204,966],{"emptyLinePlaceholder":8},[919,2206,2207,2209,2212,2214,2216,2218,2220,2223],{"class":921,"line":1014},[919,2208,1772],{"class":929},[919,2210,2211],{"class":1775}," emailQueue",[919,2213,938],{"class":937},[919,2215,1782],{"class":1781},[919,2217,1133],{"class":1156},[919,2219,1084],{"class":980},[919,2221,2222],{"class":1087},"EmailJob",[919,2224,2225],{"class":980},">(\n",[919,2227,2228,2231,2234,2236,2238,2240,2242,2244,2247,2249,2252,2254,2257,2259,2261,2263,2265,2267,2269],{"class":921,"line":1027},[919,2229,2230],{"class":929},"  async",[919,2232,2233],{"class":980}," ({ ",[919,2235,2136],{"class":994},[919,2237,1091],{"class":980},[919,2239,2146],{"class":994},[919,2241,1091],{"class":980},[919,2243,2155],{"class":994},[919,2245,2246],{"class":980}," }) ",[919,2248,1177],{"class":929},[919,2250,2251],{"class":1004}," mailer",[919,2253,1519],{"class":980},[919,2255,2256],{"class":1156},"send",[919,2258,1219],{"class":980},[919,2260,2136],{"class":1004},[919,2262,1091],{"class":980},[919,2264,2146],{"class":1004},[919,2266,1091],{"class":980},[919,2268,2155],{"class":1004},[919,2270,2271],{"class":980},"),\n",[919,2273,2274,2276,2278,2280,2283,2285,2287,2289,2291],{"class":921,"line":1037},[919,2275,2133],{"class":980},[919,2277,866],{"class":1004},[919,2279,1160],{"class":1805},[919,2281,2282],{"class":1808}," 50",[919,2284,1091],{"class":980},[919,2286,870],{"class":1004},[919,2288,1160],{"class":1805},[919,2290,1022],{"class":1808},[919,2292,2162],{"class":980},[919,2294,2295],{"class":921,"line":1050},[919,2296,2048],{"class":980},[919,2298,2299],{"class":921,"line":1060},[919,2300,966],{"emptyLinePlaceholder":8},[919,2302,2303,2305,2308,2310,2312,2314,2316,2319],{"class":921,"line":1073},[919,2304,1772],{"class":929},[919,2306,2307],{"class":1775}," metricsQueue",[919,2309,938],{"class":937},[919,2311,1782],{"class":1781},[919,2313,1133],{"class":1156},[919,2315,1084],{"class":980},[919,2317,2318],{"class":1087},"MetricJob",[919,2320,2225],{"class":980},[919,2322,2323,2325,2327,2329,2331,2333,2335,2337,2339,2341,2344,2346,2349,2351,2353,2355,2357,2359,2361],{"class":921,"line":1113},[919,2324,2230],{"class":929},[919,2326,2233],{"class":980},[919,2328,2174],{"class":994},[919,2330,1091],{"class":980},[919,2332,2183],{"class":994},[919,2334,1091],{"class":980},[919,2336,2193],{"class":994},[919,2338,2246],{"class":980},[919,2340,1177],{"class":929},[919,2342,2343],{"class":1004}," statsd",[919,2345,1519],{"class":980},[919,2347,2348],{"class":1156},"gauge",[919,2350,1219],{"class":980},[919,2352,2174],{"class":1004},[919,2354,1091],{"class":980},[919,2356,2183],{"class":1004},[919,2358,1091],{"class":980},[919,2360,2193],{"class":1004},[919,2362,2271],{"class":980},[919,2364,2365,2367,2369,2371,2374,2376,2378,2380,2383],{"class":921,"line":1119},[919,2366,2133],{"class":980},[919,2368,866],{"class":1004},[919,2370,1160],{"class":1805},[919,2372,2373],{"class":1808}," 500",[919,2375,1091],{"class":980},[919,2377,870],{"class":1004},[919,2379,1160],{"class":1805},[919,2381,2382],{"class":1808}," 1000",[919,2384,2162],{"class":980},[919,2386,2387],{"class":921,"line":1124},[919,2388,2048],{"class":980},[2390,2391,2394],"callout",{"color":2392,"icon":2393},"warning","i-lucide-alert-triangle",[854,2395,2396,2397,2399],{},"Retries replay the original batch snapshot — not the live buffer. When a flush fails, the same captured batch is retried with a 1-second delay between attempts. Jobs that arrive during retries are held in the buffer and processed in the next flush cycle. After all retry attempts are exhausted, the snapshot is permanently discarded and an error is logged. Wrap your ",[857,2398,1334],{}," in a try\u002Fcatch that persists failed jobs to a dead-letter store before re-throwing if data loss is unacceptable.",[2401,2402,2403],"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 .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 .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}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 .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}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 .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--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 .s5jk-, html code.shiki .s5jk-{--shiki-light:#267F99;--shiki-default:#267F99;--shiki-dark:#8BE9FD}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}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 .s3JHE, html code.shiki .s3JHE{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#F8F8F2}html pre.shiki code .sakC6, html code.shiki .sakC6{--shiki-light:#0000FF;--shiki-light-font-weight:inherit;--shiki-default:#0000FF;--shiki-default-font-weight:inherit;--shiki-dark:#FF79C6;--shiki-dark-font-weight:bold}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .spgvN, html code.shiki .spgvN{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#BD93F9}html pre.shiki code .sjR7W, html code.shiki .sjR7W{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#BD93F9}",{"title":915,"searchDepth":963,"depth":963,"links":2405},[2406,2407,2408,2409,2414],{"id":906,"depth":963,"text":907},{"id":1300,"depth":963,"text":1301},{"id":1355,"depth":963,"text":1369},{"id":1471,"depth":963,"text":1472,"children":2410},[2411,2412,2413],{"id":1476,"depth":969,"text":1479},{"id":1506,"depth":969,"text":1509},{"id":1561,"depth":969,"text":1564},{"id":1581,"depth":963,"text":1582},"Generic in-memory batch queue that collects jobs and processes them in bulk with deduplication, retries, and graceful shutdown.","md","i-lucide-layers",{},null,"---\ntitle: BatchQueue\ndescription: Generic in-memory batch queue that collects jobs and processes them in bulk with deduplication, retries, and graceful shutdown.\nicon: i-lucide-layers\n---\n\n`BatchQueue` collects jobs in an internal buffer and flushes them in bulk. A flush triggers automatically when a job is added with `'immediate'` priority, when the buffer reaches `maxBufferSize`, or when `flushIntervalMs` elapses. Failed flushes retry up to `maxRetries` times before the batch is discarded.\n\n`BatchQueue` deduplicates by job `id`. When a job with the same `id` is enqueued multiple times before a flush, the latest payload overwrites the earlier one. For example, if a user's bot score is updated three times per second but the queue flushes every three seconds, the database receives exactly one write for that user — containing the most recent score.\n\nEvery job has a **priority**. `'deferred'` jobs accumulate in the buffer and flush together when the timer fires or the buffer fills — this is the normal mode that provides the batching benefit. `'immediate'` jobs bypass the wait and trigger a flush right away, for high-urgency writes that cannot be delayed.\n\n## Definition\n\n```ts [batchQueue.ts]\nexport type Priority = 'immediate' | 'deferred'\n\nexport interface BatchQueueOptions {\n  \u002F** Maximum queued jobs before an automatic flush. @default 100 *\u002F\n  maxBufferSize?: number\n  \u002F** Milliseconds before flushing a non-full buffer. @default 5000 *\u002F\n  flushIntervalMs?: number\n  \u002F** Retry attempts on flush failure before discarding the batch. @default 3 *\u002F\n  maxRetries?: number\n  \u002F** Logger with `error` and `info` methods. @default console *\u002F\n  logger?: Pick\u003CConsole, 'error' | 'info'>\n}\n\nexport class BatchQueue\u003CT> {\n  constructor(\n    processor: (params: T) => Promise\u003Cvoid>,\n    options?: BatchQueueOptions\n  )\n\n  add(id: string, params: T, priority?: Priority): Promise\u003Cvoid>\n  flush(): Promise\u003Cvoid>\n  shutdown(): Promise\u003Cvoid>\n}\n```\n\n## Constructor Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `processor` | `(params: T) => Promise\u003Cvoid>` | Yes | Called once per job during a flush. Receives the job's `params` object. |\n| `options` | `BatchQueueOptions` | No | Optional tuning parameters. See Options table. |\n\n## Options\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `maxBufferSize` | `number` | `100` | Flush when this many jobs are queued. |\n| `flushIntervalMs` | `number` | `5000` | Flush after this many milliseconds of inactivity. |\n| `maxRetries` | `number` | `3` | Retry a failed flush this many times, with a 1-second delay between each attempt. |\n| `logger` | `Pick\u003CConsole, 'error' \\| 'info'>` | `console` | Any logger with `error` and `info` methods, such as a pino child logger. |\n\n## Methods\n\n### `add(id, params, priority?)`\n\nEnqueues a job. A job with the same `id` already in the buffer is overwritten — the latest payload wins and the earlier one is discarded. This prevents stale data from being written when the same entity is updated multiple times before a flush.\n\n- **`'deferred'`** — Adds the job to the buffer. Starts the timer if it is not already running. Flushes when the timer fires or the buffer fills.\n- **`'immediate'`** — Adds the job and flushes the entire queue before returning. Use this for high-urgency events where waiting for the next timed or size-triggered flush is not acceptable.\n\n### `flush()`\n\nForces all queued jobs to be processed, calling `processor` for each job in parallel via `Promise.all`.\n\n`flush()` uses a while-loop guard to handle concurrent callers without losing jobs. Here is what happens when two callers overlap:\n\n1. Caller A calls `flush()`, snapshots the current batch, and clears the buffer.\n2. New jobs arrive in the buffer while Caller A is still processing.\n3. Caller B calls `flush()`, sees that a flush is already in progress, and waits.\n4. Caller A's flush completes. The while loop checks again — new jobs exist in the buffer.\n5. Those jobs are processed in a second pass. `flush()` only returns once the in-flight promise is null **and** the buffer is empty.\n\nNo jobs are skipped regardless of how many callers overlap.\n\n### `shutdown()`\n\nCalls `flush()` once and returns after all pending jobs are processed. Register this on `SIGTERM` or `beforeExit` to avoid dropping jobs when the process exits.\n\n## Example Usage\n\nThe most common use case is batching high-frequency database writes so each incoming request does not incur its own round-trip:\n\n```typescript [visitorQueue.ts]\nimport { BatchQueue } from '@riavzon\u002Futils'\n\ninterface VisitorUpdate {\n  userId: string\n  score: number\n  isBot: boolean\n}\n\n\u002F\u002F Called once per job when the batch flushes.\nasync function saveVisitor({ userId, score, isBot }: VisitorUpdate) {\n  await db.query(\n    'UPDATE visitors SET score = $1, is_bot = $2 WHERE id = $3',\n    [score, isBot, userId]\n  )\n}\n\nconst visitorQueue = new BatchQueue\u003CVisitorUpdate>(saveVisitor, {\n  maxBufferSize: 200,\n  flushIntervalMs: 3000,\n  maxRetries: 3,\n  logger: logger.child({ service: 'visitorQueue' }),\n})\n\n\u002F\u002F Duplicate ids are deduplicated — the second call replaces the first.\nawait visitorQueue.add(`visitor:${userId}`, { userId, score: 0.9, isBot: false })\nawait visitorQueue.add(`visitor:${userId}`, { userId, score: 0.95, isBot: false })\n\n\u002F\u002F Force an immediate flush for a confirmed ban.\nawait visitorQueue.add(`visitor:${userId}`, { userId, score: 1, isBot: true }, 'immediate')\n\n\u002F\u002F Drain on shutdown so no jobs are lost.\nprocess.on('SIGTERM', () => visitorQueue.shutdown())\n```\n\nMultiple queues with different job shapes can coexist independently:\n\n```typescript [queues.ts]\nimport { BatchQueue } from '@riavzon\u002Futils'\n\ninterface EmailJob  { to: string; subject: string; body: string }\ninterface MetricJob { name: string; value: number; tags: string[] }\n\nconst emailQueue = new BatchQueue\u003CEmailJob>(\n  async ({ to, subject, body }) => mailer.send(to, subject, body),\n  { maxBufferSize: 50, flushIntervalMs: 5000 }\n)\n\nconst metricsQueue = new BatchQueue\u003CMetricJob>(\n  async ({ name, value, tags }) => statsd.gauge(name, value, tags),\n  { maxBufferSize: 500, flushIntervalMs: 1000 }\n)\n```\n\n::callout{icon=\"i-lucide-alert-triangle\" color=\"warning\"}\nRetries replay the original batch snapshot — not the live buffer. When a flush fails, the same captured batch is retried with a 1-second delay between attempts. Jobs that arrive during retries are held in the buffer and processed in the next flush cycle. After all retry attempts are exhausted, the snapshot is permanently discarded and an error is logged. Wrap your `processor` in a try\u002Fcatch that persists failed jobs to a dead-letter store before re-throwing if data loss is unacceptable.\n::\n",{"title":130,"description":2415},"CenjK3uArbHg_GjVCR3EI_WdoqpCyyvwZ_vlFNr3Dgw",[2424,2425],{"title":121,"path":122,"stem":123,"children":-1},{"title":134,"path":135,"stem":136,"children":-1},{"id":849,"title":130,"body":2427,"description":2415,"extension":2416,"icon":2417,"meta":3656,"module":2419,"navigation":8,"path":131,"rawbody":2420,"seo":3657,"stem":132,"__hash__":2422},{"type":851,"value":2428,"toc":3645},[2429,2441,2449,2457,2459,2741,2743,2789,2791,2875,2877,2881,2885,2899,2903,2909,2913,2933,2935,2939,2947,2949,2951,3373,3375,3637,3643],[854,2430,2431,859,2433,863,2435,867,2437,871,2439,875],{},[857,2432,130],{},[857,2434,862],{},[857,2436,866],{},[857,2438,870],{},[857,2440,874],{},[854,2442,2443,880,2445,884,2447,887],{},[857,2444,130],{},[857,2446,883],{},[857,2448,883],{},[854,2450,890,2451,895,2453,899,2455,902],{},[892,2452,894],{},[857,2454,898],{},[857,2456,862],{},[904,2458,907],{"id":906},[909,2460,2461],{"className":911,"code":912,"filename":913,"language":914,"meta":915,"style":915},[857,2462,2463,2487,2491,2501,2511,2519,2529,2537,2547,2555,2565,2595,2599,2603,2617,2623,2649,2657,2661,2665,2705,2721,2737],{"__ignoreMap":915},[919,2464,2465,2467,2469,2471,2473,2475,2477,2479,2481,2483,2485],{"class":921,"line":922},[919,2466,926],{"class":925},[919,2468,930],{"class":929},[919,2470,934],{"class":933},[919,2472,938],{"class":937},[919,2474,942],{"class":941},[919,2476,946],{"class":945},[919,2478,949],{"class":941},[919,2480,952],{"class":937},[919,2482,942],{"class":941},[919,2484,957],{"class":945},[919,2486,960],{"class":941},[919,2488,2489],{"class":921,"line":963},[919,2490,966],{"emptyLinePlaceholder":8},[919,2492,2493,2495,2497,2499],{"class":921,"line":969},[919,2494,926],{"class":925},[919,2496,974],{"class":929},[919,2498,977],{"class":933},[919,2500,981],{"class":980},[919,2502,2503,2505,2507,2509],{"class":921,"line":984},[919,2504,988],{"class":987},[919,2506,991],{"class":929},[919,2508,995],{"class":994},[919,2510,998],{"class":987},[919,2512,2513,2515,2517],{"class":921,"line":1001},[919,2514,1005],{"class":1004},[919,2516,1008],{"class":937},[919,2518,1011],{"class":933},[919,2520,2521,2523,2525,2527],{"class":921,"line":1014},[919,2522,1017],{"class":987},[919,2524,991],{"class":929},[919,2526,1022],{"class":994},[919,2528,998],{"class":987},[919,2530,2531,2533,2535],{"class":921,"line":1027},[919,2532,1030],{"class":1004},[919,2534,1008],{"class":937},[919,2536,1011],{"class":933},[919,2538,2539,2541,2543,2545],{"class":921,"line":1037},[919,2540,1040],{"class":987},[919,2542,991],{"class":929},[919,2544,1045],{"class":994},[919,2546,998],{"class":987},[919,2548,2549,2551,2553],{"class":921,"line":1050},[919,2550,1053],{"class":1004},[919,2552,1008],{"class":937},[919,2554,1011],{"class":933},[919,2556,2557,2559,2561,2563],{"class":921,"line":1060},[919,2558,1063],{"class":987},[919,2560,991],{"class":929},[919,2562,1068],{"class":994},[919,2564,998],{"class":987},[919,2566,2567,2569,2571,2573,2575,2577,2579,2581,2583,2585,2587,2589,2591,2593],{"class":921,"line":1073},[919,2568,1076],{"class":1004},[919,2570,1008],{"class":937},[919,2572,1081],{"class":933},[919,2574,1084],{"class":980},[919,2576,1088],{"class":1087},[919,2578,1091],{"class":980},[919,2580,949],{"class":941},[919,2582,1096],{"class":945},[919,2584,949],{"class":941},[919,2586,952],{"class":937},[919,2588,942],{"class":941},[919,2590,1105],{"class":945},[919,2592,949],{"class":941},[919,2594,1110],{"class":980},[919,2596,2597],{"class":921,"line":1113},[919,2598,1116],{"class":980},[919,2600,2601],{"class":921,"line":1119},[919,2602,966],{"emptyLinePlaceholder":8},[919,2604,2605,2607,2609,2611,2613,2615],{"class":921,"line":1124},[919,2606,926],{"class":925},[919,2608,1129],{"class":929},[919,2610,1133],{"class":1132},[919,2612,1084],{"class":980},[919,2614,1138],{"class":1087},[919,2616,1141],{"class":980},[919,2618,2619,2621],{"class":921,"line":1144},[919,2620,1147],{"class":929},[919,2622,1150],{"class":980},[919,2624,2625,2627,2629,2631,2633,2635,2637,2639,2641,2643,2645,2647],{"class":921,"line":1153},[919,2626,1157],{"class":1156},[919,2628,1160],{"class":937},[919,2630,1163],{"class":980},[919,2632,1166],{"class":994},[919,2634,1160],{"class":937},[919,2636,1171],{"class":933},[919,2638,1174],{"class":980},[919,2640,1177],{"class":929},[919,2642,1180],{"class":933},[919,2644,1084],{"class":980},[919,2646,1185],{"class":933},[919,2648,1188],{"class":980},[919,2650,2651,2653,2655],{"class":921,"line":1191},[919,2652,1194],{"class":994},[919,2654,1008],{"class":937},[919,2656,1199],{"class":933},[919,2658,2659],{"class":921,"line":1202},[919,2660,1205],{"class":980},[919,2662,2663],{"class":921,"line":1208},[919,2664,966],{"emptyLinePlaceholder":8},[919,2666,2667,2669,2671,2673,2675,2677,2679,2681,2683,2685,2687,2689,2691,2693,2695,2697,2699,2701,2703],{"class":921,"line":1213},[919,2668,1216],{"class":1156},[919,2670,1219],{"class":980},[919,2672,883],{"class":994},[919,2674,1160],{"class":937},[919,2676,1226],{"class":933},[919,2678,1091],{"class":980},[919,2680,1166],{"class":994},[919,2682,1160],{"class":937},[919,2684,1171],{"class":933},[919,2686,1091],{"class":980},[919,2688,894],{"class":994},[919,2690,1008],{"class":937},[919,2692,934],{"class":933},[919,2694,1245],{"class":980},[919,2696,1160],{"class":937},[919,2698,1180],{"class":933},[919,2700,1084],{"class":980},[919,2702,1185],{"class":933},[919,2704,1110],{"class":980},[919,2706,2707,2709,2711,2713,2715,2717,2719],{"class":921,"line":1258},[919,2708,1261],{"class":1156},[919,2710,1264],{"class":980},[919,2712,1160],{"class":937},[919,2714,1180],{"class":933},[919,2716,1084],{"class":980},[919,2718,1185],{"class":933},[919,2720,1110],{"class":980},[919,2722,2723,2725,2727,2729,2731,2733,2735],{"class":921,"line":1277},[919,2724,1280],{"class":1156},[919,2726,1264],{"class":980},[919,2728,1160],{"class":937},[919,2730,1180],{"class":933},[919,2732,1084],{"class":980},[919,2734,1185],{"class":933},[919,2736,1110],{"class":980},[919,2738,2739],{"class":921,"line":1295},[919,2740,1116],{"class":980},[904,2742,1301],{"id":1300},[1303,2744,2745,2757],{},[1306,2746,2747],{},[1309,2748,2749,2751,2753,2755],{},[1312,2750,1314],{},[1312,2752,1317],{},[1312,2754,1320],{},[1312,2756,1323],{},[1325,2758,2759,2775],{},[1309,2760,2761,2765,2769,2771],{},[1330,2762,2763],{},[857,2764,1334],{},[1330,2766,2767],{},[857,2768,1339],{},[1330,2770,1342],{},[1330,2772,1345,2773,1348],{},[857,2774,1166],{},[1309,2776,2777,2781,2785,2787],{},[1330,2778,2779],{},[857,2780,1355],{},[1330,2782,2783],{},[857,2784,1360],{},[1330,2786,1363],{},[1330,2788,1366],{},[904,2790,1369],{"id":1355},[1303,2792,2793,2805],{},[1306,2794,2795],{},[1309,2796,2797,2799,2801,2803],{},[1312,2798,1378],{},[1312,2800,1317],{},[1312,2802,1383],{},[1312,2804,1323],{},[1325,2806,2807,2823,2839,2855],{},[1309,2808,2809,2813,2817,2821],{},[1330,2810,2811],{},[857,2812,866],{},[1330,2814,2815],{},[857,2816,1398],{},[1330,2818,2819],{},[857,2820,1403],{},[1330,2822,1406],{},[1309,2824,2825,2829,2833,2837],{},[1330,2826,2827],{},[857,2828,870],{},[1330,2830,2831],{},[857,2832,1398],{},[1330,2834,2835],{},[857,2836,1421],{},[1330,2838,1424],{},[1309,2840,2841,2845,2849,2853],{},[1330,2842,2843],{},[857,2844,874],{},[1330,2846,2847],{},[857,2848,1398],{},[1330,2850,2851],{},[857,2852,1439],{},[1330,2854,1442],{},[1309,2856,2857,2861,2865,2869],{},[1330,2858,2859],{},[857,2860,1449],{},[1330,2862,2863],{},[857,2864,1454],{},[1330,2866,2867],{},[857,2868,1459],{},[1330,2870,1462,2871,1465,2873,1468],{},[857,2872,1096],{},[857,2874,1105],{},[904,2876,1472],{"id":1471},[1474,2878,2879],{"id":1476},[857,2880,1479],{},[854,2882,1482,2883,1485],{},[857,2884,883],{},[1487,2886,2887,2893],{},[1490,2888,2889,1496],{},[892,2890,2891],{},[857,2892,898],{},[1490,2894,2895,1503],{},[892,2896,2897],{},[857,2898,862],{},[1474,2900,2901],{"id":1506},[857,2902,1509],{},[854,2904,1512,2905,1515,2907,1519],{},[857,2906,1334],{},[857,2908,1518],{},[854,2910,2911,1524],{},[857,2912,1509],{},[1526,2914,2915,2919,2921,2925,2927],{},[1490,2916,1530,2917,1533],{},[857,2918,1509],{},[1490,2920,1536],{},[1490,2922,1539,2923,1542],{},[857,2924,1509],{},[1490,2926,1545],{},[1490,2928,1548,2929,1551,2931,1555],{},[857,2930,1509],{},[892,2932,1554],{},[854,2934,1558],{},[1474,2936,2937],{"id":1561},[857,2938,1564],{},[854,2940,1567,2941,1570,2943,1574,2945,1578],{},[857,2942,1509],{},[857,2944,1573],{},[857,2946,1577],{},[904,2948,1582],{"id":1581},[854,2950,1585],{},[909,2952,2953],{"className":1588,"code":1589,"filename":1590,"language":1591,"meta":915,"style":915},[857,2954,2955,2973,2977,2985,2993,3001,3009,3013,3017,3021,3049,3061,3071,3087,3091,3095,3099,3121,3131,3141,3151,3177,3181,3185,3189,3233,3277,3281,3285,3337,3341,3345],{"__ignoreMap":915},[919,2956,2957,2959,2961,2963,2965,2967,2969,2971],{"class":921,"line":922},[919,2958,1598],{"class":925},[919,2960,1601],{"class":980},[919,2962,130],{"class":1004},[919,2964,1606],{"class":980},[919,2966,1609],{"class":925},[919,2968,942],{"class":941},[919,2970,1614],{"class":945},[919,2972,960],{"class":941},[919,2974,2975],{"class":921,"line":963},[919,2976,966],{"emptyLinePlaceholder":8},[919,2978,2979,2981,2983],{"class":921,"line":969},[919,2980,1625],{"class":929},[919,2982,1628],{"class":933},[919,2984,981],{"class":980},[919,2986,2987,2989,2991],{"class":921,"line":984},[919,2988,1635],{"class":1004},[919,2990,1160],{"class":937},[919,2992,1640],{"class":933},[919,2994,2995,2997,2999],{"class":921,"line":1001},[919,2996,1645],{"class":1004},[919,2998,1160],{"class":937},[919,3000,1011],{"class":933},[919,3002,3003,3005,3007],{"class":921,"line":1014},[919,3004,1654],{"class":1004},[919,3006,1160],{"class":937},[919,3008,1659],{"class":933},[919,3010,3011],{"class":921,"line":1027},[919,3012,1116],{"class":980},[919,3014,3015],{"class":921,"line":1037},[919,3016,966],{"emptyLinePlaceholder":8},[919,3018,3019],{"class":921,"line":1050},[919,3020,1672],{"class":987},[919,3022,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043,3045,3047],{"class":921,"line":1060},[919,3024,1677],{"class":929},[919,3026,1680],{"class":929},[919,3028,1683],{"class":1156},[919,3030,1686],{"class":980},[919,3032,1689],{"class":994},[919,3034,1091],{"class":980},[919,3036,1694],{"class":994},[919,3038,1091],{"class":980},[919,3040,1699],{"class":994},[919,3042,1702],{"class":980},[919,3044,1160],{"class":937},[919,3046,1628],{"class":933},[919,3048,1709],{"class":980},[919,3050,3051,3053,3055,3057,3059],{"class":921,"line":1073},[919,3052,1714],{"class":925},[919,3054,1717],{"class":1004},[919,3056,1519],{"class":980},[919,3058,1722],{"class":1156},[919,3060,1150],{"class":980},[919,3062,3063,3065,3067,3069],{"class":921,"line":1113},[919,3064,1729],{"class":941},[919,3066,1732],{"class":945},[919,3068,949],{"class":941},[919,3070,1737],{"class":980},[919,3072,3073,3075,3077,3079,3081,3083,3085],{"class":921,"line":1119},[919,3074,1742],{"class":980},[919,3076,1694],{"class":1004},[919,3078,1091],{"class":980},[919,3080,1699],{"class":1004},[919,3082,1091],{"class":980},[919,3084,1689],{"class":1004},[919,3086,1755],{"class":980},[919,3088,3089],{"class":921,"line":1124},[919,3090,1205],{"class":980},[919,3092,3093],{"class":921,"line":1144},[919,3094,1116],{"class":980},[919,3096,3097],{"class":921,"line":1153},[919,3098,966],{"emptyLinePlaceholder":8},[919,3100,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119],{"class":921,"line":1191},[919,3102,1772],{"class":929},[919,3104,1776],{"class":1775},[919,3106,938],{"class":937},[919,3108,1782],{"class":1781},[919,3110,1133],{"class":1156},[919,3112,1084],{"class":980},[919,3114,1789],{"class":1087},[919,3116,1792],{"class":980},[919,3118,1795],{"class":1004},[919,3120,1798],{"class":980},[919,3122,3123,3125,3127,3129],{"class":921,"line":1202},[919,3124,1005],{"class":1004},[919,3126,1160],{"class":1805},[919,3128,1809],{"class":1808},[919,3130,1737],{"class":980},[919,3132,3133,3135,3137,3139],{"class":921,"line":1208},[919,3134,1030],{"class":1004},[919,3136,1160],{"class":1805},[919,3138,1820],{"class":1808},[919,3140,1737],{"class":980},[919,3142,3143,3145,3147,3149],{"class":921,"line":1213},[919,3144,1053],{"class":1004},[919,3146,1160],{"class":1805},[919,3148,1045],{"class":1808},[919,3150,1737],{"class":980},[919,3152,3153,3155,3157,3159,3161,3163,3165,3167,3169,3171,3173,3175],{"class":921,"line":1258},[919,3154,1076],{"class":1004},[919,3156,1160],{"class":1805},[919,3158,1841],{"class":1004},[919,3160,1519],{"class":980},[919,3162,1846],{"class":1156},[919,3164,1686],{"class":980},[919,3166,1851],{"class":1004},[919,3168,1160],{"class":1805},[919,3170,942],{"class":941},[919,3172,1858],{"class":945},[919,3174,949],{"class":941},[919,3176,1863],{"class":980},[919,3178,3179],{"class":921,"line":1277},[919,3180,1868],{"class":980},[919,3182,3183],{"class":921,"line":1295},[919,3184,966],{"emptyLinePlaceholder":8},[919,3186,3187],{"class":921,"line":1875},[919,3188,1878],{"class":987},[919,3190,3191,3193,3195,3197,3199,3201,3203,3205,3207,3209,3211,3213,3215,3217,3219,3221,3223,3225,3227,3229,3231],{"class":921,"line":1881},[919,3192,1884],{"class":925},[919,3194,1776],{"class":1004},[919,3196,1519],{"class":980},[919,3198,1891],{"class":1156},[919,3200,1219],{"class":980},[919,3202,1896],{"class":945},[919,3204,1899],{"class":929},[919,3206,1689],{"class":1004},[919,3208,1904],{"class":929},[919,3210,1907],{"class":945},[919,3212,1910],{"class":980},[919,3214,1689],{"class":1004},[919,3216,1091],{"class":980},[919,3218,1694],{"class":1004},[919,3220,1160],{"class":1805},[919,3222,1921],{"class":1808},[919,3224,1091],{"class":980},[919,3226,1699],{"class":1004},[919,3228,1160],{"class":1805},[919,3230,1931],{"class":1930},[919,3232,1934],{"class":980},[919,3234,3235,3237,3239,3241,3243,3245,3247,3249,3251,3253,3255,3257,3259,3261,3263,3265,3267,3269,3271,3273,3275],{"class":921,"line":1937},[919,3236,1884],{"class":925},[919,3238,1776],{"class":1004},[919,3240,1519],{"class":980},[919,3242,1891],{"class":1156},[919,3244,1219],{"class":980},[919,3246,1896],{"class":945},[919,3248,1899],{"class":929},[919,3250,1689],{"class":1004},[919,3252,1904],{"class":929},[919,3254,1907],{"class":945},[919,3256,1910],{"class":980},[919,3258,1689],{"class":1004},[919,3260,1091],{"class":980},[919,3262,1694],{"class":1004},[919,3264,1160],{"class":1805},[919,3266,1970],{"class":1808},[919,3268,1091],{"class":980},[919,3270,1699],{"class":1004},[919,3272,1160],{"class":1805},[919,3274,1931],{"class":1930},[919,3276,1934],{"class":980},[919,3278,3279],{"class":921,"line":1983},[919,3280,966],{"emptyLinePlaceholder":8},[919,3282,3283],{"class":921,"line":1988},[919,3284,1991],{"class":987},[919,3286,3287,3289,3291,3293,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313,3315,3317,3319,3321,3323,3325,3327,3329,3331,3333,3335],{"class":921,"line":1994},[919,3288,1884],{"class":925},[919,3290,1776],{"class":1004},[919,3292,1519],{"class":980},[919,3294,1891],{"class":1156},[919,3296,1219],{"class":980},[919,3298,1896],{"class":945},[919,3300,1899],{"class":929},[919,3302,1689],{"class":1004},[919,3304,1904],{"class":929},[919,3306,1907],{"class":945},[919,3308,1910],{"class":980},[919,3310,1689],{"class":1004},[919,3312,1091],{"class":980},[919,3314,1694],{"class":1004},[919,3316,1160],{"class":1805},[919,3318,2027],{"class":1808},[919,3320,1091],{"class":980},[919,3322,1699],{"class":1004},[919,3324,1160],{"class":1805},[919,3326,2036],{"class":1930},[919,3328,2039],{"class":980},[919,3330,949],{"class":941},[919,3332,946],{"class":945},[919,3334,949],{"class":941},[919,3336,2048],{"class":980},[919,3338,3339],{"class":921,"line":2051},[919,3340,966],{"emptyLinePlaceholder":8},[919,3342,3343],{"class":921,"line":2056},[919,3344,2059],{"class":987},[919,3346,3347,3349,3351,3353,3355,3357,3359,3361,3363,3365,3367,3369,3371],{"class":921,"line":2062},[919,3348,2065],{"class":1004},[919,3350,1519],{"class":980},[919,3352,2070],{"class":1156},[919,3354,1219],{"class":980},[919,3356,949],{"class":941},[919,3358,1573],{"class":945},[919,3360,949],{"class":941},[919,3362,2081],{"class":980},[919,3364,1177],{"class":929},[919,3366,1776],{"class":1004},[919,3368,1519],{"class":980},[919,3370,1561],{"class":1156},[919,3372,2092],{"class":980},[854,3374,2095],{},[909,3376,3377],{"className":1588,"code":2098,"filename":2099,"language":1591,"meta":915,"style":915},[857,3378,3379,3397,3401,3433,3465,3469,3487,3527,3547,3551,3555,3573,3613,3633],{"__ignoreMap":915},[919,3380,3381,3383,3385,3387,3389,3391,3393,3395],{"class":921,"line":922},[919,3382,1598],{"class":925},[919,3384,1601],{"class":980},[919,3386,130],{"class":1004},[919,3388,1606],{"class":980},[919,3390,1609],{"class":925},[919,3392,942],{"class":941},[919,3394,1614],{"class":945},[919,3396,960],{"class":941},[919,3398,3399],{"class":921,"line":963},[919,3400,966],{"emptyLinePlaceholder":8},[919,3402,3403,3405,3407,3409,3411,3413,3415,3417,3419,3421,3423,3425,3427,3429,3431],{"class":921,"line":969},[919,3404,1625],{"class":929},[919,3406,2130],{"class":933},[919,3408,2133],{"class":980},[919,3410,2136],{"class":1004},[919,3412,1160],{"class":937},[919,3414,1226],{"class":933},[919,3416,2143],{"class":980},[919,3418,2146],{"class":1004},[919,3420,1160],{"class":937},[919,3422,1226],{"class":933},[919,3424,2143],{"class":980},[919,3426,2155],{"class":1004},[919,3428,1160],{"class":937},[919,3430,1226],{"class":933},[919,3432,2162],{"class":980},[919,3434,3435,3437,3439,3441,3443,3445,3447,3449,3451,3453,3455,3457,3459,3461,3463],{"class":921,"line":984},[919,3436,1625],{"class":929},[919,3438,2169],{"class":933},[919,3440,1601],{"class":980},[919,3442,2174],{"class":1004},[919,3444,1160],{"class":937},[919,3446,1226],{"class":933},[919,3448,2143],{"class":980},[919,3450,2183],{"class":1004},[919,3452,1160],{"class":937},[919,3454,2188],{"class":933},[919,3456,2143],{"class":980},[919,3458,2193],{"class":1004},[919,3460,1160],{"class":937},[919,3462,1226],{"class":933},[919,3464,2200],{"class":980},[919,3466,3467],{"class":921,"line":1001},[919,3468,966],{"emptyLinePlaceholder":8},[919,3470,3471,3473,3475,3477,3479,3481,3483,3485],{"class":921,"line":1014},[919,3472,1772],{"class":929},[919,3474,2211],{"class":1775},[919,3476,938],{"class":937},[919,3478,1782],{"class":1781},[919,3480,1133],{"class":1156},[919,3482,1084],{"class":980},[919,3484,2222],{"class":1087},[919,3486,2225],{"class":980},[919,3488,3489,3491,3493,3495,3497,3499,3501,3503,3505,3507,3509,3511,3513,3515,3517,3519,3521,3523,3525],{"class":921,"line":1027},[919,3490,2230],{"class":929},[919,3492,2233],{"class":980},[919,3494,2136],{"class":994},[919,3496,1091],{"class":980},[919,3498,2146],{"class":994},[919,3500,1091],{"class":980},[919,3502,2155],{"class":994},[919,3504,2246],{"class":980},[919,3506,1177],{"class":929},[919,3508,2251],{"class":1004},[919,3510,1519],{"class":980},[919,3512,2256],{"class":1156},[919,3514,1219],{"class":980},[919,3516,2136],{"class":1004},[919,3518,1091],{"class":980},[919,3520,2146],{"class":1004},[919,3522,1091],{"class":980},[919,3524,2155],{"class":1004},[919,3526,2271],{"class":980},[919,3528,3529,3531,3533,3535,3537,3539,3541,3543,3545],{"class":921,"line":1037},[919,3530,2133],{"class":980},[919,3532,866],{"class":1004},[919,3534,1160],{"class":1805},[919,3536,2282],{"class":1808},[919,3538,1091],{"class":980},[919,3540,870],{"class":1004},[919,3542,1160],{"class":1805},[919,3544,1022],{"class":1808},[919,3546,2162],{"class":980},[919,3548,3549],{"class":921,"line":1050},[919,3550,2048],{"class":980},[919,3552,3553],{"class":921,"line":1060},[919,3554,966],{"emptyLinePlaceholder":8},[919,3556,3557,3559,3561,3563,3565,3567,3569,3571],{"class":921,"line":1073},[919,3558,1772],{"class":929},[919,3560,2307],{"class":1775},[919,3562,938],{"class":937},[919,3564,1782],{"class":1781},[919,3566,1133],{"class":1156},[919,3568,1084],{"class":980},[919,3570,2318],{"class":1087},[919,3572,2225],{"class":980},[919,3574,3575,3577,3579,3581,3583,3585,3587,3589,3591,3593,3595,3597,3599,3601,3603,3605,3607,3609,3611],{"class":921,"line":1113},[919,3576,2230],{"class":929},[919,3578,2233],{"class":980},[919,3580,2174],{"class":994},[919,3582,1091],{"class":980},[919,3584,2183],{"class":994},[919,3586,1091],{"class":980},[919,3588,2193],{"class":994},[919,3590,2246],{"class":980},[919,3592,1177],{"class":929},[919,3594,2343],{"class":1004},[919,3596,1519],{"class":980},[919,3598,2348],{"class":1156},[919,3600,1219],{"class":980},[919,3602,2174],{"class":1004},[919,3604,1091],{"class":980},[919,3606,2183],{"class":1004},[919,3608,1091],{"class":980},[919,3610,2193],{"class":1004},[919,3612,2271],{"class":980},[919,3614,3615,3617,3619,3621,3623,3625,3627,3629,3631],{"class":921,"line":1119},[919,3616,2133],{"class":980},[919,3618,866],{"class":1004},[919,3620,1160],{"class":1805},[919,3622,2373],{"class":1808},[919,3624,1091],{"class":980},[919,3626,870],{"class":1004},[919,3628,1160],{"class":1805},[919,3630,2382],{"class":1808},[919,3632,2162],{"class":980},[919,3634,3635],{"class":921,"line":1124},[919,3636,2048],{"class":980},[2390,3638,3639],{"color":2392,"icon":2393},[854,3640,2396,3641,2399],{},[857,3642,1334],{},[2401,3644,2403],{},{"title":915,"searchDepth":963,"depth":963,"links":3646},[3647,3648,3649,3650,3655],{"id":906,"depth":963,"text":907},{"id":1300,"depth":963,"text":1301},{"id":1355,"depth":963,"text":1369},{"id":1471,"depth":963,"text":1472,"children":3651},[3652,3653,3654],{"id":1476,"depth":969,"text":1479},{"id":1506,"depth":969,"text":1509},{"id":1561,"depth":969,"text":1564},{"id":1581,"depth":963,"text":1582},{},{"title":130,"description":2415},1780436296053]