Skip to content

Commit 741650b

Browse files
committed
Bun compatibility for IO and HTTP
In the interest of supporting Bun, this commit makes many breaking changes across existing modules. It also introduces Bun-specific IO and HTTP modules, and auto-resolution between environment-specific modules via `package.json` `imports` directives. Due to inevitable breaking changes, opportunity was taken to cleanup some other modules as well. --- Breaking: replaced `live_deno.mjs` with a reworked `http_live.mjs`. This module now works in both Bun and Deno. --- Breaking: replaced `http_srv.mjs` with a reworked `http_shared.mjs`. Added `concatStreams`. Moved `EXT_TO_MIME_TYPE` and `guessContentType` to this file. All features of this module are also exported by `http_deno.mjs` and the new `http_bun.mjs`. --- `http_deno.mjs`: Breaking: - Dropped: - `isErrCancel` - `dirAbs` - `dirRel` - `DirBase` - `Fil` - `HttpFileInfo` (see `HttpFile`) - `HttpFileStream` (no longer needed in Deno) - Renamed: - `DirBase` → `BaseHttpDir` - `DirAbs` → `HttpDir` - `DirRel` → `HttpDir` - `DirRelFil` → `HttpDir` (merged 3 into 1) - `Dirs` → `HttpDirs` - All "resolve file" directory methods now require a properly parsed URL pathname string, expecting the caller to handle its parsing. However, they do perform URL component decoding. Added: `HttpFile`, which serves the same role as the earlier `HttpFileInfo`, with almost the same API. --- Added `http_bun.mjs` whose API nearly mirrors `http_deno.mjs`. The environment-appropriate module is auto-resolved when importing the pseudo-module `http`. --- `io_deno.mjs`: Breaking: - Dropped: - `create` (use `writeFile`) - `touch` - `readTextCreate` - `readJson` - `filterWatch` - `FileInfo` - `isReader` - `reqReader` - `isCloser` - `reqCloser` - `ReaderStreamSource` (no longer needed in Deno) - `FileStream` (no longer needed in Deno) - `EnvMap` - Renamed: - `readText` → `readFileText` - `readTextOpt` → `readFileTextOpt` - `readTextSync` → `readFileTextSync` - `readTextSyncOpt` → `readFileTextOptSync` - Moved: - `ConcatStreamSource`: to `http_shared.mjs` / `http_deno.mjs`. - Modified: - `watchCwd` and `watchRel` now yield events one-by-one. Added: - `ENV` - `exit` - `skipErrNotFound` - `readFileBytes` - `readFileBytesSync` - `writeFileSync` - `remove` - `removeSync` - `exists` - `existsSync` - `stat` - `statSync` - `statOpt` - `statOptSync` - `fileReadStream` - `fileWriteStream` - `readDir` - `readDirSync` - `validPath` --- Added `io_bun.mjs` whose API almost mirrors `io_deno.mjs`, with some differences which are expensive to fix: - No `fileWriteStream`. - `readDir` and `readDirSync` list strings, not stringable objects with metadata. The environment-appropriate module is auto-resolved when importing the pseudo-module `io`. --- `dom.mjs`: Breaking: dropped: - `DOM_EXISTS` - `isDomHandler` - `reqDomHandler` - `optDomHandler` - `addEvents` - `removeEvents` - `clipNode` - `setText` - `mutDoc` - `DocHeadMut` - `DocBodyMut` - `DocFoc` Added: - `eventDispatch` - `eventListen` - `ListenRef` --- `http.mjs`: Breaking: dropped: - `Ctx..link` - `Ctx..unlink` - `Ctx..handleEvent` - `Ctx..sub` Improved memory management in `Ctx`. When linking a `Ctx` against a parent signal, the signal and the child context now hold each other weakly, via `ListenRef`. User code is now free to drop either the parent signal or the child context without calling `.abort`, and the dropped object will now be eligible for GC while the other one is still in use. When a child context is GC-d, its listener is removed from the parent signal. In engines without support for `WeakRef` or `FinalizationRegistry`, references work as before this change. Added `notFound`. --- `iter.mjs`: Breaking: - Dropped: - `setOf` - `setCopy` - `mapOf` - Renamed: - `setFrom` → `toSet` --- `path.mjs`: Breaking: dropped: - `isPath` (use `lang.mjs` → `isScalar`) - `reqPath` (use `lang.mjs` → `reqScalar`) - `optPath` (use `lang.mjs` → `optScalar`) Added `hasExt` which should be slightly faster than `!!ext(path)`. --- `prax.mjs`: `Ren..replaceChi` now avoids touching child nodes which occur in the exact same positions at the start of both lists: existing child nodes and new list of putative child nodes; but only at the start. This avoids side-effectful disconnect / reconnect when repeatedly passing the same starting children for the same target element. --- `lang.mjs`: Added `errSkip`.
1 parent 83d369e commit 741650b

File tree

100 files changed

+2960
-2494
lines changed

Some content is hidden

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

100 files changed

+2960
-2494
lines changed

.eslint.config.mjs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
export default [
2+
{
3+
languageOptions: {
4+
ecmaVersion: 2022,
5+
sourceType: `module`,
6+
globals: {
7+
console: `readonly`,
8+
performance: `readonly`,
9+
crypto: `readonly`,
10+
queueMicrotask: `readonly`,
11+
setTimeout: `readonly`,
12+
clearTimeout: `readonly`,
13+
setInterval: `readonly`,
14+
clearInterval: `readonly`,
15+
fetch: `readonly`,
16+
URL: `readonly`,
17+
URLSearchParams: `readonly`,
18+
Request: `readonly`,
19+
Response: `readonly`,
20+
Headers: `readonly`,
21+
AbortController: `readonly`,
22+
AbortSignal: `readonly`,
23+
Blob: `readonly`,
24+
File: `readonly`,
25+
Intl: `readonly`,
26+
TextDecoder: `readonly`,
27+
TextEncoder: `readonly`,
28+
ReadableStream: `readonly`,
29+
Event: `readonly`,
30+
EventTarget: `readonly`,
31+
CustomEvent: `readonly`,
32+
FormData: `readonly`,
33+
},
34+
},
35+
rules: {
36+
[`no-restricted-globals`]: [`error`,
37+
// window (browser)
38+
`alert`, `blur`, `confirm`, `event`, `find`, `focus`, `history`,
39+
`length`, `location`, `name`, `open`, `parent`, `print`,
40+
`prompt`, `scroll`, `self`, `status`, `stop`, `top`,
41+
// global (node)
42+
`root`,
43+
/* other */
44+
`test`,
45+
/* These global functions are broken */
46+
`isNaN`, `isFinite`,
47+
],
48+
49+
[`consistent-return`]: `error`,
50+
[`constructor-super`]: `error`,
51+
[`eqeqeq`]: [`error`, `always`, {null: `never`}],
52+
[`for-direction`]: `error`,
53+
[`no-async-promise-executor`]: `error`,
54+
[`no-case-declarations`]: `error`,
55+
[`no-class-assign`]: `error`,
56+
[`no-compare-neg-zero`]: `error`,
57+
[`no-cond-assign`]: `error`,
58+
[`no-const-assign`]: `error`,
59+
[`no-constant-condition`]: `error`,
60+
[`no-control-regex`]: `error`,
61+
[`no-debugger`]: `error`,
62+
[`no-delete-var`]: `error`,
63+
[`no-dupe-args`]: `error`,
64+
[`no-dupe-class-members`]: `error`,
65+
[`no-dupe-else-if`]: `error`,
66+
[`no-dupe-keys`]: `error`,
67+
[`no-duplicate-case`]: `error`,
68+
[`no-empty`]: [`error`, {allowEmptyCatch: true}],
69+
[`no-empty-character-class`]: `error`,
70+
[`no-empty-pattern`]: `error`,
71+
[`no-ex-assign`]: `error`,
72+
[`no-extra-boolean-cast`]: `error`,
73+
[`no-extra-semi`]: `error`,
74+
[`no-fallthrough`]: `error`,
75+
[`no-func-assign`]: `error`,
76+
[`no-global-assign`]: `error`,
77+
[`no-import-assign`]: `error`,
78+
[`no-inner-declarations`]: `error`,
79+
[`no-invalid-regexp`]: `error`,
80+
[`no-invalid-this`]: [`error`, {capIsConstructor: false}],
81+
[`no-irregular-whitespace`]: `error`,
82+
[`no-misleading-character-class`]: `error`,
83+
[`no-mixed-spaces-and-tabs`]: `error`,
84+
[`no-new-symbol`]: `error`,
85+
[`no-obj-calls`]: `error`,
86+
[`no-octal`]: `error`,
87+
[`no-prototype-builtins`]: `error`,
88+
[`no-redeclare`]: `error`,
89+
[`no-regex-spaces`]: `error`,
90+
[`no-self-assign`]: `error`,
91+
[`no-setter-return`]: `error`,
92+
[`no-shadow-restricted-names`]: `error`,
93+
[`no-sparse-arrays`]: `error`,
94+
[`no-this-before-super`]: `error`,
95+
[`no-undef`]: `error`,
96+
[`no-unexpected-multiline`]: `error`,
97+
[`no-unreachable`]: `error`,
98+
[`no-unsafe-finally`]: `error`,
99+
[`no-unsafe-negation`]: `error`,
100+
[`no-unused-expressions`]: `error`,
101+
[`no-unused-labels`]: `error`,
102+
[`no-unused-vars`]: [`error`, {argsIgnorePattern: `^_`, varsIgnorePattern: `^_`}],
103+
[`no-useless-catch`]: `error`,
104+
[`no-useless-escape`]: `error`,
105+
[`no-warning-comments`]: [`error`, {location: `anywhere`, terms: [`FIXME`]}],
106+
[`no-with`]: `error`,
107+
[`object-curly-spacing`]: [`error`, `never`],
108+
[`require-yield`]: `error`,
109+
[`semi`]: [`error`, `never`],
110+
[`use-isnan`]: `error`,
111+
[`valid-typeof`]: `error`,
112+
113+
// [`quotes`]: [`error`, `backtick`], // Doesn't work properly.
114+
},
115+
},
116+
{
117+
files: [`doc/*.mjs`],
118+
languageOptions: {ecmaVersion: 2025},
119+
},
120+
]

.eslintrc

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

cli.mjs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ export class Flag extends s.StrMap {
141141
/*
142142
Simple "env" map with support for parsing "env properties" strings. The parser
143143
supports comments with `#` but not `!`, doesn't support backslash escapes, and
144-
doesn't allow whitespace around `=`. Doesn't perform any IO; see `io_deno.mjs`
145-
→ `EnvMap` which is a subclass.
144+
doesn't allow whitespace around `=`. Doesn't perform any IO.
146145
*/
147146
export class EnvMap extends c.Bmap {
148147
set(key, val) {return super.set(l.reqStr(key), l.render(val))}
@@ -215,17 +214,21 @@ export function arrClearHard() {
215214
return ARR_CLEAR_HARD ??= new TextEncoder().encode(TERM_ESC_CLEAR_HARD)
216215
}
217216

218-
export async function timed(tag, fun) {
217+
export function timed(tag, fun) {
219218
const pre = tag ? s.san`[${tag}] ` : ``
220219
const start = performance.now()
220+
const out = fun()
221+
if (l.isPromise(out)) return timedAsync(out, pre, start)
222+
const end = performance.now()
223+
console.log(s.san`${pre}done in ${end - start} ms`)
224+
return out
225+
}
221226

222-
try {
223-
return await fun()
224-
}
225-
finally {
226-
const end = performance.now()
227-
console.log(s.san`${pre}done in ${end - start} ms`)
228-
}
227+
async function timedAsync(out, pre, start) {
228+
out = await out
229+
const end = performance.now()
230+
console.log(s.san`${pre}done in ${end - start} ms`)
231+
return out
229232
}
230233

231234
/* Internal */

doc/cli/_Flag.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Parser for CLI args. Features:
88
* On-demand parsing of booleans and numbers.
99

1010
```js
11-
const cli = cl.Flag.os()
12-
const args = cli.args
13-
const watch = cli.boolOpt(`w`)
11+
const flags = cl.Flag.os()
12+
const args = flags.args
13+
const watch = flags.boolOpt(`-w`)
1414
```

0 commit comments

Comments
 (0)