@outray/runtime-shared 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +4 -2
- package/dist/buffered-logger.cjs +102 -0
- package/dist/buffered-logger.cjs.map +1 -0
- package/dist/buffered-logger.d.cts +26 -0
- package/dist/buffered-logger.d.ts +26 -0
- package/dist/buffered-logger.js +77 -0
- package/dist/buffered-logger.js.map +1 -0
- package/dist/chunk-7Z55KL36.js +1111 -0
- package/dist/chunk-7Z55KL36.js.map +1 -0
- package/dist/chunk-EBXUVSOO.js +37 -0
- package/dist/chunk-EBXUVSOO.js.map +1 -0
- package/dist/chunk-XAMVXW6B.js +19 -0
- package/dist/chunk-XAMVXW6B.js.map +1 -0
- package/dist/durable-queue.cjs +316 -0
- package/dist/durable-queue.cjs.map +1 -0
- package/dist/durable-queue.d.cts +41 -0
- package/dist/durable-queue.d.ts +41 -0
- package/dist/durable-queue.js +290 -0
- package/dist/durable-queue.js.map +1 -0
- package/dist/helpers.cjs +1167 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +6 -0
- package/dist/helpers.d.ts +6 -0
- package/dist/helpers.js +14 -0
- package/dist/helpers.js.map +1 -0
- package/dist/postgres-ssl.cjs +37 -0
- package/dist/postgres-ssl.cjs.map +1 -0
- package/dist/postgres-ssl.d.cts +9 -0
- package/dist/postgres-ssl.d.ts +9 -0
- package/dist/postgres-ssl.js +12 -0
- package/dist/postgres-ssl.js.map +1 -0
- package/dist/protocol.cjs +38 -0
- package/dist/protocol.cjs.map +1 -0
- package/dist/protocol.d.cts +8 -0
- package/dist/protocol.d.ts +8 -0
- package/dist/protocol.js +13 -0
- package/dist/protocol.js.map +1 -0
- package/dist/public-hosts.cjs +116 -0
- package/dist/public-hosts.cjs.map +1 -0
- package/dist/public-hosts.d.cts +29 -0
- package/dist/public-hosts.d.ts +29 -0
- package/dist/public-hosts.js +82 -0
- package/dist/public-hosts.js.map +1 -0
- package/dist/tinybird-records.cjs +160 -0
- package/dist/tinybird-records.cjs.map +1 -0
- package/dist/tinybird-records.d.cts +62 -0
- package/dist/tinybird-records.d.ts +62 -0
- package/dist/tinybird-records.js +129 -0
- package/dist/tinybird-records.js.map +1 -0
- package/dist/tunnel-accounting.cjs +71 -0
- package/dist/tunnel-accounting.cjs.map +1 -0
- package/dist/tunnel-accounting.d.cts +12 -0
- package/dist/tunnel-accounting.d.ts +12 -0
- package/dist/tunnel-accounting.js +32 -0
- package/dist/tunnel-accounting.js.map +1 -0
- package/dist/tunnel-product-usage.cjs +107 -0
- package/dist/tunnel-product-usage.cjs.map +1 -0
- package/dist/tunnel-product-usage.d.cts +26 -0
- package/dist/tunnel-product-usage.d.ts +26 -0
- package/dist/tunnel-product-usage.js +81 -0
- package/dist/tunnel-product-usage.js.map +1 -0
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +105 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/usage-writer.cjs +43 -0
- package/dist/usage-writer.cjs.map +1 -0
- package/dist/usage-writer.d.cts +14 -0
- package/dist/usage-writer.d.ts +14 -0
- package/dist/usage-writer.js +7 -0
- package/dist/usage-writer.js.map +1 -0
- package/dist/utils.cjs +1171 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +2 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +19 -0
- package/dist/utils.js.map +1 -0
- package/dist/words.cjs +1136 -0
- package/dist/words.cjs.map +1 -0
- package/dist/words.d.cts +4 -0
- package/dist/words.d.ts +4 -0
- package/dist/words.js +9 -0
- package/dist/words.js.map +1 -0
- package/package.json +99 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/words.ts"],"sourcesContent":["export const ADJECTIVES = [\n \"happy\",\n \"sad\",\n \"angry\",\n \"excited\",\n \"nervous\",\n \"calm\",\n \"brave\",\n \"scared\",\n \"silly\",\n \"serious\",\n \"funny\",\n \"boring\",\n \"loud\",\n \"quiet\",\n \"fast\",\n \"slow\",\n \"big\",\n \"small\",\n \"tall\",\n \"short\",\n \"fat\",\n \"thin\",\n \"hot\",\n \"cold\",\n \"warm\",\n \"cool\",\n \"wet\",\n \"dry\",\n \"hard\",\n \"soft\",\n \"rough\",\n \"smooth\",\n \"heavy\",\n \"light\",\n \"dark\",\n \"bright\",\n \"clean\",\n \"dirty\",\n \"good\",\n \"bad\",\n \"new\",\n \"old\",\n \"young\",\n \"rich\",\n \"poor\",\n \"strong\",\n \"weak\",\n \"easy\",\n \"difficult\",\n \"simple\",\n \"complex\",\n \"beautiful\",\n \"ugly\",\n \"smart\",\n \"stupid\",\n \"crazy\",\n \"sane\",\n \"polite\",\n \"rude\",\n \"kind\",\n \"cruel\",\n \"honest\",\n \"dishonest\",\n \"loyal\",\n \"disloyal\",\n \"generous\",\n \"stingy\",\n \"friendly\",\n \"unfriendly\",\n \"lucky\",\n \"unlucky\",\n \"healthy\",\n \"sick\",\n \"safe\",\n \"dangerous\",\n \"free\",\n \"busy\",\n \"lazy\",\n \"active\",\n \"passive\",\n \"creative\",\n \"destructive\",\n \"positive\",\n \"negative\",\n \"optimistic\",\n \"pessimistic\",\n \"realistic\",\n \"idealistic\",\n \"practical\",\n \"impractical\",\n \"logical\",\n \"illogical\",\n \"rational\",\n \"irrational\",\n \"emotional\",\n \"unemotional\",\n \"sensitive\",\n \"insensitive\",\n \"sympathetic\",\n \"unsympathetic\",\n \"compassionate\",\n \"uncompassionate\",\n \"tolerant\",\n \"intolerant\",\n \"patient\",\n \"impatient\",\n \"humble\",\n \"arrogant\",\n \"modest\",\n \"immodest\",\n \"confident\",\n \"insecure\",\n \"shy\",\n \"outgoing\",\n \"introverted\",\n \"extroverted\",\n \"ambitious\",\n \"unambitious\",\n \"adventurous\",\n \"unadventurous\",\n \"cautious\",\n \"reckless\",\n \"careful\",\n \"careless\",\n \"responsible\",\n \"irresponsible\",\n \"reliable\",\n \"unreliable\",\n \"trustworthy\",\n \"untrustworthy\",\n \"honest\",\n \"dishonest\",\n \"loyal\",\n \"disloyal\",\n \"generous\",\n \"stingy\",\n \"friendly\",\n \"unfriendly\",\n \"lucky\",\n \"unlucky\",\n \"healthy\",\n \"sick\",\n \"safe\",\n \"dangerous\",\n \"free\",\n \"busy\",\n \"lazy\",\n \"active\",\n \"passive\",\n \"creative\",\n \"destructive\",\n \"positive\",\n \"negative\",\n \"optimistic\",\n \"pessimistic\",\n \"realistic\",\n \"idealistic\",\n \"practical\",\n \"impractical\",\n \"logical\",\n \"illogical\",\n \"rational\",\n \"irrational\",\n \"emotional\",\n \"unemotional\",\n \"sensitive\",\n \"insensitive\",\n \"sympathetic\",\n \"unsympathetic\",\n \"compassionate\",\n \"uncompassionate\",\n \"tolerant\",\n \"intolerant\",\n \"patient\",\n \"impatient\",\n \"humble\",\n \"arrogant\",\n \"modest\",\n \"immodest\",\n \"confident\",\n \"insecure\",\n \"shy\",\n \"outgoing\",\n \"introverted\",\n \"extroverted\",\n \"ambitious\",\n \"unambitious\",\n \"adventurous\",\n \"unadventurous\",\n \"cautious\",\n \"reckless\",\n \"careful\",\n \"careless\",\n \"responsible\",\n \"irresponsible\",\n \"reliable\",\n \"unreliable\",\n \"trustworthy\",\n \"untrustworthy\",\n];\n\nexport const NOUNS = [\n \"dog\",\n \"cat\",\n \"bird\",\n \"fish\",\n \"horse\",\n \"cow\",\n \"pig\",\n \"sheep\",\n \"goat\",\n \"chicken\",\n \"duck\",\n \"goose\",\n \"turkey\",\n \"rabbit\",\n \"mouse\",\n \"rat\",\n \"hamster\",\n \"guinea pig\",\n \"snake\",\n \"lizard\",\n \"turtle\",\n \"frog\",\n \"toad\",\n \"spider\",\n \"ant\",\n \"bee\",\n \"wasp\",\n \"butterfly\",\n \"moth\",\n \"fly\",\n \"mosquito\",\n \"beetle\",\n \"cockroach\",\n \"worm\",\n \"snail\",\n \"slug\",\n \"crab\",\n \"lobster\",\n \"shrimp\",\n \"octopus\",\n \"squid\",\n \"jellyfish\",\n \"starfish\",\n \"shark\",\n \"whale\",\n \"dolphin\",\n \"seal\",\n \"walrus\",\n \"penguin\",\n \"polar bear\",\n \"bear\",\n \"lion\",\n \"tiger\",\n \"leopard\",\n \"cheetah\",\n \"jaguar\",\n \"panther\",\n \"wolf\",\n \"fox\",\n \"coyote\",\n \"hyena\",\n \"jackal\",\n \"elephant\",\n \"rhinoceros\",\n \"hippopotamus\",\n \"giraffe\",\n \"zebra\",\n \"camel\",\n \"llama\",\n \"alpaca\",\n \"kangaroo\",\n \"koala\",\n \"panda\",\n \"monkey\",\n \"ape\",\n \"gorilla\",\n \"chimpanzee\",\n \"orangutan\",\n \"baboon\",\n \"lemur\",\n \"sloth\",\n \"armadillo\",\n \"anteater\",\n \"bat\",\n \"squirrel\",\n \"chipmunk\",\n \"beaver\",\n \"otter\",\n \"raccoon\",\n \"skunk\",\n \"badger\",\n \"weasel\",\n \"ferret\",\n \"mink\",\n \"stoat\",\n \"mongoose\",\n \"meerkat\",\n \"porcupine\",\n \"hedgehog\",\n \"mole\",\n \"shrew\",\n \"platypus\",\n \"echidna\",\n \"opossum\",\n \"kangaroo\",\n \"wallaby\",\n \"wombat\",\n \"koala\",\n \"tasmanian devil\",\n \"dingo\",\n \"emu\",\n \"cassowary\",\n \"kiwi\",\n \"ostrich\",\n \"rhea\",\n \"flamingo\",\n \"stork\",\n \"heron\",\n \"crane\",\n \"pelican\",\n \"seagull\",\n \"albatross\",\n \"eagle\",\n \"hawk\",\n \"falcon\",\n \"owl\",\n \"vulture\",\n \"parrot\",\n \"cockatoo\",\n \"macaw\",\n \"parakeet\",\n \"budgerigar\",\n \"canary\",\n \"finch\",\n \"sparrow\",\n \"robin\",\n \"bluebird\",\n \"cardinal\",\n \"woodpecker\",\n \"hummingbird\",\n \"pigeon\",\n \"dove\",\n \"crow\",\n \"raven\",\n \"magpie\",\n \"jay\",\n \"swallow\",\n \"swift\",\n \"martin\",\n \"thrush\",\n \"wren\",\n \"starling\",\n \"blackbird\",\n \"lark\",\n \"nightingale\",\n \"cuckoo\",\n \"kingfisher\",\n \"toucan\",\n \"hornbill\",\n \"hoopoe\",\n \"roller\",\n \"bee-eater\",\n \"motmot\",\n \"tody\",\n \"jacamar\",\n \"puffbird\",\n \"barbet\",\n \"honeyguide\",\n \"woodpecker\",\n \"wryneck\",\n \"piculet\",\n \"flicker\",\n \"sapsucker\",\n \"honeycreeper\",\n \"flowerpecker\",\n \"sunbird\",\n \"spiderhunter\",\n \"white-eye\",\n \"waxbill\",\n \"munia\",\n \"mannikin\",\n \"silver\",\n \"gold\",\n \"copper\",\n \"iron\",\n \"steel\",\n \"aluminum\",\n \"lead\",\n \"tin\",\n \"zinc\",\n \"nickel\",\n \"platinum\",\n \"titanium\",\n \"mercury\",\n \"uranium\",\n \"plutonium\",\n \"diamond\",\n \"ruby\",\n \"emerald\",\n \"sapphire\",\n \"topaz\",\n \"opal\",\n \"pearl\",\n \"jade\",\n \"amethyst\",\n \"garnet\",\n \"turquoise\",\n \"aquamarine\",\n \"peridot\",\n \"citrine\",\n \"zircon\",\n \"spinel\",\n \"tourmaline\",\n \"quartz\",\n \"agate\",\n \"onyx\",\n \"jasper\",\n \"bloodstone\",\n \"moonstone\",\n \"sunstone\",\n \"labradorite\",\n \"amazonite\",\n \"rhodonite\",\n \"rhodochrosite\",\n \"malachite\",\n \"azurite\",\n \"lapis lazuli\",\n \"sodalite\",\n \"calcite\",\n \"fluorite\",\n \"gypsum\",\n \"talc\",\n \"mica\",\n \"feldspar\",\n \"granite\",\n \"marble\",\n \"limestone\",\n \"sandstone\",\n \"shale\",\n \"slate\",\n \"schist\",\n \"gneiss\",\n \"basalt\",\n \"obsidian\",\n \"pumice\",\n \"scoria\",\n \"tuff\",\n \"breccia\",\n \"conglomerate\",\n \"coal\",\n \"peat\",\n \"oil\",\n \"gas\",\n \"water\",\n \"ice\",\n \"steam\",\n \"cloud\",\n \"rain\",\n \"snow\",\n \"hail\",\n \"sleet\",\n \"fog\",\n \"mist\",\n \"dew\",\n \"frost\",\n \"wind\",\n \"storm\",\n \"thunder\",\n \"lightning\",\n \"tornado\",\n \"hurricane\",\n \"typhoon\",\n \"cyclone\",\n \"monsoon\",\n \"drought\",\n \"flood\",\n \"earthquake\",\n \"volcano\",\n \"tsunami\",\n \"avalanche\",\n \"landslide\",\n \"mudslide\",\n \"fire\",\n \"smoke\",\n \"ash\",\n \"dust\",\n \"sand\",\n \"soil\",\n \"dirt\",\n \"mud\",\n \"clay\",\n \"silt\",\n \"loam\",\n \"gravel\",\n \"pebble\",\n \"rock\",\n \"stone\",\n \"boulder\",\n \"mountain\",\n \"hill\",\n \"valley\",\n \"canyon\",\n \"plain\",\n \"plateau\",\n \"desert\",\n \"forest\",\n \"jungle\",\n \"swamp\",\n \"marsh\",\n \"bog\",\n \"fen\",\n \"lake\",\n \"pond\",\n \"river\",\n \"stream\",\n \"creek\",\n \"brook\",\n \"ocean\",\n \"sea\",\n \"bay\",\n \"gulf\",\n \"cove\",\n \"inlet\",\n \"strait\",\n \"channel\",\n \"canal\",\n \"island\",\n \"peninsula\",\n \"cape\",\n \"isthmus\",\n \"delta\",\n \"estuary\",\n \"lagoon\",\n \"reef\",\n \"atoll\",\n \"archipelago\",\n \"continent\",\n \"country\",\n \"state\",\n \"province\",\n \"county\",\n \"city\",\n \"town\",\n \"village\",\n \"hamlet\",\n \"suburb\",\n \"neighborhood\",\n \"street\",\n \"road\",\n \"avenue\",\n \"boulevard\",\n \"lane\",\n \"drive\",\n \"court\",\n \"place\",\n \"square\",\n \"plaza\",\n \"park\",\n \"garden\",\n \"yard\",\n \"lawn\",\n \"field\",\n \"meadow\",\n \"pasture\",\n \"orchard\",\n \"vineyard\",\n \"farm\",\n \"ranch\",\n \"plantation\",\n \"factory\",\n \"mill\",\n \"plant\",\n \"workshop\",\n \"warehouse\",\n \"store\",\n \"shop\",\n \"market\",\n \"mall\",\n \"supermarket\",\n \"grocery\",\n \"bakery\",\n \"butcher\",\n \"pharmacy\",\n \"drugstore\",\n \"hospital\",\n \"clinic\",\n \"doctor\",\n \"dentist\",\n \"nurse\",\n \"school\",\n \"college\",\n \"university\",\n \"library\",\n \"museum\",\n \"theater\",\n \"cinema\",\n \"stadium\",\n \"arena\",\n \"gym\",\n \"pool\",\n \"beach\",\n \"hotel\",\n \"motel\",\n \"inn\",\n \"hostel\",\n \"restaurant\",\n \"cafe\",\n \"bar\",\n \"pub\",\n \"club\",\n \"disco\",\n \"casino\",\n \"bank\",\n \"post office\",\n \"police station\",\n \"fire station\",\n \"jail\",\n \"prison\",\n \"courthouse\",\n \"church\",\n \"cathedral\",\n \"temple\",\n \"mosque\",\n \"synagogue\",\n \"shrine\",\n \"monument\",\n \"statue\",\n \"fountain\",\n \"bridge\",\n \"tunnel\",\n \"dam\",\n \"reservoir\",\n \"power plant\",\n \"airport\",\n \"station\",\n \"port\",\n \"harbor\",\n \"dock\",\n \"pier\",\n \"wharf\",\n \"lighthouse\",\n \"beacon\",\n \"tower\",\n \"skyscraper\",\n \"building\",\n \"house\",\n \"apartment\",\n \"condo\",\n \"flat\",\n \"room\",\n \"kitchen\",\n \"bedroom\",\n \"bathroom\",\n \"living room\",\n \"dining room\",\n \"hall\",\n \"corridor\",\n \"stairs\",\n \"elevator\",\n \"escalator\",\n \"door\",\n \"window\",\n \"wall\",\n \"floor\",\n \"ceiling\",\n \"roof\",\n \"chimney\",\n \"fireplace\",\n \"stove\",\n \"oven\",\n \"fridge\",\n \"freezer\",\n \"sink\",\n \"toilet\",\n \"shower\",\n \"bath\",\n \"bed\",\n \"sofa\",\n \"chair\",\n \"table\",\n \"desk\",\n \"lamp\",\n \"light\",\n \"fan\",\n \"heater\",\n \"ac\",\n \"tv\",\n \"radio\",\n \"computer\",\n \"phone\",\n \"clock\",\n \"watch\",\n \"camera\",\n \"book\",\n \"pen\",\n \"pencil\",\n \"paper\",\n \"bag\",\n \"box\",\n \"bottle\",\n \"cup\",\n \"plate\",\n \"bowl\",\n \"spoon\",\n \"fork\",\n \"knife\",\n \"clothes\",\n \"shirt\",\n \"pants\",\n \"dress\",\n \"skirt\",\n \"coat\",\n \"jacket\",\n \"hat\",\n \"shoes\",\n \"socks\",\n \"underwear\",\n \"jewelry\",\n \"ring\",\n \"necklace\",\n \"bracelet\",\n \"earrings\",\n \"glasses\",\n \"sunglasses\",\n \"wallet\",\n \"purse\",\n \"money\",\n \"card\",\n \"key\",\n \"lock\",\n \"car\",\n \"truck\",\n \"bus\",\n \"van\",\n \"motorcycle\",\n \"bicycle\",\n \"scooter\",\n \"skateboard\",\n \"skates\",\n \"boat\",\n \"ship\",\n \"plane\",\n \"helicopter\",\n \"rocket\",\n \"train\",\n \"subway\",\n \"tram\",\n \"taxi\",\n \"ambulance\",\n \"police car\",\n \"fire truck\",\n \"tractor\",\n \"bulldozer\",\n \"crane\",\n \"forklift\",\n \"robot\",\n \"machine\",\n \"engine\",\n \"motor\",\n \"battery\",\n \"fuel\",\n \"energy\",\n \"power\",\n \"force\",\n \"motion\",\n \"speed\",\n \"time\",\n \"space\",\n \"matter\",\n \"atom\",\n \"molecule\",\n \"cell\",\n \"gene\",\n \"dna\",\n \"life\",\n \"death\",\n \"birth\",\n \"growth\",\n \"health\",\n \"disease\",\n \"pain\",\n \"pleasure\",\n \"love\",\n \"hate\",\n \"fear\",\n \"anger\",\n \"joy\",\n \"sadness\",\n \"surprise\",\n \"disgust\",\n \"hope\",\n \"despair\",\n \"faith\",\n \"doubt\",\n \"belief\",\n \"knowledge\",\n \"wisdom\",\n \"truth\",\n \"lie\",\n \"fact\",\n \"fiction\",\n \"story\",\n \"poem\",\n \"song\",\n \"music\",\n \"art\",\n \"science\",\n \"math\",\n \"history\",\n \"geography\",\n \"language\",\n \"word\",\n \"letter\",\n \"number\",\n \"symbol\",\n \"sign\",\n \"signal\",\n \"code\",\n \"data\",\n \"info\",\n \"news\",\n \"message\",\n \"letter\",\n \"email\",\n \"text\",\n \"call\",\n \"chat\",\n \"talk\",\n \"speech\",\n \"voice\",\n \"sound\",\n \"noise\",\n \"silence\",\n \"light\",\n \"darkness\",\n \"color\",\n \"shape\",\n \"size\",\n \"weight\",\n \"height\",\n \"width\",\n \"depth\",\n \"length\",\n \"distance\",\n \"area\",\n \"volume\",\n \"mass\",\n \"density\",\n \"temperature\",\n \"pressure\",\n \"force\",\n \"energy\",\n \"power\",\n \"work\",\n \"heat\",\n \"cold\",\n \"hot\",\n \"warm\",\n \"cool\",\n \"wet\",\n \"dry\",\n \"hard\",\n \"soft\",\n \"rough\",\n \"smooth\",\n \"heavy\",\n \"light\",\n \"fast\",\n \"slow\",\n \"strong\",\n \"weak\",\n \"good\",\n \"bad\",\n \"right\",\n \"wrong\",\n \"true\",\n \"false\",\n \"yes\",\n \"no\",\n \"maybe\",\n \"perhaps\",\n \"possibly\",\n \"probably\",\n \"certainly\",\n \"definitely\",\n \"absolutely\",\n \"exactly\",\n \"precisely\",\n \"clearly\",\n \"obviously\",\n \"naturally\",\n \"normally\",\n \"usually\",\n \"often\",\n \"sometimes\",\n \"rarely\",\n \"never\",\n \"always\",\n \"forever\",\n \"eternity\",\n \"infinity\",\n \"universe\",\n \"world\",\n \"earth\",\n \"sun\",\n \"moon\",\n \"star\",\n \"planet\",\n \"galaxy\",\n \"cosmos\",\n \"nature\",\n \"environment\",\n \"ecology\",\n \"biology\",\n \"chemistry\",\n \"physics\",\n \"astronomy\",\n \"geology\",\n \"meteorology\",\n \"psychology\",\n \"sociology\",\n \"philosophy\",\n \"religion\",\n \"politics\",\n \"economics\",\n \"business\",\n \"finance\",\n \"marketing\",\n \"management\",\n \"law\",\n \"justice\",\n \"crime\",\n \"punishment\",\n \"war\",\n \"peace\",\n \"freedom\",\n \"liberty\",\n \"rights\",\n \"duty\",\n \"responsibility\",\n \"authority\",\n \"power\",\n \"control\",\n \"influence\",\n \"leadership\",\n \"government\",\n \"democracy\",\n \"republic\",\n \"monarchy\",\n \"dictatorship\",\n \"communism\",\n \"socialism\",\n \"capitalism\",\n \"fascism\",\n \"anarchy\",\n \"revolution\",\n \"rebellion\",\n \"protest\",\n \"strike\",\n \"riot\",\n \"chaos\",\n \"order\",\n \"system\",\n \"structure\",\n \"organization\",\n \"institution\",\n \"community\",\n \"society\",\n \"culture\",\n \"civilization\",\n \"humanity\",\n \"mankind\",\n \"people\",\n \"person\",\n \"individual\",\n \"group\",\n \"team\",\n \"family\",\n \"friend\",\n \"enemy\",\n \"stranger\",\n \"neighbor\",\n \"citizen\",\n \"alien\",\n \"immigrant\",\n \"refugee\",\n \"tourist\",\n \"visitor\",\n \"guest\",\n \"host\",\n \"customer\",\n \"client\",\n \"patient\",\n \"student\",\n \"teacher\",\n \"worker\",\n \"boss\",\n \"leader\",\n \"follower\",\n \"hero\",\n \"villain\",\n \"victim\",\n \"criminal\",\n \"prisoner\",\n \"slave\",\n \"master\",\n \"servant\",\n \"king\",\n \"queen\",\n \"prince\",\n \"princess\",\n \"duke\",\n \"duchess\",\n \"lord\",\n \"lady\",\n \"knight\",\n \"dame\",\n \"baron\",\n \"baroness\",\n \"count\",\n \"countess\",\n \"emperor\",\n \"empress\",\n \"president\",\n \"minister\",\n \"governor\",\n \"mayor\",\n \"senator\",\n \"representative\",\n \"judge\",\n \"lawyer\",\n \"doctor\",\n \"nurse\",\n \"engineer\",\n \"scientist\",\n \"artist\",\n \"writer\",\n \"musician\",\n \"actor\",\n \"actress\",\n \"director\",\n \"producer\",\n \"designer\",\n \"architect\",\n \"builder\",\n \"farmer\",\n \"driver\",\n \"pilot\",\n \"sailor\",\n \"soldier\",\n \"police\",\n \"firefighter\",\n \"priest\",\n \"monk\",\n \"nun\",\n \"pope\",\n \"bishop\",\n \"rabbi\",\n \"imam\",\n \"guru\",\n \"prophet\",\n \"saint\",\n \"angel\",\n \"devil\",\n \"demon\",\n \"ghost\",\n \"spirit\",\n \"soul\",\n \"mind\",\n \"body\",\n \"heart\",\n \"brain\",\n \"blood\",\n \"bone\",\n \"skin\",\n \"hair\",\n \"eye\",\n \"ear\",\n \"nose\",\n \"mouth\",\n \"tooth\",\n \"tongue\",\n \"hand\",\n \"foot\",\n \"arm\",\n \"leg\",\n \"finger\",\n \"toe\",\n \"head\",\n \"face\",\n \"neck\",\n \"shoulder\",\n \"chest\",\n \"back\",\n \"stomach\",\n \"waist\",\n \"hip\",\n \"knee\",\n \"ankle\",\n \"elbow\",\n \"wrist\",\n];\n"],"mappings":";AAAO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,QAAQ;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ADJECTIVES,
|
|
3
|
+
NOUNS
|
|
4
|
+
} from "./chunk-7Z55KL36.js";
|
|
5
|
+
|
|
6
|
+
// src/helpers.ts
|
|
7
|
+
function generateId(prefix = "") {
|
|
8
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
9
|
+
return prefix ? `${prefix}_${random}` : random;
|
|
10
|
+
}
|
|
11
|
+
function generateSubdomain() {
|
|
12
|
+
const adj = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];
|
|
13
|
+
const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)];
|
|
14
|
+
return `${adj}-${noun}`.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
15
|
+
}
|
|
16
|
+
function extractSubdomain(host, baseDomain) {
|
|
17
|
+
if (!host) return null;
|
|
18
|
+
const cleanHost = host.split(":")[0].replace(/\.$/, "").toLowerCase();
|
|
19
|
+
const base = baseDomain.toLowerCase();
|
|
20
|
+
if (cleanHost === base) return null;
|
|
21
|
+
if (!cleanHost.endsWith(`.${base}`)) return null;
|
|
22
|
+
const sub = cleanHost.slice(0, cleanHost.length - base.length - 1);
|
|
23
|
+
return sub || null;
|
|
24
|
+
}
|
|
25
|
+
function getBandwidthKey(organizationId, date = /* @__PURE__ */ new Date()) {
|
|
26
|
+
const year = date.getUTCFullYear();
|
|
27
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
28
|
+
return `bw:${organizationId}:${year}-${month}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
generateId,
|
|
33
|
+
generateSubdomain,
|
|
34
|
+
extractSubdomain,
|
|
35
|
+
getBandwidthKey
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=chunk-EBXUVSOO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers.ts"],"sourcesContent":["import { ADJECTIVES, NOUNS } from \"./words\";\n\nexport function generateId(prefix: string = \"\"): string {\n const random = Math.random().toString(36).substring(2, 15);\n return prefix ? `${prefix}_${random}` : random;\n}\n\nexport function generateSubdomain(): string {\n const adj = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];\n const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)];\n return `${adj}-${noun}`.toLowerCase().replace(/[^a-z0-9-]/g, \"\");\n}\n\nexport function extractSubdomain(\n host: string,\n baseDomain: string,\n): string | null {\n if (!host) return null;\n\n const cleanHost = host.split(\":\")[0].replace(/\\.$/, \"\").toLowerCase();\n const base = baseDomain.toLowerCase();\n\n if (cleanHost === base) return null;\n if (!cleanHost.endsWith(`.${base}`)) return null;\n\n const sub = cleanHost.slice(0, cleanHost.length - base.length - 1);\n return sub || null;\n}\n\nexport function getBandwidthKey(organizationId: string, date = new Date()): string {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n return `bw:${organizationId}:${year}-${month}`;\n}\n"],"mappings":";;;;;;AAEO,SAAS,WAAW,SAAiB,IAAY;AACtD,QAAM,SAAS,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AACzD,SAAO,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK;AAC1C;AAEO,SAAS,oBAA4B;AAC1C,QAAM,MAAM,WAAW,KAAK,MAAM,KAAK,OAAO,IAAI,WAAW,MAAM,CAAC;AACpE,QAAM,OAAO,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC3D,SAAO,GAAG,GAAG,IAAI,IAAI,GAAG,YAAY,EAAE,QAAQ,eAAe,EAAE;AACjE;AAEO,SAAS,iBACd,MACA,YACe;AACf,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,YAAY,KAAK,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,OAAO,EAAE,EAAE,YAAY;AACpE,QAAM,OAAO,WAAW,YAAY;AAEpC,MAAI,cAAc,KAAM,QAAO;AAC/B,MAAI,CAAC,UAAU,SAAS,IAAI,IAAI,EAAE,EAAG,QAAO;AAE5C,QAAM,MAAM,UAAU,MAAM,GAAG,UAAU,SAAS,KAAK,SAAS,CAAC;AACjE,SAAO,OAAO;AAChB;AAEO,SAAS,gBAAgB,gBAAwB,OAAO,oBAAI,KAAK,GAAW;AACjF,QAAM,OAAO,KAAK,eAAe;AACjC,QAAM,QAAQ,OAAO,KAAK,YAAY,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AAC5D,SAAO,MAAM,cAAc,IAAI,IAAI,IAAI,KAAK;AAC9C;","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/usage-writer.ts
|
|
2
|
+
async function recordUsageCounters(database, event, allowedMetrics) {
|
|
3
|
+
if (!event.organizationId || event.organizationId.length > 128 || !/^[a-z][a-z0-9-]{0,63}$/.test(event.source) || !event.id || event.id.length > 256 || !Number.isFinite(Date.parse(event.timestamp))) throw new Error("Invalid usage event");
|
|
4
|
+
const deltas = {};
|
|
5
|
+
for (const [key, value] of Object.entries(event.deltas).sort(([a], [b]) => a.localeCompare(b))) {
|
|
6
|
+
if (!allowedMetrics.has(key) || typeof value === "number" && !Number.isSafeInteger(value) || !/^\d+$/.test(String(value))) throw new Error("Invalid usage delta");
|
|
7
|
+
const count = BigInt(value);
|
|
8
|
+
if (count > 9223372036854775807n) throw new Error("Usage delta overflow");
|
|
9
|
+
if (count > 0n) deltas[key] = String(count);
|
|
10
|
+
}
|
|
11
|
+
if (!Object.keys(deltas).length) return false;
|
|
12
|
+
const result = await database.query("SELECT record_product_usage($1,$2,$3,$4::timestamptz,$5::jsonb) AS recorded", [event.organizationId, event.source, event.id, event.timestamp, JSON.stringify(deltas)]);
|
|
13
|
+
return result.rows[0]?.recorded === true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
recordUsageCounters
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=chunk-XAMVXW6B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/usage-writer.ts"],"sourcesContent":["export interface UsageDatabase { query(text: string, values?: any[]): Promise<any> }\nexport interface CounterEvent<Metric extends string = string> {\n organizationId: string; source: string; id: string; timestamp: string;\n deltas: Partial<Record<Metric, string | number>>;\n}\n/** Transport and validation only; callers supply their product's metric catalog. */\nexport async function recordUsageCounters<Metric extends string>(database: UsageDatabase, event: CounterEvent<Metric>, allowedMetrics: ReadonlySet<string>): Promise<boolean> {\n if (!event.organizationId || event.organizationId.length > 128 || !/^[a-z][a-z0-9-]{0,63}$/.test(event.source) || !event.id || event.id.length > 256 || !Number.isFinite(Date.parse(event.timestamp))) throw new Error(\"Invalid usage event\");\n const deltas: Record<string, string> = {};\n for (const [key, value] of Object.entries(event.deltas).sort(([a], [b]) => a.localeCompare(b))) {\n if (!allowedMetrics.has(key) || (typeof value === \"number\" && !Number.isSafeInteger(value)) || !/^\\d+$/.test(String(value))) throw new Error(\"Invalid usage delta\");\n const count = BigInt(value as string | number);\n if (count > 9223372036854775807n) throw new Error(\"Usage delta overflow\");\n if (count > 0n) deltas[key] = String(count);\n }\n if (!Object.keys(deltas).length) return false;\n const result = await database.query(\"SELECT record_product_usage($1,$2,$3,$4::timestamptz,$5::jsonb) AS recorded\", [event.organizationId, event.source, event.id, event.timestamp, JSON.stringify(deltas)]);\n return result.rows[0]?.recorded === true;\n}\n"],"mappings":";AAMA,eAAsB,oBAA2C,UAAyB,OAA6B,gBAAuD;AAC5K,MAAI,CAAC,MAAM,kBAAkB,MAAM,eAAe,SAAS,OAAO,CAAC,yBAAyB,KAAK,MAAM,MAAM,KAAK,CAAC,MAAM,MAAM,MAAM,GAAG,SAAS,OAAO,CAAC,OAAO,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,EAAG,OAAM,IAAI,MAAM,qBAAqB;AAC5O,QAAM,SAAiC,CAAC;AACxC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,GAAG;AAC9F,QAAI,CAAC,eAAe,IAAI,GAAG,KAAM,OAAO,UAAU,YAAY,CAAC,OAAO,cAAc,KAAK,KAAM,CAAC,QAAQ,KAAK,OAAO,KAAK,CAAC,EAAG,OAAM,IAAI,MAAM,qBAAqB;AAClK,UAAM,QAAQ,OAAO,KAAwB;AAC7C,QAAI,QAAQ,qBAAsB,OAAM,IAAI,MAAM,sBAAsB;AACxE,QAAI,QAAQ,GAAI,QAAO,GAAG,IAAI,OAAO,KAAK;AAAA,EAC5C;AACA,MAAI,CAAC,OAAO,KAAK,MAAM,EAAE,OAAQ,QAAO;AACxC,QAAM,SAAS,MAAM,SAAS,MAAM,+EAA+E,CAAC,MAAM,gBAAgB,MAAM,QAAQ,MAAM,IAAI,MAAM,WAAW,KAAK,UAAU,MAAM,CAAC,CAAC;AAC1M,SAAO,OAAO,KAAK,CAAC,GAAG,aAAa;AACtC;","names":[]}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/durable-queue.ts
|
|
21
|
+
var durable_queue_exports = {};
|
|
22
|
+
__export(durable_queue_exports, {
|
|
23
|
+
DurableQueue: () => DurableQueue,
|
|
24
|
+
default: () => durable_queue_default,
|
|
25
|
+
queuePayloads: () => queuePayloads
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(durable_queue_exports);
|
|
28
|
+
var import_node_crypto = require("crypto");
|
|
29
|
+
var import_node_os = require("os");
|
|
30
|
+
var import_ioredis = require("ioredis");
|
|
31
|
+
var ENQUEUE = `
|
|
32
|
+
local maxAge = tonumber(ARGV[2])
|
|
33
|
+
if maxAge > 0 then
|
|
34
|
+
local now = redis.call('TIME')
|
|
35
|
+
redis.call('XTRIM', KEYS[1], 'MINID', tostring((tonumber(now[1]) - maxAge) * 1000) .. '-0')
|
|
36
|
+
end
|
|
37
|
+
local additions = #ARGV - 2
|
|
38
|
+
if redis.call('XLEN', KEYS[1]) + additions > tonumber(ARGV[1]) then
|
|
39
|
+
return 0
|
|
40
|
+
end
|
|
41
|
+
for index = 3, #ARGV do
|
|
42
|
+
redis.call('XADD', KEYS[1], '*', 'payload', ARGV[index])
|
|
43
|
+
end
|
|
44
|
+
if maxAge > 0 then redis.call('EXPIRE', KEYS[1], maxAge) end
|
|
45
|
+
return additions
|
|
46
|
+
`;
|
|
47
|
+
var DEAD_LETTER = `
|
|
48
|
+
redis.call('XADD', KEYS[2], 'MAXLEN', tonumber(ARGV[6]), '*',
|
|
49
|
+
'source_id', ARGV[2], 'error', ARGV[3], 'payload', ARGV[4])
|
|
50
|
+
local maxAge = tonumber(ARGV[5])
|
|
51
|
+
if maxAge > 0 then
|
|
52
|
+
local now = redis.call('TIME')
|
|
53
|
+
local cutoff = tostring((tonumber(now[1]) - maxAge) * 1000) .. '-0'
|
|
54
|
+
redis.call('XTRIM', KEYS[2], 'MINID', cutoff)
|
|
55
|
+
local sourceTime = tonumber(string.match(ARGV[2], '^(%d+)')) / 1000
|
|
56
|
+
local remaining = math.max(1, math.floor(sourceTime + maxAge - tonumber(now[1])))
|
|
57
|
+
local ttl = redis.call('TTL', KEYS[2])
|
|
58
|
+
if ttl < 0 or ttl > remaining then redis.call('EXPIRE', KEYS[2], remaining) end
|
|
59
|
+
end
|
|
60
|
+
redis.call('XACK', KEYS[1], ARGV[1], ARGV[2])
|
|
61
|
+
redis.call('XDEL', KEYS[1], ARGV[2])
|
|
62
|
+
return 1
|
|
63
|
+
`;
|
|
64
|
+
var PRUNE = `
|
|
65
|
+
local maxAge = tonumber(ARGV[1])
|
|
66
|
+
local now = redis.call('TIME')
|
|
67
|
+
local cutoff = tostring((tonumber(now[1]) - maxAge) * 1000) .. '-0'
|
|
68
|
+
for index = 1, #KEYS do
|
|
69
|
+
redis.call('XTRIM', KEYS[index], 'MINID', cutoff)
|
|
70
|
+
if redis.call('TTL', KEYS[index]) == -1 then redis.call('EXPIRE', KEYS[index], maxAge) end
|
|
71
|
+
end
|
|
72
|
+
return 1
|
|
73
|
+
`;
|
|
74
|
+
var sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
75
|
+
function fieldValue(fields, name) {
|
|
76
|
+
for (let index = 0; index < fields.length; index += 2) {
|
|
77
|
+
if (fields[index] === name) return fields[index + 1] ?? null;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
var DurableQueue = class {
|
|
82
|
+
constructor(options) {
|
|
83
|
+
this.options = options;
|
|
84
|
+
const shared = {
|
|
85
|
+
lazyConnect: true,
|
|
86
|
+
connectTimeout: 3e3,
|
|
87
|
+
commandTimeout: 5e3,
|
|
88
|
+
maxRetriesPerRequest: 1
|
|
89
|
+
};
|
|
90
|
+
this.producer = new import_ioredis.Redis(options.redisUrl, shared);
|
|
91
|
+
this.worker = new import_ioredis.Redis(options.redisUrl, {
|
|
92
|
+
...shared,
|
|
93
|
+
commandTimeout: void 0,
|
|
94
|
+
maxRetriesPerRequest: null
|
|
95
|
+
});
|
|
96
|
+
this.producer.on(
|
|
97
|
+
"error",
|
|
98
|
+
(error) => console.error(`${options.signalName} queue producer error`, error)
|
|
99
|
+
);
|
|
100
|
+
this.worker.on("error", (error) => {
|
|
101
|
+
if (!this.stopping)
|
|
102
|
+
console.error(`${options.signalName} queue worker error`, error);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
options;
|
|
106
|
+
producer;
|
|
107
|
+
worker;
|
|
108
|
+
consumer = `${(0, import_node_os.hostname)()}:${process.pid}:${(0, import_node_crypto.randomUUID)()}`;
|
|
109
|
+
stopping = false;
|
|
110
|
+
workerPromise = null;
|
|
111
|
+
async enqueue(records) {
|
|
112
|
+
if (records.length === 0) return;
|
|
113
|
+
if (this.producer.status === "wait" || this.producer.status === "end") {
|
|
114
|
+
await this.producer.connect();
|
|
115
|
+
}
|
|
116
|
+
const payloads = queuePayloads(records, this.options.maxMessageBytes);
|
|
117
|
+
const result = await this.producer.eval(
|
|
118
|
+
ENQUEUE,
|
|
119
|
+
1,
|
|
120
|
+
this.options.streamKey,
|
|
121
|
+
this.options.maxEntries,
|
|
122
|
+
this.options.maxAgeSeconds || 0,
|
|
123
|
+
...payloads
|
|
124
|
+
);
|
|
125
|
+
if (result === 0) {
|
|
126
|
+
throw new Error(`${this.options.signalName} ingestion queue is full`);
|
|
127
|
+
}
|
|
128
|
+
if (Number(result) !== payloads.length) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Could not durably enqueue ${this.options.signalName} data`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
start() {
|
|
135
|
+
if (this.workerPromise) return;
|
|
136
|
+
this.workerPromise = this.run().catch((error) => {
|
|
137
|
+
if (!this.stopping)
|
|
138
|
+
console.error(
|
|
139
|
+
`${this.options.signalName} queue stopped unexpectedly`,
|
|
140
|
+
error
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
async run() {
|
|
145
|
+
while (!this.stopping) {
|
|
146
|
+
try {
|
|
147
|
+
if (this.worker.status === "wait" || this.worker.status === "end") {
|
|
148
|
+
await this.worker.connect();
|
|
149
|
+
}
|
|
150
|
+
await this.createConsumerGroup();
|
|
151
|
+
await this.pruneExpired();
|
|
152
|
+
await this.recoverStale();
|
|
153
|
+
let lastRecoveryAt = Date.now();
|
|
154
|
+
while (!this.stopping) {
|
|
155
|
+
if (Date.now() - lastRecoveryAt >= 3e4) {
|
|
156
|
+
await this.pruneExpired();
|
|
157
|
+
await this.recoverStale();
|
|
158
|
+
lastRecoveryAt = Date.now();
|
|
159
|
+
}
|
|
160
|
+
const result = await this.worker.xreadgroup(
|
|
161
|
+
"GROUP",
|
|
162
|
+
this.options.group,
|
|
163
|
+
this.consumer,
|
|
164
|
+
"COUNT",
|
|
165
|
+
this.options.batchSize,
|
|
166
|
+
"BLOCK",
|
|
167
|
+
2e3,
|
|
168
|
+
"STREAMS",
|
|
169
|
+
this.options.streamKey,
|
|
170
|
+
">"
|
|
171
|
+
);
|
|
172
|
+
const messages = result?.[0]?.[1] ?? [];
|
|
173
|
+
for (const message of messages) await this.deliver(message);
|
|
174
|
+
}
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (this.stopping) break;
|
|
177
|
+
console.error(
|
|
178
|
+
`${this.options.signalName} queue worker will retry`,
|
|
179
|
+
error
|
|
180
|
+
);
|
|
181
|
+
this.worker.disconnect(false);
|
|
182
|
+
await sleep(2e3);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async createConsumerGroup() {
|
|
187
|
+
try {
|
|
188
|
+
await this.worker.xgroup(
|
|
189
|
+
"CREATE",
|
|
190
|
+
this.options.streamKey,
|
|
191
|
+
this.options.group,
|
|
192
|
+
"0",
|
|
193
|
+
"MKSTREAM"
|
|
194
|
+
);
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (!(error instanceof Error) || !error.message.includes("BUSYGROUP"))
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async pruneExpired() {
|
|
201
|
+
if (!this.options.maxAgeSeconds) return;
|
|
202
|
+
await this.worker.eval(PRUNE, 2, this.options.streamKey, this.options.deadLetterKey, this.options.maxAgeSeconds);
|
|
203
|
+
}
|
|
204
|
+
async recoverStale() {
|
|
205
|
+
let cursor = "0-0";
|
|
206
|
+
do {
|
|
207
|
+
const result = await this.worker.xautoclaim(
|
|
208
|
+
this.options.streamKey,
|
|
209
|
+
this.options.group,
|
|
210
|
+
this.consumer,
|
|
211
|
+
this.options.claimIdleMs || 6e4,
|
|
212
|
+
cursor,
|
|
213
|
+
"COUNT",
|
|
214
|
+
this.options.batchSize
|
|
215
|
+
);
|
|
216
|
+
cursor = result[0];
|
|
217
|
+
for (const message of result[1] ?? []) await this.deliver(message);
|
|
218
|
+
} while (!this.stopping && cursor !== "0-0");
|
|
219
|
+
}
|
|
220
|
+
async deliver([id, fields]) {
|
|
221
|
+
const payload = fieldValue(fields, "payload");
|
|
222
|
+
if (!payload) {
|
|
223
|
+
await this.acknowledge(id);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
let records;
|
|
227
|
+
try {
|
|
228
|
+
records = JSON.parse(payload);
|
|
229
|
+
if (!Array.isArray(records)) throw new Error("payload is not an array");
|
|
230
|
+
} catch (error) {
|
|
231
|
+
await this.deadLetter(id, payload, error);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
for (let attempt = 1; attempt <= this.options.maxDeliveryAttempts; attempt++) {
|
|
235
|
+
try {
|
|
236
|
+
await this.options.deliver(records);
|
|
237
|
+
await this.acknowledge(id);
|
|
238
|
+
return;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (attempt === this.options.maxDeliveryAttempts) {
|
|
241
|
+
await this.deadLetter(id, payload, error);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
await sleep(Math.min(1e3 * 2 ** (attempt - 1), 15e3));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
async acknowledge(id) {
|
|
249
|
+
const result = await this.worker.multi().xack(this.options.streamKey, this.options.group, id).xdel(this.options.streamKey, id).exec();
|
|
250
|
+
if (!result || result.some(([error]) => error)) {
|
|
251
|
+
throw new Error(`${this.options.signalName} queue acknowledgement failed`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async deadLetter(id, payload, error) {
|
|
255
|
+
const message = error instanceof Error ? error.message : "Unknown delivery failure";
|
|
256
|
+
console.error(
|
|
257
|
+
`${this.options.signalName} queue delivery failed permanently for ${id}: ${message}`
|
|
258
|
+
);
|
|
259
|
+
const result = await this.worker.eval(
|
|
260
|
+
DEAD_LETTER,
|
|
261
|
+
2,
|
|
262
|
+
this.options.streamKey,
|
|
263
|
+
this.options.deadLetterKey,
|
|
264
|
+
this.options.group,
|
|
265
|
+
id,
|
|
266
|
+
message.slice(0, 1e3),
|
|
267
|
+
payload,
|
|
268
|
+
this.options.maxAgeSeconds || 0,
|
|
269
|
+
this.options.maxDeadLetterEntries || 1e3
|
|
270
|
+
);
|
|
271
|
+
if (Number(result) !== 1) {
|
|
272
|
+
throw new Error(`${this.options.signalName} dead-letter storage failed`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async close() {
|
|
276
|
+
this.stopping = true;
|
|
277
|
+
this.worker.disconnect(false);
|
|
278
|
+
if (this.producer.status !== "end")
|
|
279
|
+
await this.producer.quit().catch(() => void 0);
|
|
280
|
+
await this.workerPromise;
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
function chunk(items, size) {
|
|
284
|
+
const chunks = [];
|
|
285
|
+
for (let index = 0; index < items.length; index += size) {
|
|
286
|
+
chunks.push(items.slice(index, index + size));
|
|
287
|
+
}
|
|
288
|
+
return chunks;
|
|
289
|
+
}
|
|
290
|
+
function queuePayloads(records, maxBytes) {
|
|
291
|
+
if (!maxBytes) return chunk(records, 250).map((rows) => JSON.stringify(rows));
|
|
292
|
+
const payloads = [];
|
|
293
|
+
let lines = [];
|
|
294
|
+
let bytes = 2;
|
|
295
|
+
for (const record of records) {
|
|
296
|
+
const line = JSON.stringify(record);
|
|
297
|
+
const size = Buffer.byteLength(line);
|
|
298
|
+
if (size + 2 > maxBytes) throw new Error("Analytics record exceeds the durable queue message size limit");
|
|
299
|
+
if (lines.length && (bytes + size + 1 > maxBytes || lines.length >= 250)) {
|
|
300
|
+
payloads.push(`[${lines.join(",")}]`);
|
|
301
|
+
lines = [];
|
|
302
|
+
bytes = 2;
|
|
303
|
+
}
|
|
304
|
+
bytes += size + (lines.length ? 1 : 0);
|
|
305
|
+
lines.push(line);
|
|
306
|
+
}
|
|
307
|
+
if (lines.length) payloads.push(`[${lines.join(",")}]`);
|
|
308
|
+
return payloads;
|
|
309
|
+
}
|
|
310
|
+
var durable_queue_default = { DurableQueue };
|
|
311
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
312
|
+
0 && (module.exports = {
|
|
313
|
+
DurableQueue,
|
|
314
|
+
queuePayloads
|
|
315
|
+
});
|
|
316
|
+
//# sourceMappingURL=durable-queue.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/durable-queue.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { hostname } from \"node:os\";\nimport { Redis } from \"ioredis\";\n\nexport interface DurableQueueOptions<T> {\n signalName: string;\n redisUrl: string;\n streamKey: string;\n deadLetterKey: string;\n group: string;\n maxEntries: number;\n batchSize: number;\n maxDeliveryAttempts: number;\n /** Optional storage bound; existing observability queues keep their policy. */\n maxAgeSeconds?: number;\n maxMessageBytes?: number;\n maxDeadLetterEntries?: number;\n claimIdleMs?: number;\n deliver: (records: T[]) => Promise<void>;\n}\n\ntype StreamMessage = [id: string, fields: string[]];\n\nconst ENQUEUE = `\nlocal maxAge = tonumber(ARGV[2])\nif maxAge > 0 then\n local now = redis.call('TIME')\n redis.call('XTRIM', KEYS[1], 'MINID', tostring((tonumber(now[1]) - maxAge) * 1000) .. '-0')\nend\nlocal additions = #ARGV - 2\nif redis.call('XLEN', KEYS[1]) + additions > tonumber(ARGV[1]) then\n return 0\nend\nfor index = 3, #ARGV do\n redis.call('XADD', KEYS[1], '*', 'payload', ARGV[index])\nend\nif maxAge > 0 then redis.call('EXPIRE', KEYS[1], maxAge) end\nreturn additions\n`;\n\nconst DEAD_LETTER = `\nredis.call('XADD', KEYS[2], 'MAXLEN', tonumber(ARGV[6]), '*',\n 'source_id', ARGV[2], 'error', ARGV[3], 'payload', ARGV[4])\nlocal maxAge = tonumber(ARGV[5])\nif maxAge > 0 then\n local now = redis.call('TIME')\n local cutoff = tostring((tonumber(now[1]) - maxAge) * 1000) .. '-0'\n redis.call('XTRIM', KEYS[2], 'MINID', cutoff)\n local sourceTime = tonumber(string.match(ARGV[2], '^(%d+)')) / 1000\n local remaining = math.max(1, math.floor(sourceTime + maxAge - tonumber(now[1])))\n local ttl = redis.call('TTL', KEYS[2])\n if ttl < 0 or ttl > remaining then redis.call('EXPIRE', KEYS[2], remaining) end\nend\nredis.call('XACK', KEYS[1], ARGV[1], ARGV[2])\nredis.call('XDEL', KEYS[1], ARGV[2])\nreturn 1\n`;\n\nconst PRUNE = `\nlocal maxAge = tonumber(ARGV[1])\nlocal now = redis.call('TIME')\nlocal cutoff = tostring((tonumber(now[1]) - maxAge) * 1000) .. '-0'\nfor index = 1, #KEYS do\n redis.call('XTRIM', KEYS[index], 'MINID', cutoff)\n if redis.call('TTL', KEYS[index]) == -1 then redis.call('EXPIRE', KEYS[index], maxAge) end\nend\nreturn 1\n`;\n\nconst sleep = (milliseconds: number) =>\n new Promise((resolve) => setTimeout(resolve, milliseconds));\n\nfunction fieldValue(fields: string[], name: string): string | null {\n for (let index = 0; index < fields.length; index += 2) {\n if (fields[index] === name) return fields[index + 1] ?? null;\n }\n return null;\n}\n\nexport class DurableQueue<T> {\n private readonly producer: Redis;\n private readonly worker: Redis;\n private readonly consumer = `${hostname()}:${process.pid}:${randomUUID()}`;\n private stopping = false;\n private workerPromise: Promise<void> | null = null;\n\n constructor(private readonly options: DurableQueueOptions<T>) {\n const shared = {\n lazyConnect: true,\n connectTimeout: 3_000,\n commandTimeout: 5_000,\n maxRetriesPerRequest: 1,\n } as const;\n this.producer = new Redis(options.redisUrl, shared);\n this.worker = new Redis(options.redisUrl, {\n ...shared,\n commandTimeout: undefined,\n maxRetriesPerRequest: null,\n });\n\n this.producer.on(\"error\", (error: Error) =>\n console.error(`${options.signalName} queue producer error`, error),\n );\n this.worker.on(\"error\", (error: Error) => {\n if (!this.stopping)\n console.error(`${options.signalName} queue worker error`, error);\n });\n }\n\n async enqueue(records: T[]): Promise<void> {\n if (records.length === 0) return;\n if (this.producer.status === \"wait\" || this.producer.status === \"end\") {\n await this.producer.connect();\n }\n\n const payloads = queuePayloads(records, this.options.maxMessageBytes);\n // Admission and enqueue must share one Redis operation across replicas.\n const result = await this.producer.eval(\n ENQUEUE, 1, this.options.streamKey, this.options.maxEntries,\n this.options.maxAgeSeconds || 0, ...payloads,\n );\n if (result === 0) {\n throw new Error(`${this.options.signalName} ingestion queue is full`);\n }\n if (Number(result) !== payloads.length) {\n throw new Error(\n `Could not durably enqueue ${this.options.signalName} data`,\n );\n }\n }\n\n start(): void {\n if (this.workerPromise) return;\n this.workerPromise = this.run().catch((error) => {\n if (!this.stopping)\n console.error(\n `${this.options.signalName} queue stopped unexpectedly`,\n error,\n );\n });\n }\n\n private async run(): Promise<void> {\n while (!this.stopping) {\n try {\n if (this.worker.status === \"wait\" || this.worker.status === \"end\") {\n await this.worker.connect();\n }\n await this.createConsumerGroup();\n await this.pruneExpired();\n await this.recoverStale();\n let lastRecoveryAt = Date.now();\n\n while (!this.stopping) {\n if (Date.now() - lastRecoveryAt >= 30_000) {\n await this.pruneExpired();\n await this.recoverStale();\n lastRecoveryAt = Date.now();\n }\n const result = (await this.worker.xreadgroup(\n \"GROUP\",\n this.options.group,\n this.consumer,\n \"COUNT\",\n this.options.batchSize,\n \"BLOCK\",\n 2_000,\n \"STREAMS\",\n this.options.streamKey,\n \">\",\n )) as [string, StreamMessage[]][] | null;\n\n const messages = result?.[0]?.[1] ?? [];\n for (const message of messages) await this.deliver(message);\n }\n } catch (error) {\n if (this.stopping) break;\n console.error(\n `${this.options.signalName} queue worker will retry`,\n error,\n );\n this.worker.disconnect(false);\n await sleep(2_000);\n }\n }\n }\n\n private async createConsumerGroup(): Promise<void> {\n try {\n await this.worker.xgroup(\n \"CREATE\",\n this.options.streamKey,\n this.options.group,\n \"0\",\n \"MKSTREAM\",\n );\n } catch (error) {\n if (!(error instanceof Error) || !error.message.includes(\"BUSYGROUP\"))\n throw error;\n }\n }\n\n private async pruneExpired(): Promise<void> {\n if (!this.options.maxAgeSeconds) return;\n await this.worker.eval(PRUNE, 2, this.options.streamKey, this.options.deadLetterKey, this.options.maxAgeSeconds);\n }\n\n private async recoverStale(): Promise<void> {\n let cursor = \"0-0\";\n do {\n const result = (await this.worker.xautoclaim(\n this.options.streamKey,\n this.options.group,\n this.consumer,\n this.options.claimIdleMs || 60_000,\n cursor,\n \"COUNT\",\n this.options.batchSize,\n )) as [string, StreamMessage[]];\n cursor = result[0];\n for (const message of result[1] ?? []) await this.deliver(message);\n } while (!this.stopping && cursor !== \"0-0\");\n }\n\n private async deliver([id, fields]: StreamMessage): Promise<void> {\n const payload = fieldValue(fields, \"payload\");\n if (!payload) {\n await this.acknowledge(id);\n return;\n }\n\n let records: T[];\n try {\n records = JSON.parse(payload) as T[];\n if (!Array.isArray(records)) throw new Error(\"payload is not an array\");\n } catch (error) {\n await this.deadLetter(id, payload, error);\n return;\n }\n\n for (\n let attempt = 1;\n attempt <= this.options.maxDeliveryAttempts;\n attempt++\n ) {\n try {\n await this.options.deliver(records);\n await this.acknowledge(id);\n return;\n } catch (error) {\n if (attempt === this.options.maxDeliveryAttempts) {\n await this.deadLetter(id, payload, error);\n return;\n }\n await sleep(Math.min(1_000 * 2 ** (attempt - 1), 15_000));\n }\n }\n }\n\n private async acknowledge(id: string): Promise<void> {\n const result = await this.worker\n .multi()\n .xack(this.options.streamKey, this.options.group, id)\n .xdel(this.options.streamKey, id)\n .exec();\n if (!result || result.some(([error]) => error)) {\n throw new Error(`${this.options.signalName} queue acknowledgement failed`);\n }\n }\n\n private async deadLetter(\n id: string,\n payload: string,\n error: unknown,\n ): Promise<void> {\n const message =\n error instanceof Error ? error.message : \"Unknown delivery failure\";\n console.error(\n `${this.options.signalName} queue delivery failed permanently for ${id}: ${message}`,\n );\n // Only acknowledge the source after dead-letter storage succeeded. Redis\n // MULTI continues after a failed XADD (for example OOM), which could discard\n // a record without storing its failed-delivery copy.\n const result = await this.worker.eval(\n DEAD_LETTER, 2, this.options.streamKey, this.options.deadLetterKey,\n this.options.group, id, message.slice(0, 1_000), payload,\n this.options.maxAgeSeconds || 0, this.options.maxDeadLetterEntries || 1_000,\n );\n if (Number(result) !== 1) {\n throw new Error(`${this.options.signalName} dead-letter storage failed`);\n }\n }\n\n async close(): Promise<void> {\n this.stopping = true;\n this.worker.disconnect(false);\n if (this.producer.status !== \"end\")\n await this.producer.quit().catch(() => undefined);\n await this.workerPromise;\n }\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let index = 0; index < items.length; index += size) {\n chunks.push(items.slice(index, index + size));\n }\n return chunks;\n}\n\nexport function queuePayloads<T>(records: T[], maxBytes?: number): string[] {\n if (!maxBytes) return chunk(records, 250).map((rows) => JSON.stringify(rows));\n const payloads: string[] = [];\n let lines: string[] = [];\n let bytes = 2;\n for (const record of records) {\n const line = JSON.stringify(record);\n const size = Buffer.byteLength(line);\n if (size + 2 > maxBytes) throw new Error(\"Analytics record exceeds the durable queue message size limit\");\n if (lines.length && (bytes + size + 1 > maxBytes || lines.length >= 250)) {\n payloads.push(`[${lines.join(\",\")}]`);\n lines = [];\n bytes = 2;\n }\n bytes += size + (lines.length ? 1 : 0);\n lines.push(line);\n }\n if (lines.length) payloads.push(`[${lines.join(\",\")}]`);\n return payloads;\n}\n\nexport default { DurableQueue };\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
interface DurableQueueOptions<T> {
|
|
2
|
+
signalName: string;
|
|
3
|
+
redisUrl: string;
|
|
4
|
+
streamKey: string;
|
|
5
|
+
deadLetterKey: string;
|
|
6
|
+
group: string;
|
|
7
|
+
maxEntries: number;
|
|
8
|
+
batchSize: number;
|
|
9
|
+
maxDeliveryAttempts: number;
|
|
10
|
+
/** Optional storage bound; existing observability queues keep their policy. */
|
|
11
|
+
maxAgeSeconds?: number;
|
|
12
|
+
maxMessageBytes?: number;
|
|
13
|
+
maxDeadLetterEntries?: number;
|
|
14
|
+
claimIdleMs?: number;
|
|
15
|
+
deliver: (records: T[]) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
declare class DurableQueue<T> {
|
|
18
|
+
private readonly options;
|
|
19
|
+
private readonly producer;
|
|
20
|
+
private readonly worker;
|
|
21
|
+
private readonly consumer;
|
|
22
|
+
private stopping;
|
|
23
|
+
private workerPromise;
|
|
24
|
+
constructor(options: DurableQueueOptions<T>);
|
|
25
|
+
enqueue(records: T[]): Promise<void>;
|
|
26
|
+
start(): void;
|
|
27
|
+
private run;
|
|
28
|
+
private createConsumerGroup;
|
|
29
|
+
private pruneExpired;
|
|
30
|
+
private recoverStale;
|
|
31
|
+
private deliver;
|
|
32
|
+
private acknowledge;
|
|
33
|
+
private deadLetter;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
declare function queuePayloads<T>(records: T[], maxBytes?: number): string[];
|
|
37
|
+
declare const _default: {
|
|
38
|
+
DurableQueue: typeof DurableQueue;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { DurableQueue, type DurableQueueOptions, _default as default, queuePayloads };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
interface DurableQueueOptions<T> {
|
|
2
|
+
signalName: string;
|
|
3
|
+
redisUrl: string;
|
|
4
|
+
streamKey: string;
|
|
5
|
+
deadLetterKey: string;
|
|
6
|
+
group: string;
|
|
7
|
+
maxEntries: number;
|
|
8
|
+
batchSize: number;
|
|
9
|
+
maxDeliveryAttempts: number;
|
|
10
|
+
/** Optional storage bound; existing observability queues keep their policy. */
|
|
11
|
+
maxAgeSeconds?: number;
|
|
12
|
+
maxMessageBytes?: number;
|
|
13
|
+
maxDeadLetterEntries?: number;
|
|
14
|
+
claimIdleMs?: number;
|
|
15
|
+
deliver: (records: T[]) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
declare class DurableQueue<T> {
|
|
18
|
+
private readonly options;
|
|
19
|
+
private readonly producer;
|
|
20
|
+
private readonly worker;
|
|
21
|
+
private readonly consumer;
|
|
22
|
+
private stopping;
|
|
23
|
+
private workerPromise;
|
|
24
|
+
constructor(options: DurableQueueOptions<T>);
|
|
25
|
+
enqueue(records: T[]): Promise<void>;
|
|
26
|
+
start(): void;
|
|
27
|
+
private run;
|
|
28
|
+
private createConsumerGroup;
|
|
29
|
+
private pruneExpired;
|
|
30
|
+
private recoverStale;
|
|
31
|
+
private deliver;
|
|
32
|
+
private acknowledge;
|
|
33
|
+
private deadLetter;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
declare function queuePayloads<T>(records: T[], maxBytes?: number): string[];
|
|
37
|
+
declare const _default: {
|
|
38
|
+
DurableQueue: typeof DurableQueue;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { DurableQueue, type DurableQueueOptions, _default as default, queuePayloads };
|