@amritk/nish-aarch64-darwin 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/INSTALL.md +22 -13
  2. package/bin/nish +0 -0
  3. package/docs/AI.md +86 -16
  4. package/package.json +1 -1
  5. package/runtime/async.d.mts +49 -0
  6. package/runtime/async.mjs +27 -0
  7. package/runtime/nish.d.ts +4681 -427
  8. package/runtime/nish.h +6 -2
  9. package/runtime/nish.mjs +4 -0
  10. package/runtime/runtime-net.c +22 -0
  11. package/runtime/runtime-shm.c +93 -2
  12. package/runtime/vite.d.ts +30 -0
  13. package/runtime/vite.mjs +150 -0
  14. package/scripts/build.sh +108 -13
  15. package/std/README.md +131 -131
  16. package/std/base64.ts +34 -5
  17. package/std/bytes.ts +258 -42
  18. package/std/cli-args.ts +296 -70
  19. package/std/cli-flags.ts +184 -19
  20. package/std/cli.ts +475 -54
  21. package/std/collections.ts +121 -23
  22. package/std/compress/checksum.ts +44 -14
  23. package/std/compress/deflate.ts +224 -111
  24. package/std/compress/gzip.ts +217 -53
  25. package/std/compress/zlib.ts +63 -7
  26. package/std/crypto/aes.ts +80 -9
  27. package/std/crypto/base64url.ts +22 -0
  28. package/std/crypto/bcrypt-batch.ts +88 -21
  29. package/std/crypto/bcrypt.ts +60 -0
  30. package/std/crypto/chacha20poly1305.ts +53 -0
  31. package/std/crypto/ct.ts +32 -13
  32. package/std/crypto/ed25519.ts +47 -0
  33. package/std/crypto/hkdf.ts +198 -13
  34. package/std/crypto/hmac.ts +235 -31
  35. package/std/crypto/jwt.ts +192 -63
  36. package/std/crypto/p256.ts +159 -16
  37. package/std/crypto/p384.ts +28 -3
  38. package/std/crypto/pki-roots.ts +32 -2
  39. package/std/crypto/pki.ts +81 -15
  40. package/std/crypto/rsa.ts +33 -3
  41. package/std/crypto/sha1.ts +3 -0
  42. package/std/crypto/sha256.ts +24 -1
  43. package/std/crypto/sha512.ts +99 -14
  44. package/std/crypto/x25519.ts +152 -14
  45. package/std/crypto/x509-random.ts +10 -0
  46. package/std/crypto/x509.ts +67 -7
  47. package/std/json-equal.ts +19 -0
  48. package/std/json-format.ts +112 -13
  49. package/std/json-number.ts +64 -14
  50. package/std/json-pointer.ts +23 -1
  51. package/std/json-tokenizer.ts +100 -29
  52. package/std/json-typed.ts +713 -66
  53. package/std/json-value.ts +400 -124
  54. package/std/json.ts +138 -10
  55. package/std/map.ts +25 -7
  56. package/std/math.ts +36 -4
  57. package/std/net/buffer-pool.ts +42 -11
  58. package/std/net/dns-config.ts +109 -23
  59. package/std/net/dns-message.ts +62 -7
  60. package/std/net/dns-resolver.ts +247 -53
  61. package/std/net/dns.ts +203 -35
  62. package/std/net/fetch.ts +151 -61
  63. package/std/net/handler.ts +278 -80
  64. package/std/net/hpack.ts +262 -52
  65. package/std/net/http-compress.ts +125 -15
  66. package/std/net/http-fields.ts +85 -9
  67. package/std/net/http1-client-codec.ts +100 -19
  68. package/std/net/http1-codec.ts +297 -77
  69. package/std/net/http1-server.ts +430 -94
  70. package/std/net/http2-frame.ts +272 -35
  71. package/std/net/http2-tls.ts +135 -34
  72. package/std/net/http2.ts +247 -106
  73. package/std/net/http3-frame.ts +154 -17
  74. package/std/net/http3-server.ts +275 -101
  75. package/std/net/http3.ts +307 -115
  76. package/std/net/outbound.ts +37 -3
  77. package/std/net/postgres-carrier.ts +144 -8
  78. package/std/net/postgres.ts +801 -112
  79. package/std/net/prefork.ts +164 -31
  80. package/std/net/qpack.ts +105 -18
  81. package/std/net/quic-conn-ack.ts +59 -12
  82. package/std/net/quic-conn-cid.ts +124 -27
  83. package/std/net/quic-conn-params.ts +70 -10
  84. package/std/net/quic-datagram.ts +43 -3
  85. package/std/net/quic-frame.ts +286 -12
  86. package/std/net/quic-listener.ts +101 -32
  87. package/std/net/quic-packet.ts +302 -21
  88. package/std/net/quic-recovery.ts +264 -52
  89. package/std/net/quic-stream.ts +353 -91
  90. package/std/net/quic.ts +1124 -201
  91. package/std/net/router.ts +87 -40
  92. package/std/net/tls/client.ts +166 -51
  93. package/std/net/tls/codec.ts +413 -56
  94. package/std/net/tls/record-client.ts +110 -55
  95. package/std/net/tls/record-server.ts +159 -59
  96. package/std/net/tls/record.ts +109 -12
  97. package/std/net/tls/schedule.ts +235 -26
  98. package/std/net/tls/ticket.ts +159 -40
  99. package/std/net/tls/verify.ts +49 -3
  100. package/std/net/tls-tcp.ts +250 -45
  101. package/std/net/tls.ts +221 -59
  102. package/std/net/upstream.ts +81 -45
  103. package/std/net/url.ts +97 -13
  104. package/std/net/websocket.ts +122 -12
  105. package/std/net/webtransport.ts +220 -89
  106. package/std/pair.ts +10 -2
  107. package/std/random.ts +34 -9
  108. package/std/regex.ts +352 -198
  109. package/std/region.ts +70 -15
  110. package/std/secret.ts +52 -11
  111. package/std/sort.ts +17 -2
  112. package/std/sqlite.ts +256 -35
  113. package/std/sync/ring.ts +430 -40
  114. package/std/sync/shm.ts +222 -15
  115. package/std/term-io.ts +137 -64
  116. package/std/term-pixels.ts +144 -19
  117. package/std/term-probe.ts +66 -25
  118. package/std/term-rate.ts +128 -57
  119. package/std/term.ts +332 -121
  120. package/std/testing.ts +130 -32
  121. package/std/text.ts +73 -7
  122. package/std/threads.ts +229 -41
  123. package/std/yaml-json.ts +94 -82
  124. package/std/yaml-lines.ts +47 -15
  125. package/std/yaml-write.ts +24 -16
  126. package/std/yaml.ts +764 -384
package/INSTALL.md CHANGED
@@ -52,7 +52,14 @@ export PATH="$(brew --prefix llvm@18)/bin:$PATH" # add to your shell profile
52
52
  ```
53
53
 
54
54
  Xcode's `clang` (`xcode-select --install`) also works for native binaries;
55
- the Homebrew LLVM is needed for the `wasm` and `wasi` profiles (`wasm-ld`).
55
+ the Homebrew LLVM is needed for the `wasm`, `wasm-host` and `wasi` profiles (`wasm-ld`).
56
+
57
+ `wasm-opt` (binaryen: `apt-get install binaryen`, `brew install binaryen`) is
58
+ optional. When it is on `PATH`, `scripts/build.sh --profile wasm-host` runs
59
+ `wasm-opt -Oz` on the module, and the build line says whether it ran. Without
60
+ it the module is complete, just not as small.
61
+
62
+ <a id="wasi-optional-for---profile-wasi" style="scroll-margin-top: 65px"></a>
56
63
 
57
64
  ### WASI (optional, for `--profile wasi`)
58
65
 
@@ -105,7 +112,7 @@ of its own architecture by the release workflow before the release existed, and
105
112
  installing is a download and an unpack.
106
113
 
107
114
  Through npm, which is also how an Nish *program* resolves its dependencies
108
- ([wp21-packages.md](wp21-packages.md)), so this is the one to pick if you want
115
+ ([wp21-packages.md](https://github.com/amritk/nish/blob/main/docs/wp21-packages.md)), so this is the one to pick if you want
109
116
  the compiler pinned per project in a `package.json`:
110
117
 
111
118
  ```bash
@@ -169,7 +176,7 @@ release also attaches `nish-<version>.spdx.json`, an SPDX 2.3 software bill of
169
176
  materials: every attached file with its SHA-256, the clang, linker, Node.js
170
177
  and seed compiler that built each tarball (recorded by the build row itself),
171
178
  and the vendored code from
172
- [THIRD_PARTY_NOTICES.md](../THIRD_PARTY_NOTICES.md) that each of them contains.
179
+ [THIRD_PARTY_NOTICES.md](https://github.com/amritk/nish/blob/main/THIRD_PARTY_NOTICES.md) that each of them contains.
173
180
  How these fit the rest of the release's defences is
174
181
  [docs/security/supply-chain.md](security/supply-chain.md).
175
182
 
@@ -198,13 +205,13 @@ never fails over it.
198
205
  > installers above handle it by running the binary through a one-line `exec` of
199
206
  > an absolute path. If you unpack a tarball by hand, invoke it by path
200
207
  > (`nish-<version>-<asset>/bin/nish`) or write that wrapper yourself. The
201
- > underlying defect is [wp19 §5a](wp19-stage0-retirement.md#5a-what-r6-is-waiting-on)
208
+ > underlying defect is [wp19 §5a](https://github.com/amritk/nish/blob/main/docs/wp19-stage0-retirement.md#5a-what-r6-is-waiting-on)
202
209
  > item 4.
203
210
 
204
211
  **The package is `nish` from 0.20.0.** Releases up to 0.18.0 were published
205
212
  as `@amritk/nish` (0.19.0's publish to npm failed), which is deprecated and
206
213
  points here; `npm install -g nish`
207
- replaces it ([docs/wp12-release.md](wp12-release.md#the-npm-name)). Versions
214
+ replaces it ([docs/wp12-release.md](https://github.com/amritk/nish/blob/main/docs/wp12-release.md#the-npm-name)). Versions
208
215
  0.0.0 and 0.0.1 of `nish` are an unrelated 2014 project that held the name
209
216
  before it, so pin `nish@^0.20.0` or later rather than an older range.
210
217
 
@@ -233,9 +240,9 @@ nish: no prebuilt compiler for freebsd/x64
233
240
  Until 0.6.0 it ran the TypeScript compiler that shipped in the same package
234
241
  instead — the same compiler by every test here, about eight times slower, and
235
242
  no C toolchain needed. That compiler was stage0, which was deleted in R6
236
- ([wp19](wp19-stage0-retirement.md)), so there is nothing left in the package to
243
+ ([wp19](https://github.com/amritk/nish/blob/main/docs/wp19-stage0-retirement.md)), so there is nothing left in the package to
237
244
  fall back to. The cost is stated where the rest of that deletion's costs are,
238
- in [wp19 §6](wp19-stage0-retirement.md#6-what-retirement-costs-stated-plainly),
245
+ in [wp19 §6](https://github.com/amritk/nish/blob/main/docs/wp19-stage0-retirement.md#6-what-retirement-costs-stated-plainly),
239
246
  and it is a real one: **musl, FreeBSD and 32-bit platforms have no `npm
240
247
  install` route to a compiler any more.**
241
248
 
@@ -276,7 +283,7 @@ to have on the issue tracker rather than a workaround to discover here.
276
283
  `nish` from 0.20.0; 0.19.0 is on GitHub only, because its npm publish
277
284
  failed. Every release publishes the main package and its platform packages to
278
285
  npm from `release.yml`, by trusted publishing
279
- ([docs/wp12-release.md](wp12-release.md#release-procedure) step 4), so
286
+ ([docs/wp12-release.md](https://github.com/amritk/nish/blob/main/docs/wp12-release.md#release-procedure) step 4), so
280
287
  `npm install -g nish` is the whole install. The rest of this section is
281
288
  for a machine that cannot reach the registry, or a release before 0.10.0.
282
289
 
@@ -358,7 +365,7 @@ v0.16.0; v0.1.1 was the first release with a binary attached.
358
365
  The `v0.1.0` tag exists but has no release behind it and no assets, so every
359
366
  `v0.1.0` download URL is a 404 — the tag was pushed by a workflow, and GitHub
360
367
  raises no event for that, so nothing ever built it
361
- ([docs/wp12-release.md](wp12-release.md#release-procedure) step 2). When a newer
368
+ ([docs/wp12-release.md](https://github.com/amritk/nish/blob/main/docs/wp12-release.md#release-procedure) step 2). When a newer
362
369
  release exists, take its version from
363
370
  [the releases page](https://github.com/amritk/nish/releases/latest).
364
371
 
@@ -435,7 +442,7 @@ over, `runtime-checksum.c` the CRC-32 kernels of `nish/compress/checksum`,
435
442
  `runtime-sandbox.c` the confinement a `--sandbox` build applies, and
436
443
  `runtime-shm.c` the shared-memory regions of `nish/sync/shm`.
437
444
  They are separate so that each carries its own measured size ceiling
438
- ([docs/wp7-runtime.md](wp7-runtime.md)); nothing in the core calls into the
445
+ ([docs/wp7-runtime.md](https://github.com/amritk/nish/blob/main/docs/wp7-runtime.md)); nothing in the core calls into the
439
446
  others, so a line that names only `runtime.c` and `runtime-os.c` still links a
440
447
  program that uses none of the other nine. `scripts/build.sh` compiles the other
441
448
  nine beside any
@@ -451,7 +458,7 @@ beside `-DNISH_THREADS=1`).
451
458
  ## 2a. What `npm run build` does
452
459
 
453
460
  `src/` is the compiler, written in Nish, and it compiles itself
454
- ([docs/wp14-selfhost.md](wp14-selfhost.md)). From a checkout, with clang on
461
+ ([docs/wp14-selfhost.md](https://github.com/amritk/nish/blob/main/docs/wp14-selfhost.md)). From a checkout, with clang on
455
462
  `PATH`, `npm run build` runs `scripts/bootstrap.sh` with the seed from §2:
456
463
 
457
464
  ```bash
@@ -486,7 +493,7 @@ in `src/` and becomes usable inside `src/` from the next release on; CI's
486
493
  `bootstrap` job is what checks that the released seed still builds stage1.
487
494
  Until R6 the seed was a TypeScript compiler, stage0, run under Node; it was
488
495
  deleted once the native one answered every flag it did
489
- ([wp19](wp19-stage0-retirement.md)).
496
+ ([wp19](https://github.com/amritk/nish/blob/main/docs/wp19-stage0-retirement.md)).
490
497
 
491
498
  ## 3. Hello world
492
499
 
@@ -518,7 +525,7 @@ nish hello.ts -o hello.ll
518
525
 
519
526
  Other build profiles: `--profile size` (smallest binary), `--profile debug`
520
527
  (no optimisation, symbols kept). Run `nish --help` for every flag, and
521
- see the [README](../README.md) for the language subset.
528
+ see the [README](https://github.com/amritk/nish/blob/main/README.md) for the language subset.
522
529
 
523
530
  To use a program as a script rather than keep the binary, run it:
524
531
 
@@ -549,6 +556,8 @@ it cannot make private, compiles the runtime itself as it always did; the
549
556
  wasi profile and `scripts/build.sh` called directly never use the cache.
550
557
  Removing the directory is always safe.
551
558
 
559
+ <a id="4-exit-codes" style="scroll-margin-top: 65px"></a>
560
+
552
561
  ## 4. Exit codes
553
562
 
554
563
  | Code | Meaning |
package/bin/nish CHANGED
Binary file
package/docs/AI.md CHANGED
@@ -108,7 +108,9 @@ the difference is a row of [the user guide's table](guide/using-nish/to-typescri
108
108
  or a bug in `nish` worth reporting. A program on `nish:net`, the signal
109
109
  descriptor or a C declaration (NL4010, NL4011), a compound assignment whose
110
110
  index would run twice (NL4012) or a generic whose element type decides its
111
- code (NL4013, NL4014) is refused and has no TypeScript to run.
111
+ code (NL4013, NL4014) is refused and has no TypeScript to run. An `async`
112
+ program is written as Node async/await, whose spawned tasks may print in
113
+ another order than native.
112
114
 
113
115
  Two more surfaces worth knowing: `nish --emit-ast f.ts` prints what was parsed
114
116
  and `nish --emit-checked f.ts` prints the side tables the emitter reads. Both
@@ -140,7 +142,11 @@ everywhere, a template literal instead of `String(n)`.
140
142
  - A module is one `.ts` file. At the top level it may hold **only**
141
143
  declarations: `const` arrows (functions), `class`, `interface`, module
142
144
  `const`s, `type` aliases, numeric `enum`s, and `import`s. There is no
143
- top-level code, so there is no initialisation order to think about.
145
+ top-level code, so there is no initialisation order to think about. The
146
+ one exception is an entry module with no `main`: its top-level statements
147
+ run as `main` (`docs/LANGUAGE.md` → "Top-level code"). Declare every
148
+ function above the first statement, and pass a function what it needs
149
+ rather than naming a variable of the code.
144
150
  - `export const main` lives in the entry module only, takes no parameters, and
145
151
  returns `void` or an `i32`-lowered `number` — the process exit code. Under
146
152
  `--number-mode f64`, declare it `main(): i32`.
@@ -175,12 +181,12 @@ rejects. This table is the highest-value part of the page.
175
181
  | `h.get<i32>(7)` (type argument at a method call) | `Type arguments are not written at a call site in Nish` | `h.get(7)` — a generic method infers like a generic function |
176
182
  | `<T>(p: T) => p.x` (a member of a type parameter) | `` Cannot read `x` of `T`: an unconstrained type parameter has no members `` | `<T extends Point>(p: T) => p.x`, where `Point` is a class or interface that declares `x` |
177
183
  | `identity<i32>(7)` (type argument at a call) | `Type arguments are not written at a call site in Nish` | `identity(7)` — `T` is inferred from the arguments |
178
- | `async` / `await` / `Promise` | forbidden (no event loop) | the I/O builtins are synchronous |
184
+ | a promise in a variable, `.then`, `Promise.all` | forbidden: a promise is never a value | `await` each call where it is made; see [Async functions](#async-functions) |
179
185
  | `namespace N { }`, `declare global { }`, `@decorator` | forbidden | one module per file; a plain function in place of a decorator |
180
186
  | `keyof T`, `<T = i32>` (a default type argument) | `` Unsupported type `keyof T` (Phase 1 supports …) `` / `a default type argument … is not supported` | name the type; a type argument is always inferred |
181
187
  | `class B extends A` | `` `extends` is not supported: Nish has no inheritance `` | repeat the fields and `implements` an interface |
182
188
  | `static` members, `get x()` / `set x(v)` | `` … `static` members are not supported `` / `` Getters and setters are not supported in class `C` (use a method) `` | module `const`s and plain methods |
183
- | `const [a, b] = xs`, `({ x }: Point) =>`, `(n?: i32)`, `(n = 1)`, `f(...xs)` | `Destructuring is not supported` / `Destructured parameters are not supported` / `Optional parameters are not supported` / `` Parameter `n` has a default and no type annotation `` / `Spread arguments are not supported` | one name per binding; `n: i32 = 1` (a constant or an earlier parameter) for a default; `...ns: i32[]` as the last parameter, or pass the array itself |
189
+ | `const [a, b] = xs`, `({ x }: Point) =>`, `(n?: i32)`, `(n = 1)`, `f(...xs)` | `Destructuring is not supported` / `Destructured parameters are not supported` / `Optional parameters are not supported` / `` Parameter `n` has a default and no type annotation `` / `Spread arguments are not supported` | one name per binding; `n: i32 = 1` (a constant or an earlier parameter) for a default, `o: Opts | null = null` for an options argument; `...ns: i32[]` as the last parameter, or pass the array itself |
184
190
  | `function f(): void;` (an overload), `export default function ()` | `Functions must have a body` / `Functions must be named` | one named function, with its body |
185
191
  | a method in an `interface` | `` Interface `I` cannot declare methods (interfaces describe layout only) `` | fields only; a top-level function over the interface |
186
192
  | `abstract class`, `declare class`, `constructor(public x: i32)`, `interface B extends A`, `[k: string]: T` | `Abstract classes are not supported` / `` `declare class` is not supported `` / `Parameter properties … are not supported; declare the field and assign it` / ``Interface inheritance (`extends`) is not supported; list every field`` / `Index signatures are not supported …` | a plain class with its fields declared and assigned in the constructor; every field listed; a `Map` for a keyed table |
@@ -583,8 +589,11 @@ const double = (n: i32): i32 => n * 2; // a concise body is that one `return`
583
589
  - **Parameters are immutable**: `p = 1`, `p++`, `p += 1` are all rejected. Copy
584
590
  into a `let` first.
585
591
  - A non-`void` function must return on every path.
586
- - Rejected: generators, `async`, destructured / rest / optional / default
587
- parameters, overloads, nested function declarations. Type parameters *are*
592
+ - Rejected: generators, a method that is `async`, destructured and optional
593
+ (`x?: T`) parameters, overloads, nested function declarations. A default
594
+ (`n: i32 = 1`) or a rest parameter (`...ns: i32[]`) is allowed on a
595
+ function, a method, a constructor or a module `const` arrow — see
596
+ "Optional parameters" in [Recipes for what is missing](#recipes-for-what-is-missing). Type parameters *are*
588
597
  allowed — see [Generic functions](#generic-functions).
589
598
 
590
599
  ### Generic functions
@@ -850,8 +859,8 @@ export const main = (): i32 => {
850
859
  (`(x) => { if (x > limit) { hits.push(x) } }`); each capture becomes one more
851
860
  argument of the direct call. It may not assign to one, read a `let`
852
861
  (`` The arrow reads `k`, a `let` of the function it is written in: ... bind the value to a `const` before the call ``),
853
- read `this` (bind `const self = this`), or read a function parameter of its
854
- function. An arrow inside another arrow, or given to a method, a
862
+ read `this` (bind `const self = this`), or read a function-typed parameter
863
+ of its function. An arrow inside another arrow, or given to a method, a
855
864
  constructor, `expose` or `exposeWith`, captures nothing; `xs.sort(cmp)`'s
856
865
  comparator is the exception, and captures as an arrow argument does.
857
866
  - **The argument's type must match exactly**: `(x: i32) => i64` for a
@@ -873,6 +882,52 @@ export const main = (): i32 => {
873
882
  };
874
883
  ```
875
884
 
885
+ ### Async functions
886
+
887
+ `async` compiles natively: a function that awaits becomes a frame and a resume
888
+ switch, one that awaits nothing a plain function, and `export async function
889
+ main` runs to its end, then finishes every task it spawned. Nothing waits on
890
+ sockets or timers in this release, so every task runs to completion.
891
+ `--emit-ts` writes it as Node async/await, where `spawn`ed tasks resume in
892
+ Node's order, not the native one. A call
893
+ that can fail answers `Promise<Result<T, E>>`: test the `Result` after the
894
+ `await`. The rules:
895
+
896
+ - `async` goes on a top-level `function` or an arrow, never a method
897
+ (`NL1063`). Its return type is `Promise<T>` (`NL2655`), and `Promise<T>`
898
+ appears nowhere else — not on a parameter, field, local or alias (`NL2654`).
899
+ - **`await` takes a direct call to an `async` function** (`NL2643` for a value,
900
+ `NL2644` for a plain function's call), **at the top of a statement**: alone,
901
+ as a `const`/`let` initializer, after `return`, or right of a plain `=`.
902
+ Anywhere inside a larger expression is `NL2642`, so bind first:
903
+ `const n = await load(1); console.log(n);`.
904
+ - An `async` call that is not awaited is `NL2645`: a promise is never a value.
905
+ No `.then` (`NL2650`), no `Promise.all` (`NL2649`), no `for await`
906
+ (`NL2133`).
907
+ - Several at once: `import { awaitAll, spawn } from "nish:async"`, then
908
+ `const [a, b] = await awaitAll(f(x), g(y))` (two to eight calls, one name
909
+ each, `NL2647`). `spawn(f(x))` starts a task without waiting; `f` answers
910
+ `void` or a `Result` (`NL2646`).
911
+ - No recursion through `await`, direct or mutual (`NL2648`): write a loop.
912
+ - An `async` arrow goes only to a parameter whose function type answers
913
+ `Promise<T>` (`NL2639`), and only an `async` one goes there (`NL2640`).
914
+ - No `async` under a wasm target or `--profile wasi` (`NL2652`).
915
+ - `spawn(f(x))` runs `f` at once, until it first waits on the outside world,
916
+ before it returns; Node runs `f` only to its first `await` and the rest
917
+ after the spawning task yields. Do not rely on either order.
918
+
919
+ ```ts nish:err NL2642
920
+ async function load(id: i32): Promise<i32> {
921
+ return id;
922
+ }
923
+
924
+ async function run(): Promise<void> {
925
+ console.log(await load(1));
926
+ }
927
+
928
+ export const main = (): i32 => 0;
929
+ ```
930
+
876
931
  ### Data parallelism: `nish/threads`
877
932
 
878
933
  `parallelMapInto(src, dst, f)` writes `f(src[i])` into `dst[i]`, and
@@ -1425,6 +1480,13 @@ export const main = (): i32 => {
1425
1480
  ```
1426
1481
 
1427
1482
  - **No body, and it cannot be `export`ed.**
1483
+ - **Not in a `--target wasm32` build, nor an `--emit-dts` one with no
1484
+ `--target`** (NL2666; `--target wasm32-wasi` keeps it): there a function the page
1485
+ supplies is imported from a host module, the page's own TypeScript file
1486
+ named by `--host`, and becomes a wasm import from module `host`. Only
1487
+ scalars, enums and `HostHandle<"kind">` (a nominal `i32` for an object the
1488
+ page keeps) cross; `import { Canvas, fill } from "./host.ts"`, no `type`
1489
+ modifier.
1428
1490
  - **A class with a `CPtr` field is a handle class: open one with `using`.**
1429
1491
  `using f = new File(p)` closes `f` once at every exit of its block (falling
1430
1492
  off the end, `return`, `break`, `continue`, `orReturn()`), so never call the
@@ -2243,7 +2305,8 @@ backlog)`, `tcpAccept(fd, peer)`, `netRead(fd, buf, off, len)`,
2243
2305
  `i32`: **a negative number is a failure, not an exception** — `-11` means "would
2244
2306
  block, call again", `-32` a peer that has gone (never SIGPIPE), `-98` the port
2245
2307
  is in use, `-111` refused, `-22` a bad argument. Every socket is non-blocking,
2246
- and there is no `async` and no callback: your `main` is the loop. A client calls
2308
+ and there is no callback, and an `async` function cannot wait on a socket yet
2309
+ (its tasks run on an in-process queue): your `main` is the loop. A client calls
2247
2310
  `tcpConnect(addr)`, which answers the descriptor while it is still connecting;
2248
2311
  wait for it to be writable, then `connectResult(fd)` is 0 or the failure. Buffers
2249
2312
  are `u8[]` only; an address is 18 bytes of one (IPv4 as `::ffff:a.b.c.d`, then
@@ -2254,6 +2317,9 @@ To fetch a URL from a CLI, skip all of this: `nish/net/fetch`'s
2254
2317
  response's head is in and answers it with `body.readAll(limit)`, or null on a
2255
2318
  failure (a `FetchSyncClient` keeps the connection and says why in `error`).
2256
2319
  `netRead` / `netWrite` panic on a range outside the buffer.
2320
+ `netWrite2(fd, a, aOff, aLen, b, bOff, bLen)` writes two ranges in one
2321
+ `sendmsg` (a header and a body without a copy) and answers the bytes written,
2322
+ which may stop inside either range; it checks both ranges, the first one first.
2257
2323
  `tcpListenFlags(host, port, backlog, flags)` is `tcpListen` with flag 1
2258
2324
  `SO_REUSEPORT`, so several listeners, in one process or many, share a port (Linux
2259
2325
  spreads the connections), and flag 2 `TCP_NODELAY` on every socket `tcpAccept`
@@ -2796,13 +2862,16 @@ or `PG_LOST` to `fail(run)` (on a spent handle these do nothing and count in
2796
2862
  `stray`), and after each call `next(run)` until
2797
2863
  `PG_BATCH_NONE`: `PG_BATCH_ROW` (the connection's row answers request `tag`),
2798
2864
  then one of `PG_BATCH_DONE`, `PG_BATCH_MISSING` or `PG_BATCH_FAILED` per
2799
- request. It reads no clock: when to take is the loop's choice, or a `PgBatchClock`'s (`PgBatchClockConfig`: `minCount`, `factor` × the moving average of batch sizes, `maxWaitUs`, the idle bypass `lightCount`; defaults are a fixed window), which `takeDue(conn, clock, nowUs, pool.inFlight())` consults after `clock.arrived(nowUs)` per add; `PgBatchTurns` wakes one collecting connection only when its batch is due. (No block;
2865
+ request. `sorted = false` drops `q.ord` from the statement's `order by` (and
2866
+ its Sort node, with `orderBy` empty): rows route as they come, and every last
2867
+ event waits for `end`. The batcher reads no clock: when to take is the loop's choice, or a `PgBatchClock`'s (`PgBatchClockConfig`: `minCount`, `factor` × the moving average of batch sizes, `maxWaitUs`, the idle bypass `lightCount`; defaults are a fixed window), which `takeDue(conn, clock, nowUs, pool.inFlight())` consults after `clock.arrived(nowUs)` per add; `PgBatchTurns` wakes one collecting connection only when its batch is due. (No block;
2800
2868
  `tests/postgres/live`'s `batch` scenario runs it against a server, and the user
2801
2869
  guide's [PostgreSQL page](guide/using-nish/postgres.md#batching-keyed-reads)
2802
2870
  its walk-through.)
2803
2871
 
2804
2872
  **Call another service from a route handler** — there is no `await fetch()`
2805
- in a handler and no event-loop callback: `nish/net/upstream`'s `Upstream(h,
2873
+ in a handler (an `async` task does not wait on a socket yet) and no event-loop
2874
+ callback: `nish/net/upstream`'s `Upstream(h,
2806
2875
  origin, limits)` is a pool of keep-alive connections to one `http:` origin on
2807
2876
  the `HttpHandler`'s own loop. `users.get(req, path)` returns at once — test it
2808
2877
  for `UPSTREAM_E_FULL`, which holds nothing — and keeps `req` held; after each
@@ -2857,9 +2926,10 @@ export const main = (): i32 => {
2857
2926
 
2858
2927
  **Optional parameters** — write a default instead: `(n: i32 = 1)`. A default
2859
2928
  is a literal, an enum member or an earlier parameter, and the call site fills
2860
- it in. `x?: T` is refused. A variable count of one type is a rest parameter,
2861
- `(...ns: i32[])`, last in the list; a call never spreads (`f(...xs)`), it passes
2862
- `xs` to an array parameter.
2929
+ it in. An options argument is `(opts: Options | null = null)`: `null` is the
2930
+ one default of a `T | null` parameter. `x?: T` is refused. A variable count
2931
+ of one type is a rest parameter, `(...ns: i32[])`, last in the list; a call
2932
+ never spreads (`f(...xs)`), it passes `xs` to an array parameter.
2863
2933
 
2864
2934
  **A calendar, regex, JSON, threads of your own** — not in the language (the
2865
2935
  wall clock is `Date.now()`, and that is all of `Date`). Say so rather than
@@ -2956,8 +3026,8 @@ export const first = (xs: i32[]): i32 => uncheckedGet(xs, 0);
2956
3026
  A package that must not touch the network says so in `package.json`,
2957
3027
  `"nish": { "capabilities": { "deny": ["net"] } }`, and `--deny net` or an
2958
3028
  allowlist such as `--allow fs.read,exit` says the same on the command line.
2959
- The `"nish"` field holds `noPanic` and `capabilities` and nothing else, each
2960
- written once; anything more is refused (NL3036) rather than skipped. A
3029
+ The `"nish"` field holds `noPanic`, `capabilities` and `host` and nothing
3030
+ else, each written once; anything more is refused (NL3036) rather than skipped. A
2961
3031
  program whose `main` — or, in a library or a header build, any export —
2962
3032
  reaches more is refused (NL2459), spanned at the first call and naming the
2963
3033
  whole chain to the builtin; nothing changes in a program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amritk/nish-aarch64-darwin",
3
- "version": "0.34.1",
3
+ "version": "0.36.0",
4
4
  "description": "The nish native compiler for macOS on ARM64",
5
5
  "license": "MIT",
6
6
  "os": [
@@ -0,0 +1,49 @@
1
+ // The declarations of `runtime/async.mjs`, `nish:async` under Node.
2
+
3
+ /** Starts `task` without waiting for it; the launcher waits before it exits. */
4
+ export declare function spawn(task: Promise<void>): void;
5
+ /** Every task's answer, in the order the calls are written, once all of them finish. */
6
+ export declare function awaitAll<A, B>(a: Promise<A>, b: Promise<B>): Promise<[A, B]>;
7
+ export declare function awaitAll<A, B, C>(a: Promise<A>, b: Promise<B>, c: Promise<C>): Promise<[A, B, C]>;
8
+ export declare function awaitAll<A, B, C, D>(
9
+ a: Promise<A>,
10
+ b: Promise<B>,
11
+ c: Promise<C>,
12
+ d: Promise<D>,
13
+ ): Promise<[A, B, C, D]>;
14
+ export declare function awaitAll<A, B, C, D, E>(
15
+ a: Promise<A>,
16
+ b: Promise<B>,
17
+ c: Promise<C>,
18
+ d: Promise<D>,
19
+ e: Promise<E>,
20
+ ): Promise<[A, B, C, D, E]>;
21
+ export declare function awaitAll<A, B, C, D, E, F>(
22
+ a: Promise<A>,
23
+ b: Promise<B>,
24
+ c: Promise<C>,
25
+ d: Promise<D>,
26
+ e: Promise<E>,
27
+ f: Promise<F>,
28
+ ): Promise<[A, B, C, D, E, F]>;
29
+ export declare function awaitAll<A, B, C, D, E, F, G>(
30
+ a: Promise<A>,
31
+ b: Promise<B>,
32
+ c: Promise<C>,
33
+ d: Promise<D>,
34
+ e: Promise<E>,
35
+ f: Promise<F>,
36
+ g: Promise<G>,
37
+ ): Promise<[A, B, C, D, E, F, G]>;
38
+ export declare function awaitAll<A, B, C, D, E, F, G, H>(
39
+ a: Promise<A>,
40
+ b: Promise<B>,
41
+ c: Promise<C>,
42
+ d: Promise<D>,
43
+ e: Promise<E>,
44
+ f: Promise<F>,
45
+ g: Promise<G>,
46
+ h: Promise<H>,
47
+ ): Promise<[A, B, C, D, E, F, G, H]>;
48
+ /** Waits for every task `spawn` started, the tasks those tasks start included. */
49
+ export declare function settleTasks(): Promise<void>;
@@ -0,0 +1,27 @@
1
+ // `nish:async` under Node (WP49): what `nish --emit-ts` writes an async
2
+ // program against, and what `runtime/nish.mjs` answers `nish:async` with. A
3
+ // file of its own, not `nish/runtime`, because `nish:process` has a `spawn`
4
+ // there already.
5
+ //
6
+ // `awaitAll` is `Promise.all` over its two to eight tasks. `spawn` starts a
7
+ // task without awaiting it and keeps it, so the launcher's `settleTasks` waits
8
+ // for every task started before the process exits, as the native driver
9
+ // drains its queue after `main` answers. Node runs a task only until its first
10
+ // `await` where native runs it until it first waits, so spawned tasks may print
11
+ // in another order (`docs/RUN_UNDER_NODE.md`). A task that throws is Node's
12
+ // unhandled rejection, which exits 1 as a native panic does.
13
+
14
+ const pending = [];
15
+
16
+ export const spawn = (task) => {
17
+ pending.push(task);
18
+ };
19
+
20
+ export const awaitAll = (...tasks) => Promise.all(tasks);
21
+
22
+ export const settleTasks = async () => {
23
+ for (let i = 0; i < pending.length; i++) {
24
+ await pending[i];
25
+ }
26
+ pending.length = 0;
27
+ };