Skip to content

Commit ba1a16e

Browse files
authored
Merge pull request #68 from script-development/engineer/doctrine-8-fs-http-docs
docs(fs-http): surface Doctrine #8 timeout contract; collapse README duplication
2 parents 00578ff + 770e045 commit ba1a16e

2 files changed

Lines changed: 62 additions & 32 deletions

File tree

docs/packages/http.md

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ await http.deleteRequest('/users/1');
3434

3535
```typescript
3636
const http = createHttpService('https://api.example.com', {
37+
// Request timeout in milliseconds (default: 30000, pass 0 to disable)
38+
timeout: 30_000,
39+
3740
// Send cookies with cross-origin requests (default: true)
3841
withCredentials: true,
3942

@@ -52,6 +55,50 @@ const http = createHttpService('https://api.example.com', {
5255

5356
When `smartCredentials` is enabled, the service automatically includes credentials for same-origin requests and excludes them for cross-origin requests. This is useful when your application talks to both your own API and third-party services.
5457

58+
## Timeout
59+
60+
The factory ships a compliant timeout surface per the **Doctrine #8 library-author extension** (war-room CLAUDE.md, 2026-04-22).
61+
62+
> Library-author extension (2026-04-22) — Shared HTTP factory packages (e.g., `@script-development/fs-http`) must expose a compliant timeout surface: a default, a required option, or a documented contract plus consumer-level enforcement. Inheriting framework defaults at the library layer silently propagates the violation to every consumer territory.
63+
64+
### Default
65+
66+
Every request method that goes through the axios pipeline — `getRequest`, `postRequest`, `putRequest`, `patchRequest`, `deleteRequest` — inherits a **30000ms (30s) default timeout** when no override is provided. This default is the Armory's compliance posture: consumer territories that adopt fs-http inherit Doctrine #8 enforcement automatically rather than re-implementing it per call.
67+
68+
### Service-wide Override
69+
70+
Pass `timeout` in the options to tighten (or relax) the service-wide default for every request the service issues:
71+
72+
```typescript
73+
// Tighten for a fast-API service
74+
const http = createHttpService('https://api.example.com', {timeout: 5_000});
75+
```
76+
77+
### Service-wide Opt-out
78+
79+
Pass `timeout: 0` to disable the default. The consumer accepts Doctrine #8 enforcement at the call layer — typical use cases are AI streaming endpoints with their own timeout discipline, where a bounded request timeout is wrong by construction:
80+
81+
```typescript
82+
const http = createHttpService('https://ai.example.com', {timeout: 0});
83+
```
84+
85+
### Per-request Override
86+
87+
The existing `AxiosRequestConfig.timeout` parameter on each method overrides the service-wide value for a single call. Use this when most calls fit the service default but a specific endpoint needs different latency tolerance:
88+
89+
```typescript
90+
// Service default (30000ms) for most calls; per-call override for the long one
91+
await http.postRequest('/generate-report', payload, {timeout: 120_000});
92+
```
93+
94+
### `DEFAULT_TIMEOUT_MS`
95+
96+
The default is also exported as a barrel-level constant for consumers that want to reference it explicitly (e.g., to derive a related timeout, or to assert parity in a test):
97+
98+
```typescript
99+
import {DEFAULT_TIMEOUT_MS} from '@script-development/fs-http';
100+
```
101+
55102
## Middleware
56103

57104
The middleware system lets you intercept requests at three points in the lifecycle. Every registration returns an unregister function:
@@ -152,13 +199,20 @@ try {
152199

153200
### `createHttpService(baseURL, options?)`
154201

155-
| Parameter | Type | Description |
156-
| -------------------------- | ------------------------ | ---------------------------------------------------- |
157-
| `baseURL` | `string` | Base URL for all requests |
158-
| `options.headers` | `Record<string, string>` | Default headers |
159-
| `options.withCredentials` | `boolean` | Send cookies cross-origin (default: `true`) |
160-
| `options.withXSRFToken` | `boolean` | Include XSRF token (default: `false`) |
161-
| `options.smartCredentials` | `boolean` | Auto-toggle credentials by origin (default: `false`) |
202+
| Parameter | Type | Description |
203+
| -------------------------- | ------------------------ | ----------------------------------------------------------------------- |
204+
| `baseURL` | `string` | Base URL for all requests |
205+
| `options.timeout` | `number \| undefined` | Request timeout in milliseconds (default: `30000`; pass `0` to disable) |
206+
| `options.headers` | `Record<string, string>` | Default headers |
207+
| `options.withCredentials` | `boolean` | Send cookies cross-origin (default: `true`) |
208+
| `options.withXSRFToken` | `boolean` | Include XSRF token (default: `false`) |
209+
| `options.smartCredentials` | `boolean` | Auto-toggle credentials by origin (default: `false`) |
210+
211+
### Constants
212+
213+
| Constant | Type | Description |
214+
| -------------------- | -------------- | ---------------------------------------------------------------------------------------- |
215+
| `DEFAULT_TIMEOUT_MS` | `const number` | Service-wide default timeout in milliseconds (`30000`); barrel-exported for consumer use |
162216

163217
### Service Methods
164218

packages/http/README.md

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,7 @@ Creates a new HTTP service instance.
4444

4545
### Timeout
4646

47-
The factory applies a **30000ms (30s) default timeout** to every request. This default is the Armory's compliance posture for the war-room **Doctrine #8 library-author extension** (CLAUDE.md, 2026-04-22):
48-
49-
> Library-author extension (2026-04-22) — Shared HTTP factory packages (e.g., `@script-development/fs-http`) must expose a compliant timeout surface: a default, a required option, or a documented contract plus consumer-level enforcement. Inheriting framework defaults at the library layer silently propagates the violation to every consumer territory.
50-
51-
To override the service-wide default, pass `timeout` in the options:
52-
53-
```typescript
54-
// Tighten for a fast-API service
55-
const http = createHttpService('https://api.example.com', {timeout: 5_000});
56-
```
57-
58-
To disable the default and accept Doctrine #8 responsibility at the consumer layer (e.g., AI streaming endpoints with their own timeout discipline), pass `timeout: 0`:
59-
60-
```typescript
61-
const http = createHttpService('https://ai.example.com', {timeout: 0});
62-
```
63-
64-
Per-request overrides remain available via the existing `AxiosRequestConfig.timeout` parameter on each method:
65-
66-
```typescript
67-
// Service default (30000ms) for most calls; per-call override for the long one
68-
await http.postRequest('/generate-report', payload, {timeout: 120_000});
69-
```
70-
71-
The constant is also exported as `DEFAULT_TIMEOUT_MS` for consumers that want to reference it explicitly.
47+
Per **Doctrine #8 library-author extension** (war-room CLAUDE.md, 2026-04-22), the factory applies a **30000ms default timeout** with `timeout: 0` opt-out and per-request override. See [the docs site Timeout section](https://packages.script.nl/packages/http#timeout) for the full surface contract.
7248

7349
### Request Methods
7450

0 commit comments

Comments
 (0)