{"_id":"@aetherflux/smarty-pants","name":"@aetherflux/smarty-pants","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@aetherflux/smarty-pants","version":"1.0.0","description":"A pluggable smart request engine with retry, fallback, and adaptive strategy execution.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"lint":"npx @biomejs/biome check './src'","build":"npx tsc","prepublishOnly":"npm run build","test":"npm run build && node dist/test.js"},"keywords":["http","fetch","request","response","retry","network","fallback","tor","typescript","sdk"],"author":{"name":"Amartya Chowdhury","url":"aether-flux"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/aether-flux/smarty-pants.git"},"bugs":{"url":"https://github.com/aether-flux/smarty-pants/issues"},"homepage":"https://github.com/aether-flux/smarty-pants","devDependencies":{"@biomejs/biome":"2.4.12","@types/node":"^25.6.0","ts-node":"^10.9.2","typescript":"^6.0.3"},"dependencies":{"undici":"^7.25.0"},"gitHead":"6736fea3cb3c55cb7e936491b4630dd2d4494935","_id":"@aetherflux/smarty-pants@1.0.0","_nodeVersion":"22.13.0","_npmVersion":"11.11.1","dist":{"integrity":"sha512-88vKkfuE6pagLC7jcBmgDz+p6c6pDXcfOAWcFUgru7kc/CW9OpsJMc4Ysynmsrh+UPRJraZlfNJ0PT+SeaaPVg==","shasum":"899d814a91582318415949dd7a72d1023b3d4a52","tarball":"https://registry.npmjs.org/@aetherflux/smarty-pants/-/smarty-pants-1.0.0.tgz","fileCount":23,"unpackedSize":18008,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDvh5ORJdiT17hRv6RAIkoeNg/I6i59fdg00ztMy2v0JwIhALn+90Ri1Pq7el0WSBOf6H0ZMGPwdoUi7egyWK2Yr8KJ"}]},"_npmUser":{"name":"aetherflux","email":"work.amar05@yahoo.com"},"directories":{},"maintainers":[{"name":"aetherflux","email":"work.amar05@yahoo.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/smarty-pants_1.0.0_1776843266926_0.27189321246660536"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-22T07:34:26.821Z","1.0.0":"2026-04-22T07:34:27.051Z","modified":"2026-04-22T07:34:27.282Z"},"maintainers":[{"name":"aetherflux","email":"work.amar05@yahoo.com"}],"description":"A pluggable smart request engine with retry, fallback, and adaptive strategy execution.","homepage":"https://github.com/aether-flux/smarty-pants","keywords":["http","fetch","request","response","retry","network","fallback","tor","typescript","sdk"],"repository":{"type":"git","url":"git+https://github.com/aether-flux/smarty-pants.git"},"author":{"name":"Amartya Chowdhury","url":"aether-flux"},"bugs":{"url":"https://github.com/aether-flux/smarty-pants/issues"},"license":"MIT","readme":"# Smarty Pants  ᕙ(•̀ ᗜ •́)ᕗ\nA pluggable smart request engine with retry, fallback, and strategy-based execution.\n\n---\n\n## Why?\nMaking HTTP requests sounds pretty simple, but turns out it isn't:\n- Requests fail\n- APIs timeout\n- Different networks behave differently\n- Retrying manually is troublesome\n\n**Smarty Pants** solves this by introducing **strategy-based execution**:\n> Try -> Retry -> Fallback to different strategy -> Retry -> Observe\n\n---\n\n## Installation\n```bash\nnpm install smarty-pants\n```\n\n## Example Usage\n```js\nimport { Smarty } from 'smarty-pants';\n\nconst smarty = new Smarty();\nconst res = await smarty.fetch(\"http://example.com\", {\n    strategy: 'direct',     // default: auto\n    timeout: 5000,          // default: 10000\n    method: 'POST',         // default: null (GET)\n});\n\nconsole.log(res);\n```\n\n---\n\n## How It Works\nSmarty pants uses **strategies** to execute requests.\nEach strategy:\n- tries the request\n- retries if needed\n- fails gracefully and falls back to next strategy\n\n## Built-in Strategies\n### `direct`\nNormal HTTP request using fetch.\n\n### `tor`\nRoutes request through a SOCKS proxy (eg, Tor)\n> ⚠️ Requires a running proxy (like Tor on 1127.0.0.1:9050)\n\n## `auto` Mode Default\nAutomatically tries strategies in order.\n\nIt has light adaptive behavior:\n> The last successful strategy is tried first during the next request.\n\n---\n\n## Response Structure\n```ts\n{\n  data: any | null,\n  status: number | null,\n\n  error?: {\n    message: string,\n    strategy?: string\n  },\n\n  meta: {\n    strategy: string | null,\n    attempts: number,\n    duration: number,\n    fallbackUsed: boolean,\n    timeline: [\n      {\n        type: \"start\" | \"success\" | \"failed\" | \"timeout\",\n        strategy: string,\n        time: number,\n        message?: string\n      }\n    ]\n  }\n}\n```\n\n### Example output\n```json\n{\n  \"data\": \"<html>...</html>\",\n  \"status\": 200,\n  \"meta\": {\n    \"strategy\": \"tor\",\n    \"attempts\": 2,\n    \"duration\": 5609,\n    \"fallbackUsed\": true,\n    \"timeline\": [\n      { \"type\": \"start\", \"strategy\": \"direct\", \"time\": 0 },\n      { \"type\": \"failed\", \"strategy\": \"direct\", \"time\": 5002 },\n      { \"type\": \"start\", \"strategy\": \"tor\", \"time\": 5002 },\n      { \"type\": \"success\", \"strategy\": \"tor\", \"time\": 5609 }\n    ]\n  }\n}\n```\n\n---\n\n## 🔌 Custom Strategies\nYou can plug in your own strategies as well!\nFor example:\n```ts\nimport { Smarty, Strategy } from \"smarty-pants\";\n\nconst mystrat: Strategy = {\n  name: \"mystrat\",\n\n  async execute(url, options) {\n    const res = await fetch(url, options);\n    return res;\n  }\n};\n\nconst smarty = new Smarty().addStrategy(mystrat);\nconst res = await smarty.fetch(\"http://example.com\", { strategy: [\"mystrat\", \"direct\"] });      // 'strategy' value must be same as 'name' field in your strategy\n```\n\n### Strategy Interface\n```ts\ninterface Strategy {\n    name: string;\n    execute(\n        url: string,\n        options: SmartReqOptions,\n        signal?: AbortSignal\n    ): Promise<SmartResponse>;\n```\n\n### Options\n```ts\n{\n  method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"OPTIONS\";\n  headers?: Record<string, string>;\n  body?: any;\n\n  strategy?: StrategyInput<T>;\n  retries?: number;             // per strategy\n  timeout?: number;             // per attempt\n  maxDuration?: number;         // total request time\n}\n```\n\n---\n\n## Timeline\nEvery response includes a **timeline**:\n- when each strategy started\n- when it failed\n- when fallback happened\n- when it succeeded\n\nThis makes debugging network issues way easier.\n\n## Design Philosophy\n- Minimal core\n- Extensible via custom strategies\n- No unnecessary abstractions\n\n---\n\n## License\nMIT\n","readmeFilename":"README.md","_rev":"1-20b4947aa34eaa2015e9aef8464a3616"}