Skip to content

Commit 8cef63e

Browse files
committed
remove HTTP builders; minor tweaks in other modules
`http.mjs`: * Dropped `HttpBui`. * Dropped `ReqBui`. * Dropped `ResBui`. * Dropped `ReqRou..method` in favor of `ReqRou..req.method`. * Dropped `ReqRou..signal` in favor of `ReqRou..req.signal`. * Renamed `ReqRou..meth` → `ReqRou..method` and `ReqRou..someMeth` → `ReqRou..someMethod` for consistency with the `fetch` / `Request` API. * Renamed `HttpErr` → `ErrHttp`. * Renamed all constants. * Added various constants. * Added `resOk`. * When `Cookie..install` invokes the `document.cookie` setter, it passes a string rather than an object. This avoids exceptions in badly programmed scripts that monkeypatch the `document.cookie` setter with their own buggy implementation. Motivation for dropping request and response builders: the implementation had forward compatibility problems and caused edge case breakages in some browsers, and any alternative design has ergonomic problems. As a result, the abstraction is not worth it. `coll.mjs`: * Methods `.added` in various collection classes now return a boolean indicating whether the entry was newly added or had already existed. Sets detect this by value. Maps detect this by key. * Dropped `Bset..addedOpt`. * Dropped `ClsVec..added`. `test.mjs`: * `no` is also exported as `false`. * `ok` is also exported as `true`.
1 parent 8a3f6f1 commit 8cef63e

55 files changed

Lines changed: 675 additions & 1938 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

coll.mjs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ export class Bset extends Set {
2222
return this
2323
}
2424

25-
added(val) {return this.add(val), val}
26-
addedOpt(val) {return this.addOpt(val), val}
25+
added(val) {return !this.has(val) && (this.add(val), true)}
2726
reset(src) {return this.clear(), this.mut(src)}
2827
clear() {return (super.size && super.clear()), this}
2928
clone() {return new this.constructor(this)}
@@ -143,7 +142,14 @@ export class Coll extends TypedMap {
143142
reqVal(val) {return val}
144143
add(val) {return this.set(this.getKey(val), val)}
145144
addOpt(val) {return this.setOpt(this.getKeyOpt(val), val)}
146-
added(val) {return this.add(val), val}
145+
146+
added(val) {
147+
const key = this.getKey(val)
148+
const got = this.has(key)
149+
this.set(key, val)
150+
return got
151+
}
152+
147153
toArray() {return [...this.values()]}
148154
toJSON() {return this.toArray()}
149155
[Symbol.iterator]() {return this.values()}
@@ -152,9 +158,9 @@ export class Coll extends TypedMap {
152158
export class ClsColl extends Coll {
153159
get cls() {return Object}
154160
reqVal(val) {return l.reqInst(val, this.cls)}
155-
add(val) {return super.add(this.make(val))}
161+
add(val) {return (val = this.make(val)), this.set(this.getKey(val), val)}
156162
addOpt(val) {return l.isSome(val) ? super.addOpt(this.make(val)) : this}
157-
added(val) {return this.add((val = this.make(val))), val}
163+
added(val) {return super.added(this.make(val))}
158164
make(val) {return l.toInst(val, this.cls)}
159165
}
160166

@@ -217,7 +223,6 @@ export class ClsVec extends TypedVec {
217223
constructor(src) {super().mut(src)}
218224
reqVal(val) {return l.reqInst(val, this.cls)}
219225
add(val) {return super.add(this.make(val))}
220-
added(val) {return this.add((val = this.make(val))), val}
221226
make(val) {return l.toInst(val, this.cls)}
222227
}
223228

doc/cmd_doc.mjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ const FEATS = [
2020
[`coll`, `extended versions of JS data structure classes, with better APIs.`],
2121
[`url`, `better URL implementation.`],
2222
[`time`, `tools for datetimes and intervals.`],
23-
[`http`, `shortcuts for the native fetch/Request/Response APIs.`],
2423
[`path`, `various functions for working with FS paths.`],
2524
[`dom`, `shortcuts for working with the DOM.`],
2625
[`dom_shim`, `lightweight and performant shim for DOM nodes and elements.`],
@@ -30,6 +29,10 @@ const FEATS = [
3029
[`prax`, `simple system for rendering DOM elements. React-inspired syntax, better semantics and performance.`],
3130
[`obs`, `observables via proxies.`],
3231
[`obs_dom`, `automatic reactivity for custom DOM elements.`],
32+
[`http`, `shortcuts for the fetch/Response APIs, URL routing, cookie decoding/encoding.`],
33+
[`http_deno`, `tools for HTTP servers running in Deno.`],
34+
[`http_srv`, `streaming and broadcasting tools for generic HTTP servers.`],
35+
[`live_deno`, `tools for live-reloading in development.`],
3336
[`cli`, `essential tools for CLI apps.`],
3437
[`test`, `tools for testing and benchmarking.`],
3538
]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Subclass of `Error` for HTTP responses. The error message includes the HTTP status code, if any.
22

33
```ts
4-
class HttpErr extends Error {
4+
class ErrHttp extends Error {
55
message: string
66
status: int
77
res?: Response

doc/http/_ReqBui.md

Lines changed: 0 additions & 89 deletions
This file was deleted.

doc/http/_ReqRou.md

Lines changed: 0 additions & 42 deletions
This file was deleted.

doc/http/_Res.md

Lines changed: 0 additions & 34 deletions
This file was deleted.

doc/http/reqBui.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

doc/http/resOk.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Signature: `(res: Response | Promise<Response>) => Promise<Response>`.
2+
3+
Missing feature of the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). If the response is OK (HTTP code between 200 and 299, `.ok === true`), the resulting promise resolves to that response as-is. Otherwise the resulting promise is rejected with a descriptive {{link http ErrHttp}} which includes the response status code, the response body (if any) as the error message, and the response itself for introspection if needed.
4+
5+
```js
6+
import * as h from '{{featUrl http}}'
7+
8+
// If response is unsuccessful, this will throw `h.ErrHttp`.
9+
const res = await h.resOk(await fetch(someUrl, someOpt))
10+
11+
const body = res.json()
12+
```

doc/http_deno_readme.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
## Overview
2+
3+
{{codeHead}} provides essential tools for HTTP servers running in [Deno](https://deno.land).
4+
5+
* Tools for serving files (with content type detection) and directories (with optional file filtering / whitelisting / blacklisting).
6+
* Tools for simple HTML file servers, with automatic matching of "clean" URL paths such as `/` and `/posts` to HTML files such as `index.html` and `posts.html`.
7+
8+
Also see {{featLink http}} for routing and cookies, and {{featLink live_deno}} for live-reload tools for development.
9+
10+
## TOC
11+
12+
* [#Usage](#usage)
13+
* [#API](#api)
14+
* [#Misc](#misc)
15+
{{toc}}
16+
17+
## Usage
18+
19+
Simple example of a server that serves files from the current directory, automatically matching URL paths to HTML files:
20+
21+
```js
22+
import * as hd from '{{featUrl http_deno}}'
23+
24+
const srv = new class Srv extends hd.Srv {
25+
// Serves files from the current folder, with no filtering.
26+
dirs = hd.Dirs.of(hd.dirRel(`.`))
27+
28+
async res(req) {
29+
const rou = new h.ReqRou(req)
30+
31+
return (
32+
(await this.dirs.resolveSiteFileWithNotFound(req.url))?.res() ||
33+
rou.notFound()
34+
)
35+
}
36+
}()
37+
38+
await srv.listen({port: somePort})
39+
```
40+
41+
## API
42+
43+
{{api}}

doc/http_readme.md

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
## Overview
22

3-
{{codeHead}} provides tiny syntactic shortcuts for native `Request`/`Response`/`Headers`/`fetch`.
3+
{{codeHead}} provides essential tools for HTTP servers and clients:
44

5-
* Fluent builder-style API.
6-
* Interoperable with built-ins.
7-
* Shortcuts for common actions, such as:
8-
* Building HTTP requests via {{link http ReqBui}}.
9-
* A builder-style API is more concise and flexible than the native one.
10-
* Handling HTTP errors in responses via {{link http Res}}.
11-
* Constructing descriptive exceptions with HTTP status and response text.
12-
* Routing incoming HTTP requests via {{link http Rou}}.
5+
* Shortcuts for making requests via native `fetch`.
6+
* Cookie decoding and encoding.
7+
* URL-based routing for SSR and SPA apps.
138

14-
HTTP request/response utils are ported and reworked from https://github.com/mitranim/xhttp. Routing utils are ported and reworked from https://github.com/mitranim/imperouter.
9+
Also see {{featLink http_deno}} for Deno HTTP servers, {{featLink http_srv}} for generic tools for HTTP servers using native stream APIs, and {{featLink live_deno}} for live-reload tools for development.
1510

1611
## TOC
1712

@@ -32,9 +27,3 @@ const resBody = await h.reqBui().to(`/api`).post().json(reqBody).fetchOkJson()
3227
## API
3328

3429
{{api}}
35-
36-
## Misc
37-
38-
`Req..headers` is a null-prototype dict, rather than `Headers`, for performance and compatibility reasons. In Deno, many operations involving `Headers` are stupidly slow. Using plain dicts for headers seems to performs better, and is automatically compatible with object rest/spread and `Object.assign`.
39-
40-
Each header is stored as a single string. When appending, values are joined with `, `. This matches the limitations of the `Headers` and `fetch` APIs, which don't seem to support multiple occurrences of the same header.

0 commit comments

Comments
 (0)