# 📘 Learn Here — StormFetch Functions for Freshers

> ┌──────────────────────────────────────────────────────────────┐  
> **🎓 LEARN HERE: START SMALL, THEN BUILD ENTERPRISE APPS**  
> Every lesson tells you: what the function does, syntax, parameters, return value, example, expected output, errors, and real use.  
> └──────────────────────────────────────────────────────────────┘

**Version:** `1.16.3`  
**Teacher/Developer:** **Pradeep Kumar Sheoran (Stack Developer)** · **BSG Technologies**  
**Questions or contribution:** **+91-8595147850 (Also WhatsApp)**  
**Official learning community:** [🌐 Visit BSG Technologies — meet, learn, contribute, discuss, or accept a coffee invitation](https://bsgtechnologies.com)

## 🧭 Navigation

[5-minute start](#-lesson-1-create-your-client) · [GET data](#-lesson-2-read-data-with-get) · [Send data](#-lesson-3-send-data-with-post-put-patch-and-delete) · [All HTTP functions](#-all-http-function-mini-lessons) · [React hooks](#-react-hook-mini-lessons) · [Cache/debug](#-cache-and-debug-mini-lessons) · [Files](#-file-and-form-mini-lessons) · [Streaming](#-streaming-mini-lessons) · [Offline/mobile/plugins](#-offline-mobile-and-plugin-mini-lessons) · [DOM](#-dom-and-scraping-mini-lessons) · [Testing/adapters](#-testing-error-and-adapter-mini-lessons) · [Security/metrics/runtime](#-security-observability-and-runtime-mini-lessons) · [Errors](#-common-error-handling) · [Questionnaire](#-questionnaire-old-vs-new)

## 📦 Install

```bash
npm install stormfetch
```

## 🚀 Lesson 1: Create your client

### `createStormFetchClient(options?)`

**Easy meaning:** This creates your reusable API connection. Create it once, then use it everywhere.

**Syntax**

```ts
const api = createStormFetchClient(options);
```

| Parameter | Type | Required? | Easy explanation |
| --- | --- | --- | --- |
| `options` | `FastApiClientOptions` | No | Base URL, timeout, auth, retries, cache, security, adapters, and hooks |

**Returns:** `FastApiClient`.

```ts
import { createStormFetchClient } from 'stormfetch';

const api = createStormFetchClient({
  baseURL: 'https://api.example.com',
  timeout: 10_000,
  retry: 2,
});

console.log(api.defaults.baseURL);
```

**Output**

```text
https://api.example.com
```

**Possible errors:** Invalid timeout, adapter, proxy, response type, rate, or security configuration rejects before sending a request.

**Use cases:** One API client per backend, shared authentication, enterprise security policy, SSR client, test client.

### Client-creation mini lessons

| Function | Syntax and parameters | Returns | Tiny example → output | Errors | Use it when |
| --- | --- | --- | --- | --- | --- |
| `fastApi` | `fastApi.get(url)`; no creation parameter | Ready client | `await fastApi.get('/health')` → response | Normal request errors | Learning or a tiny prototype |
| `new FastApiClient(options)` | Same options as factory | Client instance | `new FastApiClient({ timeout: 5000 })` → client | Invalid options at request time | You specifically need class construction |
| `createFastApiClient(options?)` | Alias of `createStormFetchClient` | Client | `createFastApiClient()` → client | Same as main factory | Old code compatibility |
| `createTypedStormFetchClient<T>(options?)` | Endpoint map generic + normal options | Typed client | `api.get('/users')` → typed data | Type error for unknown endpoint; runtime request errors | SDKs with fixed endpoints |
| `createReactNativeStormFetchClient(options?)` | Native options and normal client options | Native-safe client | `createReactNativeStormFetchClient({ baseURL })` → client | Missing injected native service only when that feature is used | React Native or Expo |
| `createStormFetchServerClient(options?)` | `baseURL`, incoming `headers`, `cookies` | Server client | `createStormFetchServerClient({ cookies: 'sid=1' })` → client | Normal Node/security errors | SSR or backend-to-backend calls |
| `STORMFETCH_PACKAGE_INFO` | Constant; no call | Frozen package identity | `.developer` → `Pradeep Kumar Sheoran (Stack Developer)` | None | Support/version/signature screen |

## 📥 Lesson 2: Read data with `get`

### `client.get<TData>(url, config?)`

**Easy meaning:** Ask the server to give you data.

```ts
const response = await api.get<User[]>('/users', {
  params: { page: 1 },
  cache: true,
});
```

| Parameter | Type | Required? | Meaning |
| --- | --- | --- | --- |
| `url` | `string` | Yes | API path or allowed absolute URL |
| `config` | `FastApiRequestConfig` | No | Query params, headers, cache, retry, timeout, signal, security, response type |

**Returns:** `Promise<FastApiResponse<User[]>>`.

**Example output**

```ts
console.log(response.status); // 200
console.log(response.data);   // [{ id: 1, name: 'Asha' }]
```

**Errors:** Timeout, cancellation, network failure, blocked host, invalid JSON, status rejected by `validateStatus`, response-size limit.

**Use cases:** Product lists, profile details, dashboards, configuration, search results.

## 📤 Lesson 3: Send data with `post`, `put`, `patch`, and `delete`

| Function | Meaning | Syntax | Returns | Example → output | Common errors | Use case |
| --- | --- | --- | --- | --- | --- | --- |
| `post` | Create/trigger | `api.post<TData,TBody>(url, body, config?)` | Response promise | `post('/users',{name:'Asha'})` → `{id:10,name:'Asha'}` | Validation, 4xx/5xx, timeout | Signup, login, create, action |
| `put` | Replace full record | `api.put(url, body, config?)` | Response promise | `put('/users/10', user)` → updated user | Missing record, validation | Full edit form |
| `patch` | Update selected fields | `api.patch(url, partial, config?)` | Response promise | `patch('/users/10',{name:'Riya'})` → changed user | Conflict, validation | Small edit |
| `delete` | Remove record | `api.delete<T>(url, config?)` | Response promise | `delete('/users/10')` → status `204` | Not found, forbidden | Delete/archive |

```ts
try {
  const created = await api.post<{ id: number }, { name: string }>(
    '/users',
    { name: 'Asha' }
  );
  console.log(created.data.id);
} catch (error) {
  if (isStormFetchError(error)) console.log(error.code, error.status);
}
```

## 🌐 All HTTP function mini lessons

| Function | Description | Parameters | Return | Example → expected output | Error handling | Use case |
| --- | --- | --- | --- | --- | --- | --- |
| `request` | Most configurable request | `{ url, method?, data?, ...config }` | Response promise | `request({url:'/x',method:'GET'})` → response | Catch `StormFetchError` | Dynamic method/config |
| `fetch` | Fetch-like API with StormFetch features | `url`, optional config | Response promise | `fetch('/x',{method:'GET'})` → response | Catch normalized error | Native Fetch migration |
| `get` | Read data | `url`, config | Response promise | `get('/users')` → array | Catch status/network error | REST read |
| `post` | Create/trigger | `url`, data, config | Response promise | `post('/users',{name:'A'})` → created record | Catch validation/status error | REST create |
| `put` | Replace | `url`, data, config | Response promise | `put('/users/1',user)` → replacement | Catch conflict/status error | Full update |
| `patch` | Partial update | `url`, data, config | Response promise | `patch('/users/1',{active:true})` → update | Catch validation/status error | Partial update |
| `delete` | Delete | `url`, config | Response promise | `delete('/users/1')` → `204` | Catch forbidden/not found | Remove record |
| `head` | Headers only | `url`, config | Response with undefined data | `head('/file')` → `content-length` header | Catch network/status error | File existence/ETag |
| `options` | Server capabilities | `url`, config | Response promise | `options('/users')` → `allow` header | Catch CORS/status error | Method discovery |
| `query` | QUERY method with body | `url`, data, config | Response promise | `query('/search',{term:'book'})` → matches | Catch unsupported-method/status error | Complex safe query |
| `GET` | Uppercase alias | Same as `get` | Same as `get` | `GET('/users')` → array | Same as `get` | HTTP-style SDK |
| `POST` | Uppercase alias | Same as `post` | Same as `post` | `POST('/users',body)` → record | Same as `post` | HTTP-style SDK |
| `PUT` | Uppercase alias | Same as `put` | Same as `put` | `PUT('/users/1',body)` → record | Same as `put` | HTTP-style SDK |
| `PATCH` | Uppercase alias | Same as `patch` | Same as `patch` | `PATCH('/users/1',body)` → record | Same as `patch` | HTTP-style SDK |
| `DELETE` | Uppercase alias | Same as `delete` | Same as `delete` | `DELETE('/users/1')` → `204` | Same as `delete` | HTTP-style SDK |
| `HEAD` | Uppercase alias | Same as `head` | Same as `head` | `HEAD('/file')` → headers | Same as `head` | HTTP-style SDK |
| `OPTIONS` | Uppercase alias | Same as `options` | Same as `options` | `OPTIONS('/x')` → capabilities | Same as `options` | HTTP-style SDK |
| `QUERY` | Uppercase alias | Same as `query` | Same as `query` | `QUERY('/search',body)` → matches | Same as `query` | HTTP-style SDK |

## 🧩 API helper mini lessons

| Function | Description | Main parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- | --- |
| `postJson` | POST with JSON header | `url`, data, config | Response promise | `postJson('/login',{email})` → token | JSON shape/status errors | Strict JSON API |
| `postForm` | URL-encoded POST | `url`, object/URLSearchParams, config | Response promise | `{q:'book'}` → body `q=book` | Form depth/body limit | HTML-style backend |
| `postMultipart` | Multipart POST | `url`, object/FormData, config | Response promise | file form → upload result | File/body/security limit | Avatar/document upload |
| `graphql` | GraphQL POST | query, variables, config | Typed response | `graphql('{ me { id } }')` → `{me:{id:1}}` | GraphQL HTTP/JSON errors | GraphQL backend |
| `batch` | Parallel request list | request array | Ordered responses | two calls → two responses | Rejects if a call rejects | Dashboard startup |
| `poll` | Repeat request | url, interval/options, config | `{stop,subscribe}` | subscribe → new response each interval | Listener/request errors | Job status |
| `resource` | CRUD function builder | base path | Six REST functions | `resource('/users').detail(1)` → user | Normal request errors | Service layer |
| `contract` | Named contract builder | endpoint definition | Named functions | `contract({users:{url:'/users'}}).users()` → response | Definition/request errors | Internal typed SDK |
| `generateStormFetchServicesFromOpenApi` | OpenAPI → TypeScript | document, generation options | Source string | spec → `export const ...` | Invalid document | Generated SDK |

## ⚛️ React hook mini lessons

First create hooks:

```ts
const { useStormQuery, useLazyStormQuery, useStormMutation, useStormInfiniteQuery } =
  createStormFetchHooks(React, api);
```

| Hook/function | Parameters | Return | Example → UI output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `createStormFetchHooks` | React object, client | Four hooks | factory → hook functions | Invalid/incomplete React adapter | React DOM/RN integration |
| `useStormQuery` | url, config, options | data/error/loading/refetch/reset | users endpoint → list or spinner | Error stored in `error` | Auto-load screen |
| `useLazyStormQuery` | url, config, options | query state | call `refetch()` → data appears | Error stored in state | Search button/modal |
| `useStormMutation` | url, method, options | mutate/data/error/loading/reset | `mutate(form)` → saved record | `mutate` rejects and state receives error | Form submit/delete |
| `useStormInfiniteQuery` | url, paging options | pages/fetchNextPage/states | click more → new page appended | Error stored in state | Feed/catalog |

```tsx
function Users() {
  const users = useStormQuery<User[]>('/users');
  if (users.loading) return <p>Loading...</p>;
  if (users.error) return <p>{users.error.message}</p>;
  return <p>{users.data?.length ?? 0} users</p>;
}
```

**Possible output:** `12 users`.

## 💾 Cache and debug mini lessons

| Function | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `clearCache` | optional key | void | `clearCache()` → memory cleared | None normally | Logout/reset |
| `clearCacheAsync` | optional key | Promise<void> | `await clearCacheAsync()` → all storage cleared | Storage adapter error | AsyncStorage cleanup |
| `invalidateTags` | string tags | Promise<void> | `invalidateTags(['users'])` → matching entries removed | Storage error | After mutation |
| `prefetch` | url, config | Response promise | prefetch `/users` → cached response | Request error | Before navigation |
| `dehydrateCache` | none | Snapshot promise | call → serializable entries | Storage read error | SSR/persistence |
| `hydrateCache` | snapshot | Promise<void> | restore → keys available | Invalid/storage snapshot error | Browser hydration |
| `cacheKeys` | none | string[] | call → `['GET:/users']` | None normally | Debug panel |
| `cacheManager` | property | Cache facade | `.keys()` → key array | Depends on selected operation | Framework integration |
| `history` | none | Redacted entries | call → recent requests | None | Support/debugging |
| `clearHistory` | none | void | call → `history()` becomes `[]` | None | Privacy/reset |
| `replay` | request ID | Response promise | replay ID → fresh response | Unknown ID/request error | Reproduce bug |
| `toCurl` | ID or resolved config | Redacted string | call → `curl 'https://...'` | Unknown ID | Share reproduction |
| `toHAR` | none | HAR object | call → `{log:{version:'1.2'}}` | None | Network analysis |
| `subscribe` | event listener | unsubscribe function | listener → `request:success` | Listener code can throw | Metrics/devtools |
| `policy` | matcher, config | remove function | policy `/admin/**` → timeout applied | Invalid request config | Route defaults |
| `createStormFetchDevTools` | client, event limit | Controller | `snapshot()` → events/history | Client operation errors | Custom inspector |
| `mountStormFetchDevTools` | client, HTMLElement, options | Controller + unmount | mount → visible request panel | Browser DOM required | Local web debugging |

## 📁 File and form mini lessons

| Function | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `createFormData` | plain object | FormData | `{name:'A'}` → multipart field | Circular/unsafe/depth error during request serialization | Browser/Node upload |
| `client.createFormData` | plain object | FormData | same as above | Same as above | Convenient client method |
| `createReactNativeFile` | uri, name, MIME type | RN descriptor | image URI → `{uri,name,type}` | App picker/URI errors occur outside helper | Mobile upload |
| `isReactNativeFile` | unknown value | boolean | valid descriptor → `true` | None | Guard unknown picker result |
| `postMultipart` | url, object/FormData, config | Response promise | avatar → `{uploaded:true}` | Body/file/network limits | Upload |
| `postForm` | url, object/params, config | Response promise | fields → server result | Depth/body limit | Form endpoint |
| `download` | url, optional file name/config | Blob response | PDF → downloaded/saved | Browser saver/network error | Browser file download |
| `saveBlob` | Blob, file name | void | blob → browser download prompt | Browser DOM/URL API required | Save generated data |

```ts
const form = createFormData({ displayName: 'Asha', avatar: file });
const result = await api.postMultipart('/profile/avatar', form);
console.log(result.status); // 200
```

## 🌊 Streaming mini lessons

| Function | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `streamText` | url, config | Async text chunks | `for await` → `hello`, ` world` | Abort/network/size error | AI text/live logs |
| `streamJson` | url, config | Parsed value promise | await → `{done:true}` | Invalid JSON/size error | Large JSON stream |
| `streamNdjson` | url, config | Async object stream | each line → `{id:1}` | Invalid NDJSON line | Events/export rows |
| `sse` | url, SSE options | closeable controller | `onMessage` → event data | Connection/parser error callback | Notifications/live status |

```ts
for await (const row of api.streamNdjson<{ id: number }>('/events')) {
  console.log(row.id);
}
// Output: 1, then 2, then 3 as data arrives
```

## 📴 Offline, mobile, and plugin mini lessons

| Function | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `flushOfflineQueue` | none | Promise<void> | call online → queued writes sent | Retry/conflict/dead-letter error | Reconnect handling |
| `offlineQueueSnapshot` | none | Snapshot promise | call → pending/dead arrays | Storage error | Offline UI badge |
| `retryOfflineRequest` | request ID | Promise<void> | retry ID → request runs | Unknown ID/request error | Manual retry |
| `discardOfflineRequest` | request ID | Promise<void> | discard → removed | Unknown ID | User cancels change |
| `retryOfflineBatch` | optional IDs | Promise<void> | no IDs → retry all dead letters | Individual request errors | Recovery screen |
| `reconcileOfflineRequest` | ID, replacement config | Promise<void> | new body → conflict retried | Unknown ID/invalid config | 409 conflict resolution |
| `createMemoryOfflineQueueStorage` | optional initial state | Storage | factory → in-memory adapter | None normally | Tests/nonpersistent apps |
| `createJsonOfflineQueueStorage` | key-value storage, options | Storage | factory → JSON adapter | JSON/encryption/storage error | AsyncStorage/MMKV wrapper |
| `nativeUpload` | transfer options | Result promise | await → native status/URI | Missing adapter/native failure | Background upload |
| `nativeDownload` | transfer options | Result promise | await → local URI | Missing adapter/native failure | Background download |
| `startNativeUpload` | transfer options | Task | task → pause/resume/cancel/result | Missing adapter/native failure | Controlled upload |
| `startNativeDownload` | transfer options | Task | task → progress and result | Missing adapter/native failure | Controlled download |
| `usePlugin` | plugin object | uninstall promise | install → async remover | API-version/setup error | Extend client |
| `removePlugin` | plugin name | Promise<void> | remove → plugin cleanup | Cleanup error | Dynamic feature off |
| `installedPlugins` | none | plugin list | call → names/versions | None | Diagnostics |
| `dispose` | none | Promise<void> | call → resources released | Plugin cleanup error | Tests/app shutdown |
| `authPlugin` | token provider | Plugin | install → Bearer header | Token provider error | Central auth |
| `languagePlugin` | language provider | Plugin | install → language header | Provider error | Localization |
| `loggerPlugin` | optional logger | Plugin | install → lifecycle logs | Logger callback error | Development logs |
| `hmacSigningPlugin` | secret/signing options | Plugin | install → signature headers | Crypto/signing error | Partner API signing |
| `secureLoggerPlugin` | safe logger options | Plugin | install → redacted metadata logs | Logger callback error | Production logging |
| `securityRateLimitPlugin` | threshold/callback options | Plugin | repeated 401/403/429 → callback | Callback error | Security alerting |

## 🧾 DOM and scraping mini lessons

| Function | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `getHtml` | url, config | String response | call → `'<html>...'` | Network/status/size | Read web page |
| `getXml` | url, config | String response | call → `'<feed>...'` | Network/status/size | RSS/XML API |
| `getDom` | url, config + mimeType | Document response | call → queryable document | DOM parser unavailable/parse error | Page extraction |
| `parseDom` | markup, MIME type | Document | HTML → document | Parser missing/invalid markup | Existing HTML |
| `scrape` | url, schema, config | Typed response | title schema → `{title:'...'}` | Selector/request error | Structured scraper |
| `scrapeDocument` | document, schema | Typed object | schema → extracted data | Required selector missing | Local extraction |
| `selectText` | document, CSS selector | string/undefined | `h1` → `'Welcome'` | Invalid selector | One text value |
| `selectAttr` | document, selector, attribute | string/undefined | `a`,`href` → `'/docs'` | Invalid selector | One attribute |
| `selectAll` | document, selector, mapper | array | `li` → item array | Invalid selector/mapper error | Repeated elements |
| `extractMeta` | document | record | call → `{description:'...'}` | None normally | SEO audit |
| `extractLinks` | document | string[] | call → `['/docs']` | None normally | Link audit |
| `extractImages` | document | string[] | call → `['hero.jpg']` | None normally | Image audit |
| `extractJsonLd` | document | unknown[] | call → parsed schemas | Invalid JSON-LD entries skipped | Structured-data audit |

## 🧪 Testing, error, and adapter mini lessons

| Function/class | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `createMockAdapter` | routes/options | Adapter | GET route → fake response | Missing route error | Unit test |
| `createMockServer` | routes/scenarios | Mock server | set scenario → selected data | Missing route/scenario | Demo/test suite |
| `createStormFetchError` | message/config/request metadata | StormFetchError | factory → normalized error | Invalid input is a developer mistake | Custom transport |
| `createFastApiError` | same as above | Same error | alias → error | Same as above | Legacy code |
| `isStormFetchError` | unknown | boolean type guard | caught error → `true` | None | Safe catch block |
| `createInterceptorManager` | generic type | manager | `use(fn)` → eject function | Interceptor callback error | Custom pipeline |
| `new StormFetchCache` | optional storage | cache engine | `set/get` → cached value | Storage serialization error | Custom cache |
| `FastApiCache` | same constructor | cache engine | alias → cache | Same | Legacy name |
| `new RequestDedupe` | none | dedupe engine | same key → same promise | Underlying promise error | Custom request layer |
| `new RequestQueue` | none | scheduler | queued job → result | Job error | Concurrency control |
| `dispatchAdapter` | resolved config | response promise | auto config → selected transport result | No runtime transport/config error | Adapter framework |
| `fetchAdapter` | resolved config | response promise | fetch config → response | Fetch/network/limit error | Browser/RN/Deno/Bun |
| `xhrAdapter` | resolved config | response promise | XHR config → response | XHR/network/limit error | Browser progress |
| `httpAdapter` | resolved config | response promise | Node config → response | Proxy/TLS/socket/network error | Node HTTP/1.1 |
| `http2Adapter` | resolved config | response promise | HTTP/2 config → response | Session/protocol error | Node HTTP/2 |

Adapters are advanced APIs. Freshers should normally choose `createStormFetchClient()` and let StormFetch select the adapter.

## 🎛️ Controller and returned-helper mini lessons

Some factory functions return an object containing more functions. These functions are public too:

| Returned function | Comes from | Parameters | Return/output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `stop()` | `poll()` | none | Stops timer; `void` | None normally | End polling on unmount |
| `subscribe(listener)` | `poll()` | response listener | Unsubscribe function; listener receives responses | Listener error | Show each poll result |
| `list(config?)` | `resource()` | request config | Array response | Request error | REST list |
| `detail(id, config?)` | `resource()` | record ID, config | Record response | Not found/status error | REST detail |
| `create(data, config?)` | `resource()` | create body, config | Created record response | Validation/status error | REST create |
| `replace(id, data, config?)` | `resource()` | ID, full body, config | Replaced record response | Validation/conflict | REST PUT |
| `update(id, data, config?)` | `resource()` | ID, partial body, config | Updated record response | Validation/conflict | REST PATCH |
| `remove(id, config?)` | `resource()` | ID, config | Delete response | Forbidden/not found | REST delete |
| `prefetch(url, config?)` | `cacheManager` | URL, config | Cached response | Request/storage error | Warm cache |
| `invalidate(tags)` | `cacheManager` | tag list | `Promise<void>` | Storage error | Clear related data |
| `clear(key?)` | `cacheManager` | optional key | `Promise<void>` | Storage error | Clear cache |
| `keys()` | `cacheManager` | none | `string[]` | None normally | Cache inspector |
| `dehydrate()` | `cacheManager` | none | Snapshot | Storage error | SSR export |
| `hydrate(snapshot)` | `cacheManager` | snapshot | `Promise<void>` | Invalid/storage error | SSR restore |
| `subscribe(listener)` | `cacheManager` | event listener | Unsubscribe function | Listener error | Cache UI/devtools |
| `close()` | `sse()` | none | Closes event stream | None normally | Leave live screen |
| `setScenario(name)` | `createMockServer()` | scenario name | `void` | Unknown scenario appears as route failure | Switch test state |
| `addRoute(route, scenario?)` | `createMockServer()` | mock route, optional scenario | `void` | Invalid route | Build test dynamically |
| `requests()` | `createMockServer()` | none | Resolved request array | None | Assert sent calls |
| `clearRequests()` | `createMockServer()` | none | `void` | None | Reset test |
| `snapshot()` | `createStormFetchDevTools()` | none | Sync events/history/cache snapshot | None normally | Render inspector |
| `snapshotAsync()` | DevTools | none | Snapshot including offline queue | Storage error | Full inspector |
| `subscribe(listener)` | DevTools | snapshot listener | Unsubscribe function | Listener error | Reactive panel |
| `clear()` | DevTools | none | Clears events/history | None | Reset panel |
| `dispose()` | DevTools | none | Releases listeners | None normally | Unmount/test cleanup |
| `unmount()` | Mounted DevTools | none | Removes browser panel | Browser DOM required | Close inspector |
| `onEvent(event)` | `createStormFetchMetrics()` | StormFetch event | Updates counters | None normally | Connect client metrics |
| `snapshot()` | Metrics | none | Counter/duration object | None | Monitoring UI |
| `reset()` | Metrics | none | Clears counters | None | Test/window reset |
| `pause()` | Native transfer task | none | Pauses when adapter supports it | Native adapter error | User pauses transfer |
| `resume()` | Native transfer task | none | Resumes task | Native adapter error | Continue transfer |
| `cancel(reason?)` | Native transfer task | optional reason | Cancels task | Native adapter error | User cancels transfer |
| `result` | Native transfer task | Promise property | Final transfer result | Rejects on native failure | Await completion |
| `use(handler, options?)` | Interceptor manager | handler, run conditions | Eject function | Handler error during request | Register logic |
| `eject(handler)` | Interceptor manager | same handler | `void` | None | Remove logic |
| `clear()` | Interceptor manager | none | `void` | None | Reset interceptors |
| `handlers(context?)` | Interceptor manager | optional context | Matching handler array | `runWhen` predicate error | Advanced pipeline introspection |

## 🛡️ Security, observability, and runtime mini lessons

| Function/constant | Parameters | Return | Example → output | Errors | Use case |
| --- | --- | --- | --- | --- | --- |
| `STORMFETCH_ERROR_CODES` | none | frozen map | `.TIMEOUT` → `'ERR_TIMEOUT'` | None | Stable branching |
| `createOpenTelemetryObservability` | tracer bridge options | observability config | pass to client → spans | Tracer callback error | Enterprise tracing |
| `createStormFetchMetrics` | none | onEvent/snapshot/reset | snapshot → counters | None normally | Dashboard metrics |
| `isBrowser` | none | boolean | browser → `true` | None | Runtime branch |
| `isReactNative` | none | boolean | RN → `true` | None | Mobile branch |
| `isNodeLike` | none | boolean | Node → `true` | None | Server branch |
| `isDeno` | none | boolean | Deno → `true` | None | Deno branch |
| `isBun` | none | boolean | Bun → `true` | None | Bun branch |
| `getRuntimeInfo` | none | capability object | Node → `{runtime:'node',hasFetch:true,...}` | None | Support report |
| `buildQueryString` | params, serializer/options | encoded string | `{q:'a b'}` → `'?q=a+b'` | Depth/circular/encoder error | URL building |
| `replacePathParams` | URL pattern, values | string | `'/users/:id',{id:4}` → `'/users/4'` | Missing values stay unresolved | REST route |
| `joinURL` | base URL, path | string | `'https://a.com','/x'` → `'https://a.com/x'` | Malformed external input may fail later | Client URL building |

## ❌ Common error handling

```ts
import {
  isStormFetchError,
  STORMFETCH_ERROR_CODES,
} from 'stormfetch';

try {
  await api.get('/profile');
} catch (error) {
  if (!isStormFetchError(error)) throw error;

  if (error.code === STORMFETCH_ERROR_CODES.TIMEOUT) {
    console.log('Server took too long. Please retry.');
  } else if (error.isAbortError) {
    console.log('Request was cancelled.');
  } else if (error.status === 401) {
    console.log('Please login again.');
  } else {
    console.log(error.message, error.requestId);
  }
}
```

| Error/code | Simple meaning | What the user should do |
| --- | --- | --- |
| `ERR_TIMEOUT` | Server was too slow | Retry or show a friendly timeout message |
| `ERR_CANCELED` | App/user cancelled | Usually no warning needed |
| `ERR_NETWORK` | No usable connection | Check network or backend |
| `ECONNREFUSED` | Server rejected connection | Start/check backend service |
| `ENOTFOUND` | Hostname was not found | Check URL/DNS |
| `ERR_REQUEST_TOO_LARGE` | Upload crossed safe limit | Reduce file or increase trusted limit |
| `ERR_RESPONSE_TOO_LARGE` | Download crossed safe limit | Use a trusted stream/limit decision |
| `ERR_DECOMPRESSION` | Compressed body was unsafe/invalid | Reject response and inspect server |
| `ERR_BAD_RESPONSE` | HTTP/parse/schema failure | Read `status`, `data`, and `requestId` |

## ❓ Questionnaire: old vs new

| Question | Easy answer |
| --- | --- |
| Earlier, did every adapter safely enforce streamed size limits? | Not consistently. Now Fetch, XHR, Node buffered responses, Fetch streams, and Node streams have tested limits. |
| Earlier, could I use HTTP QUERY directly? | No dedicated helper. Now use `query()` or `QUERY()`. |
| Earlier, were nested forms bounded and protected? | Basic form conversion existed. Now depth, circular-reference, key-style, and dangerous-key controls are available. |
| Earlier, could an interceptor run only once or only for matching calls? | Basic interceptors existed. Now use `runWhen`, `once`, and `prepend`. |
| Can I identify native Node network errors? | Yes. Stable codes preserve `ECONNREFUSED`, `ECONNRESET`, and `ENOTFOUND`. |
| Can I build offline-first mutations? | Yes. Queue writes, persist them, retry batches, inspect dead letters, discard, or reconcile conflicts. |
| Can I use the same library in ReactJS and React Native? | Yes. Use the root entry for web/shared code and `stormfetch/react-native` for explicit mobile setup. |
| Can I use it without React? | Yes. React hooks are optional and React is not bundled. |
| Can I inspect requests without leaking tokens? | Yes. History, curl, HAR, secure logger, and errors redact sensitive values by default. |
| Can I generate a typed SDK? | Yes. Use the OpenAPI generator CLI or `generateStormFetchServicesFromOpenApi`. |
| Can I test without a real backend? | Yes. Use `createMockAdapter` or `createMockServer`. |
| Is it automatically the top npm search result? | No package can guarantee ranking. Accurate keywords, useful docs, releases, adoption, quality, downloads, and community activity improve discoverability. |

## ✅ What should a fresher learn first?

1. Create `api` with `createStormFetchClient`.
2. Learn `get` and `post`.
3. Handle errors with `isStormFetchError`.
4. Add auth through the client or `authPlugin`.
5. Learn `useStormQuery` and `useStormMutation` if using React.
6. Add retry/cache only where the API behavior supports it.
7. Add an allowed-host security policy before production.
8. Use mocks, browser tests, and the packed-package test before release.

---

> **✍️ Official code signature**  
> `STORMFETCH_PACKAGE_INFO.signature` = **Built by Pradeep Kumar Sheoran (Stack Developer) at BSG Technologies**  
> [🌐 Visit the official website](https://bsgtechnologies.com) · **+91-8595147850 (Also WhatsApp)**
