@amritk/nish-aarch64-darwin 0.35.0 → 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 (119) hide show
  1. package/INSTALL.md +6 -1
  2. package/bin/nish +0 -0
  3. package/docs/AI.md +9 -2
  4. package/package.json +1 -1
  5. package/runtime/nish.d.ts +4612 -430
  6. package/runtime/vite.d.ts +30 -0
  7. package/runtime/vite.mjs +150 -0
  8. package/scripts/build.sh +108 -13
  9. package/std/base64.ts +34 -5
  10. package/std/bytes.ts +256 -40
  11. package/std/cli-args.ts +296 -70
  12. package/std/cli-flags.ts +184 -19
  13. package/std/cli.ts +475 -54
  14. package/std/collections.ts +121 -23
  15. package/std/compress/checksum.ts +44 -14
  16. package/std/compress/deflate.ts +224 -111
  17. package/std/compress/gzip.ts +217 -53
  18. package/std/compress/zlib.ts +63 -7
  19. package/std/crypto/aes.ts +80 -9
  20. package/std/crypto/base64url.ts +22 -0
  21. package/std/crypto/bcrypt-batch.ts +88 -21
  22. package/std/crypto/bcrypt.ts +60 -0
  23. package/std/crypto/chacha20poly1305.ts +53 -0
  24. package/std/crypto/ct.ts +32 -13
  25. package/std/crypto/ed25519.ts +47 -0
  26. package/std/crypto/hkdf.ts +198 -13
  27. package/std/crypto/hmac.ts +235 -31
  28. package/std/crypto/jwt.ts +192 -63
  29. package/std/crypto/p256.ts +159 -16
  30. package/std/crypto/p384.ts +28 -3
  31. package/std/crypto/pki-roots.ts +32 -2
  32. package/std/crypto/pki.ts +81 -15
  33. package/std/crypto/rsa.ts +33 -3
  34. package/std/crypto/sha1.ts +3 -0
  35. package/std/crypto/sha256.ts +24 -1
  36. package/std/crypto/sha512.ts +99 -14
  37. package/std/crypto/x25519.ts +152 -14
  38. package/std/crypto/x509-random.ts +10 -0
  39. package/std/crypto/x509.ts +67 -7
  40. package/std/json-equal.ts +19 -0
  41. package/std/json-format.ts +112 -13
  42. package/std/json-number.ts +64 -14
  43. package/std/json-pointer.ts +23 -1
  44. package/std/json-tokenizer.ts +100 -29
  45. package/std/json-typed.ts +713 -66
  46. package/std/json-value.ts +400 -124
  47. package/std/json.ts +138 -10
  48. package/std/map.ts +25 -7
  49. package/std/math.ts +36 -4
  50. package/std/net/buffer-pool.ts +42 -11
  51. package/std/net/dns-config.ts +109 -23
  52. package/std/net/dns-message.ts +62 -7
  53. package/std/net/dns-resolver.ts +247 -53
  54. package/std/net/dns.ts +203 -35
  55. package/std/net/fetch.ts +151 -61
  56. package/std/net/handler.ts +278 -80
  57. package/std/net/hpack.ts +262 -52
  58. package/std/net/http-compress.ts +125 -15
  59. package/std/net/http-fields.ts +85 -9
  60. package/std/net/http1-client-codec.ts +100 -19
  61. package/std/net/http1-codec.ts +235 -27
  62. package/std/net/http1-server.ts +343 -85
  63. package/std/net/http2-frame.ts +272 -35
  64. package/std/net/http2-tls.ts +135 -34
  65. package/std/net/http2.ts +247 -106
  66. package/std/net/http3-frame.ts +154 -17
  67. package/std/net/http3-server.ts +246 -96
  68. package/std/net/http3.ts +307 -115
  69. package/std/net/outbound.ts +37 -3
  70. package/std/net/postgres-carrier.ts +144 -8
  71. package/std/net/postgres.ts +723 -103
  72. package/std/net/prefork.ts +164 -31
  73. package/std/net/qpack.ts +105 -18
  74. package/std/net/quic-conn-ack.ts +59 -12
  75. package/std/net/quic-conn-cid.ts +124 -27
  76. package/std/net/quic-conn-params.ts +70 -10
  77. package/std/net/quic-datagram.ts +43 -3
  78. package/std/net/quic-frame.ts +286 -12
  79. package/std/net/quic-listener.ts +101 -32
  80. package/std/net/quic-packet.ts +302 -21
  81. package/std/net/quic-recovery.ts +228 -44
  82. package/std/net/quic-stream.ts +353 -91
  83. package/std/net/quic.ts +489 -171
  84. package/std/net/router.ts +87 -40
  85. package/std/net/tls/client.ts +166 -51
  86. package/std/net/tls/codec.ts +413 -56
  87. package/std/net/tls/record-client.ts +110 -55
  88. package/std/net/tls/record-server.ts +159 -59
  89. package/std/net/tls/record.ts +109 -12
  90. package/std/net/tls/schedule.ts +235 -26
  91. package/std/net/tls/ticket.ts +159 -40
  92. package/std/net/tls/verify.ts +49 -3
  93. package/std/net/tls-tcp.ts +250 -45
  94. package/std/net/tls.ts +221 -59
  95. package/std/net/upstream.ts +81 -45
  96. package/std/net/url.ts +97 -13
  97. package/std/net/websocket.ts +122 -12
  98. package/std/net/webtransport.ts +220 -89
  99. package/std/pair.ts +10 -2
  100. package/std/random.ts +34 -9
  101. package/std/regex.ts +352 -198
  102. package/std/region.ts +70 -15
  103. package/std/secret.ts +52 -11
  104. package/std/sort.ts +17 -2
  105. package/std/sqlite.ts +256 -35
  106. package/std/sync/ring.ts +205 -35
  107. package/std/sync/shm.ts +194 -16
  108. package/std/term-io.ts +137 -64
  109. package/std/term-pixels.ts +144 -19
  110. package/std/term-probe.ts +66 -25
  111. package/std/term-rate.ts +128 -57
  112. package/std/term.ts +332 -121
  113. package/std/testing.ts +130 -32
  114. package/std/text.ts +73 -7
  115. package/std/threads.ts +229 -41
  116. package/std/yaml-json.ts +94 -82
  117. package/std/yaml-lines.ts +47 -15
  118. package/std/yaml-write.ts +24 -16
  119. package/std/yaml.ts +764 -384
@@ -4,12 +4,17 @@
4
4
  * messages into an output buffer and reads the backend's from an input
5
5
  * buffer, for a program that owns its socket (`nish:net`) and its loop.
6
6
  *
7
+ * import { PG_FAILED, PG_NEED_MORE, PgConfig, PgConnection } from "nish/net/postgres";
8
+ * import { secret, wipe } from "nish:secret";
9
+ *
7
10
  * const config = new PgConfig();
8
11
  * config.user = "app";
9
12
  * config.database = "app";
10
13
  * const nonce = new Array<u8>(18);
11
14
  * crypto.getRandomValues(nonce);
15
+ * const password = secret(passwordBytes); // a u8[] the program read from its secret store
12
16
  * const conn = new PgConnection(config, password, nonce);
17
+ * wipe(password); // the connection keeps its own copy
13
18
  * // write conn.outputBuffer()[conn.outputStart() .. conn.outputEnd()), then conn.sent(n)
14
19
  * // read into conn.inputBuffer() at conn.inputEnd(), up to conn.inputRoom() bytes, then conn.received(n)
15
20
  * let event: i32 = conn.next();
@@ -334,7 +339,11 @@ export class PgConfig {
334
339
 
335
340
  /** A server's ErrorResponse or NoticeResponse: the fields a program acts on. */
336
341
  export class PgError {
337
- /** ERROR, FATAL or PANIC; WARNING, NOTICE, DEBUG, INFO or LOG for a notice. Never localised. */
342
+ /**
343
+ * ERROR, FATAL or PANIC; WARNING, NOTICE, DEBUG, INFO or LOG for a notice.
344
+ * Never localised, unless the server sent no `V` field (before 9.6) and the
345
+ * localised `S` field stands in for it.
346
+ */
338
347
  readonly severity: string
339
348
  /** The SQLSTATE, five characters: `23505` is a unique violation. */
340
349
  readonly code: string
@@ -349,6 +358,19 @@ export class PgError {
349
358
  /** The 1-based character position in the statement's text, or "". */
350
359
  readonly position: string
351
360
 
361
+ /**
362
+ * Builds the record from the fields of one ErrorResponse or
363
+ * NoticeResponse; a program reads it from `lastError` or `lastNotice`
364
+ * rather than building one.
365
+ * @param severity The `V` field, never localised; the `S` field, which may be
366
+ * localised, when the server sent no `V` (servers before 9.6).
367
+ * @param code The SQLSTATE, the `C` field.
368
+ * @param message The primary message, the `M` field.
369
+ * @param detail The `D` field, or "" when the server sent none.
370
+ * @param hint The `H` field, or "".
371
+ * @param constraint The `n` field, or "".
372
+ * @param position The `P` field, a 1-based character position as text, or "".
373
+ */
352
374
  constructor(
353
375
  severity: string,
354
376
  code: string,
@@ -390,19 +412,25 @@ const pgAllZero = (bytes: u8[]): boolean => {
390
412
  * The holder outlives the wipe, so that `wiped()` reads the very bytes.
391
413
  */
392
414
  class PgPassword {
415
+ /** @internal Used by `PgConnection.scramContinue` and `PgPool.connect` in this module. */
393
416
  readonly bytes: Secret<u8[]>
394
- /** Whether `wipe()` has run; the bytes are no longer a password. */
417
+ /**
418
+ * Whether `wipe()` has run; the bytes are no longer a password.
419
+ * @internal Used by `PgConnection.dispose`, `PgConnection.scramContinue`, `PgPool.connect` and `PgPool.dispose` in this module.
420
+ */
395
421
  gone: boolean = false
396
422
 
397
423
  constructor(password: Secret<u8[]>) {
398
424
  this.bytes = secret(expose(password, pgCopyBytes))
399
425
  }
400
426
 
427
+ /** @internal Used by `PgConnection.dispose` and `PgPool.dispose` in this module. */
401
428
  wipe(): void {
402
429
  wipe(this.bytes)
403
430
  this.gone = true
404
431
  }
405
432
 
433
+ /** @internal Used by `PgConnection.passwordWiped` and `PgPool.passwordWiped` in this module. */
406
434
  wiped(): boolean {
407
435
  return expose(this.bytes, pgAllZero)
408
436
  }
@@ -669,7 +697,15 @@ export class PgText {
669
697
  this.failed = false
670
698
  }
671
699
 
672
- /** An `int2`, `int4` or `int8` column: an optional `-` and 1 to 19 digits; 0 and `failed` otherwise, and on overflow. */
700
+ /**
701
+ * An `int2`, `int4` or `int8` column: an optional `-` and its digits, in
702
+ * place. Leading zeros are allowed; a value outside `i64` is an overflow.
703
+ * @param b The buffer the column lies in, usually `conn.inputBuffer()`.
704
+ * @param start The column's first byte, as `colStart(c)` gives it.
705
+ * @param length The column's length in bytes; NULL's -1 is refused.
706
+ * @returns The value, or 0 with `failed` set for an empty or out-of-range
707
+ * window, a byte that is not a digit, or an overflow.
708
+ */
673
709
  int(b: u8[], start: i32, length: i32): i64 {
674
710
  const end: i32 = start + length
675
711
  if (length <= 0 || start < 0 || end < start || end > toI32(b.length)) {
@@ -707,7 +743,13 @@ export class PgText {
707
743
  return negative ? acc : -acc
708
744
  }
709
745
 
710
- /** A `bool` column: `t` or `f`; false and `failed` otherwise. */
746
+ /**
747
+ * A `bool` column: `t` or `f`, in place.
748
+ * @param b The buffer the column lies in.
749
+ * @param start The column's first byte.
750
+ * @param length The column's length in bytes; anything but 1 is refused.
751
+ * @returns True for `t`, false for `f`; false with `failed` set otherwise.
752
+ */
711
753
  bool(b: u8[], start: i32, length: i32): boolean {
712
754
  if (length === 1 && start >= 0 && start < toI32(b.length)) {
713
755
  const c: i32 = toI32(b[start])
@@ -728,7 +770,14 @@ export class PgText {
728
770
  * `timestamp` column (the same without `+00`), written to `out[at, at + 24)`
729
771
  * as `2024-01-02T03:04:05.123Z`, the fraction cut to milliseconds. Answers
730
772
  * 24, or -1 and `failed` for anything else: a year outside 0001–9999, BC,
731
- * `infinity`, an offset other than `+00`.
773
+ * `infinity`, an offset other than `+00`. Nothing is allocated.
774
+ * @param b The buffer the column lies in.
775
+ * @param start The column's first byte.
776
+ * @param length The column's length in bytes, at least 19.
777
+ * @param out The buffer to write the 24 ISO 8601 bytes into; the caller owns it.
778
+ * @param at Where in `out` the time starts; `out` needs 24 bytes from there.
779
+ * @returns 24, the bytes written; -1 with `failed` set, and `out` untouched,
780
+ * for a column it does not read or no room in `out`.
732
781
  */
733
782
  timestamp(b: u8[], start: i32, length: i32, out: u8[], at: i32): i32 {
734
783
  if (
@@ -854,6 +903,10 @@ export class PgBinary {
854
903
  * bytes, big-endian two's complement); 0 and `failed` for any other length,
855
904
  * NULL's -1 among them. A `timestamptz` or `timestamp` reads as an `int8`:
856
905
  * microseconds since 2000-01-01 00:00:00 UTC, which `iso` writes out.
906
+ * @param b The buffer the column lies in, usually `conn.inputBuffer()`.
907
+ * @param start The column's first byte, as `colStart(c)` gives it.
908
+ * @param length The column's length in bytes: 2, 4 or 8.
909
+ * @returns The value, sign-extended to 64 bits, or 0 with `failed` set.
857
910
  */
858
911
  int(b: u8[], start: i32, length: i32): i64 {
859
912
  if ((length !== 2 && length !== 4 && length !== 8) || !this.inside(b, start, length)) {
@@ -870,7 +923,13 @@ export class PgBinary {
870
923
  return toI64(v >= 32768 ? v - 65536 : v)
871
924
  }
872
925
 
873
- /** A `bool` column: one byte, 1 or 0; false and `failed` otherwise. */
926
+ /**
927
+ * A `bool` column: one byte, 1 or 0.
928
+ * @param b The buffer the column lies in.
929
+ * @param start The column's first byte.
930
+ * @param length The column's length in bytes; anything but 1 is refused.
931
+ * @returns True for 1, false for 0; false with `failed` set otherwise.
932
+ */
874
933
  bool(b: u8[], start: i32, length: i32): boolean {
875
934
  if (length === 1 && this.inside(b, start, length)) {
876
935
  const c: i32 = toI32(b[start])
@@ -885,7 +944,15 @@ export class PgBinary {
885
944
  return false
886
945
  }
887
946
 
888
- /** A `float8` column: eight bytes, IEEE 754 big-endian; 0 and `failed` otherwise. */
947
+ /**
948
+ * A `float8` column: eight bytes, IEEE 754 big-endian. A `float4` (four
949
+ * bytes) is refused.
950
+ * @param b The buffer the column lies in.
951
+ * @param start The column's first byte.
952
+ * @param length The column's length in bytes; anything but 8 is refused.
953
+ * @returns The value, NaN and the infinities included; 0 with `failed` set
954
+ * for a column that is not eight bytes inside `b`.
955
+ */
889
956
  float(b: u8[], start: i32, length: i32): f64 {
890
957
  if (length !== 8 || !this.inside(b, start, length)) {
891
958
  this.failed = true
@@ -898,6 +965,12 @@ export class PgBinary {
898
965
  * A `timestamptz` or `timestamp` column, written to `out[at, at + 24)` as
899
966
  * `iso` writes it. Answers 24, or -1 and `failed` for a column that is not
900
967
  * eight bytes or a time `iso` refuses.
968
+ * @param b The buffer the column lies in.
969
+ * @param start The column's first byte.
970
+ * @param length The column's length in bytes; anything but 8 is refused.
971
+ * @param out The buffer to write the 24 ISO 8601 bytes into; the caller owns it.
972
+ * @param at Where in `out` the time starts; `out` needs 24 bytes from there.
973
+ * @returns 24, the bytes written, or -1 with `failed` set.
901
974
  */
902
975
  timestamp(b: u8[], start: i32, length: i32, out: u8[], at: i32): i32 {
903
976
  if (length !== 8 || !this.inside(b, start, length)) {
@@ -913,6 +986,11 @@ export class PgBinary {
913
986
  * not rounded, to milliseconds, as `PgText.timestamp` cuts the same time.
914
987
  * Answers 24, or -1 and `failed` with `out` untouched for a year outside
915
988
  * 0001–9999 (`infinity` and `-infinity` among them) or no room in `out`.
989
+ * Nothing is allocated.
990
+ * @param micros Microseconds since 2000-01-01 00:00:00 UTC; negative is before 2000.
991
+ * @param out The buffer to write into; the caller owns it.
992
+ * @param at Where in `out` the time starts; `out` needs 24 bytes from there.
993
+ * @returns 24, the bytes written, or -1 with `failed` set.
916
994
  */
917
995
  iso(micros: i64, out: u8[], at: i32): i32 {
918
996
  if (at < 0 || at > toI32(out.length) - 24) {
@@ -980,9 +1058,9 @@ export class PgBinaryArray {
980
1058
  /** The element type's OID, 20, 21 or 23, once `begin` has read a header it accepts. */
981
1059
  elementOid: i32 = 0
982
1060
  /** The current element's first byte in the buffer. */
983
- start: i32 = 0
1061
+ private start: i32 = 0
984
1062
  /** The current element's length: its type's size, or 0 for a NULL. */
985
- length: i32 = 0
1063
+ private length: i32 = 0
986
1064
  private binary: PgBinary
987
1065
  private b: u8[]
988
1066
  private pos: i32 = 0
@@ -992,12 +1070,26 @@ export class PgBinaryArray {
992
1070
  private hasNull: boolean = false
993
1071
  private bad: boolean = true
994
1072
 
1073
+ /**
1074
+ * A walker with nothing begun; `next()` answers `PG_ARRAY_BAD` until `begin`.
1075
+ * @param binary The decoders `int()` reads through and whose `failed` every
1076
+ * refusal sets; usually `conn.binary`.
1077
+ */
995
1078
  constructor(binary: PgBinary) {
996
1079
  this.binary = binary
997
1080
  this.b = []
998
1081
  }
999
1082
 
1000
- /** Starts a walk over `b[start, start + length)`; a header this walker does not read is refused. */
1083
+ /**
1084
+ * Starts a walk over `b[start, start + length)`, reading its header; a
1085
+ * header this walker does not read is refused, which sets `binary.failed`
1086
+ * and makes `next()` answer `PG_ARRAY_BAD`. The walker keeps `b` and reads
1087
+ * it until the next `begin`, so the window must stay valid that long: for a
1088
+ * column, until the connection's next `next()`.
1089
+ * @param b The buffer the column lies in, usually `conn.inputBuffer()`.
1090
+ * @param start The column's first byte, as `colStart(c)` gives it.
1091
+ * @param length The column's length in bytes; NULL's -1 is refused.
1092
+ */
1001
1093
  begin(b: u8[], start: i32, length: i32): void {
1002
1094
  this.b = b
1003
1095
  this.count = 0
@@ -1050,7 +1142,13 @@ export class PgBinaryArray {
1050
1142
  return PG_ARRAY_BAD
1051
1143
  }
1052
1144
 
1053
- /** The next element: `PG_ARRAY_ELEMENT`, `PG_ARRAY_NULL`, `PG_ARRAY_END` or `PG_ARRAY_BAD`. */
1145
+ /**
1146
+ * Steps to the next element, which `int()` then reads.
1147
+ * @returns `PG_ARRAY_ELEMENT`, `PG_ARRAY_NULL`, `PG_ARRAY_END` once all
1148
+ * `count` elements have been read and the column ends there, or
1149
+ * `PG_ARRAY_BAD` (with `binary.failed` set) for a layout it refuses; a
1150
+ * refused walk answers `PG_ARRAY_BAD` from then on.
1151
+ */
1054
1152
  next(): i32 {
1055
1153
  if (this.bad) {
1056
1154
  return PG_ARRAY_BAD
@@ -1084,7 +1182,13 @@ export class PgBinaryArray {
1084
1182
  return PG_ARRAY_ELEMENT
1085
1183
  }
1086
1184
 
1087
- /** The current element as an integer, through `PgBinary.int`; a NULL, or a walk that was refused, sets `binary.failed`. */
1185
+ /**
1186
+ * The current element as an integer, through `PgBinary.int`; a NULL, or a
1187
+ * walk that was refused, sets `binary.failed`.
1188
+ * @returns The element, sign-extended to 64 bits, or 0 when this call is
1189
+ * refused, which sets `binary.failed`. The flag is sticky and shared, so
1190
+ * an earlier refusal leaves it set without making this call answer 0.
1191
+ */
1088
1192
  int(): i64 {
1089
1193
  if (this.bad) {
1090
1194
  this.binary.failed = true
@@ -1095,7 +1199,7 @@ export class PgBinaryArray {
1095
1199
  }
1096
1200
 
1097
1201
  /**
1098
- * A walk over a one-dimensional `text[]` column in place: `start` the
1202
+ * A walk over a one-dimensional `text[]` column in place: `begin` the
1099
1203
  * column, then `next()` until `PG_ARRAY_END` or `PG_ARRAY_BAD`. Each element
1100
1204
  * is the window `[start, start + length)` of the column's buffer; a quoted
1101
1205
  * element with a backslash escape in it has `escaped` set, and `copy` writes
@@ -1115,11 +1219,20 @@ export class PgArrayWalker {
1115
1219
  private bad: boolean = false
1116
1220
  private b: u8[]
1117
1221
 
1222
+ /** A walker with nothing begun; `next()` answers `PG_ARRAY_END` until `begin`. */
1118
1223
  constructor() {
1119
1224
  this.b = []
1120
1225
  }
1121
1226
 
1122
- /** Starts a walk over `b[start, start + length)`. */
1227
+ /**
1228
+ * Starts a walk over `b[start, start + length)`, which must be a `{...}`
1229
+ * literal; anything else makes `next()` answer `PG_ARRAY_BAD`. The walker
1230
+ * keeps `b` and reads it until the next `begin`, so for a column the walk
1231
+ * must end before the connection's next `next()`.
1232
+ * @param b The buffer the column lies in, usually `conn.inputBuffer()`.
1233
+ * @param start The column's first byte, as `colStart(c)` gives it.
1234
+ * @param length The column's length in bytes, braces included.
1235
+ */
1123
1236
  begin(b: u8[], start: i32, length: i32): void {
1124
1237
  this.b = b
1125
1238
  this.first = true
@@ -1136,7 +1249,12 @@ export class PgArrayWalker {
1136
1249
  return PG_ARRAY_BAD
1137
1250
  }
1138
1251
 
1139
- /** The next element: `PG_ARRAY_ELEMENT`, `PG_ARRAY_NULL`, `PG_ARRAY_END` or `PG_ARRAY_BAD`. */
1252
+ /**
1253
+ * Steps to the next element, setting `start`, `length` and `escaped`.
1254
+ * @returns `PG_ARRAY_ELEMENT`, `PG_ARRAY_NULL`, `PG_ARRAY_END` or
1255
+ * `PG_ARRAY_BAD`; once `PG_ARRAY_BAD`, the walk answers it until the next
1256
+ * `begin`.
1257
+ */
1140
1258
  next(): i32 {
1141
1259
  if (this.bad) {
1142
1260
  return PG_ARRAY_BAD
@@ -1210,7 +1328,14 @@ export class PgArrayWalker {
1210
1328
  return PG_ARRAY_ELEMENT
1211
1329
  }
1212
1330
 
1213
- /** Writes the current element, unescaped, to `out[at, ...)`; answers its length, or -1 when it does not fit. */
1331
+ /**
1332
+ * Writes the current element, unescaped (each backslash dropped and the
1333
+ * byte after it kept), to `out[at, ...)`. Nothing is allocated.
1334
+ * @param out The buffer to write into; the caller owns it.
1335
+ * @param at Where in `out` the element starts.
1336
+ * @returns The bytes written, at most `length`; -1 when it does not fit,
1337
+ * in which case `out` may hold part of it.
1338
+ */
1214
1339
  copy(out: u8[], at: i32): i32 {
1215
1340
  const b: u8[] = this.b
1216
1341
  let n: i32 = 0
@@ -1307,7 +1432,14 @@ export class PgConnection {
1307
1432
  * A connection that has queued its startup message. `password` is copied,
1308
1433
  * so the caller may wipe its own; `nonce` must be at least 18 bytes from a
1309
1434
  * cryptographic random source (`crypto.getRandomValues`), and is fixed only
1310
- * in a test.
1435
+ * in a test. Panics on a `PgConfig` that is a mistake (no user, a cap out
1436
+ * of range, a NUL in a startup parameter) or a nonce shorter than 18 bytes.
1437
+ * @param config The caps and startup parameters; kept, and read for the
1438
+ * connection's life, so do not change it afterwards.
1439
+ * @param password The role's password as UTF-8 bytes, without SASLprep;
1440
+ * copied into a holder the connection wipes once the SCRAM proof is
1441
+ * computed, or when it fails or is disposed. It may be empty for `trust`.
1442
+ * @param nonce The client nonce: its first 18 bytes are used, base64-encoded.
1311
1443
  */
1312
1444
  constructor(config: PgConfig, password: Secret<u8[]>, nonce: u8[]) {
1313
1445
  if (toI32(nonce.length) < PG_NONCE_BYTES) {
@@ -1354,22 +1486,38 @@ export class PgConnection {
1354
1486
 
1355
1487
  // --- Buffers -----------------------------------------------------------------
1356
1488
 
1357
- /** The input buffer: read from the socket into it at `inputEnd()`. */
1489
+ /**
1490
+ * The input buffer: read from the socket into it at `inputEnd()`. The
1491
+ * connection owns it, and `next()` may replace it with a larger one, so
1492
+ * fetch it again after every `next()`.
1493
+ * @returns The buffer itself, not a copy.
1494
+ */
1358
1495
  inputBuffer(): u8[] {
1359
1496
  return this.input
1360
1497
  }
1361
1498
 
1362
- /** Where the next byte read goes. */
1499
+ /**
1500
+ * Where the next byte read goes.
1501
+ * @returns An index into `inputBuffer()`.
1502
+ */
1363
1503
  inputEnd(): i32 {
1364
1504
  return this.inEnd
1365
1505
  }
1366
1506
 
1367
- /** How many bytes may be read into the input buffer now. */
1507
+ /**
1508
+ * How many bytes may be read into the input buffer now.
1509
+ * @returns The bytes free from `inputEnd()` to the buffer's end; 0 when it
1510
+ * is full, which `next()` mends by compacting or growing it.
1511
+ */
1368
1512
  inputRoom(): i32 {
1369
1513
  return toI32(this.input.length) - this.inEnd
1370
1514
  }
1371
1515
 
1372
- /** Records that `n` bytes were read into the input buffer at `inputEnd()`. */
1516
+ /**
1517
+ * Records that `n` bytes were read into the input buffer at `inputEnd()`.
1518
+ * Panics on a negative `n` or one past `inputRoom()`.
1519
+ * @param n The bytes the read wrote, from 0 to `inputRoom()`.
1520
+ */
1373
1521
  received(n: i32): void {
1374
1522
  if (n < 0 || n > this.inputRoom()) {
1375
1523
  panic("nish/net/postgres: received more than inputRoom()")
@@ -1377,7 +1525,16 @@ export class PgConnection {
1377
1525
  this.inEnd += n
1378
1526
  }
1379
1527
 
1380
- /** Copies what fits of `src[start, start + length)` into the input buffer; answers how much. */
1528
+ /**
1529
+ * Copies what fits of `src[start, start + length)` into the input buffer at
1530
+ * `inputEnd()`, for a program whose bytes arrive in a buffer of its own.
1531
+ * Panics on a window outside `src`.
1532
+ * @param src The bytes to take; the caller keeps them.
1533
+ * @param start The window's first byte in `src`.
1534
+ * @param length The window's length in bytes.
1535
+ * @returns The bytes copied, at most `inputRoom()`; the rest are the
1536
+ * caller's to give again after `next()`.
1537
+ */
1381
1538
  receive(src: u8[], start: i32, length: i32): i32 {
1382
1539
  if (start < 0 || length < 0 || length > toI32(src.length) - start) {
1383
1540
  panic("nish/net/postgres: receive() outside its source")
@@ -1389,22 +1546,39 @@ export class PgConnection {
1389
1546
  return n
1390
1547
  }
1391
1548
 
1392
- /** The output buffer: write `[outputStart(), outputEnd())` to the socket. */
1549
+ /**
1550
+ * The output buffer: write `[outputStart(), outputEnd())` to the socket.
1551
+ * The connection owns it, and a builder call or `sent` may grow or compact
1552
+ * it, so fetch it again after each.
1553
+ * @returns The buffer itself, not a copy.
1554
+ */
1393
1555
  outputBuffer(): u8[] {
1394
1556
  return this.out
1395
1557
  }
1396
1558
 
1397
- /** The first byte not yet sent. */
1559
+ /**
1560
+ * The first byte not yet sent.
1561
+ * @returns An index into `outputBuffer()`.
1562
+ */
1398
1563
  outputStart(): i32 {
1399
1564
  return this.outStart
1400
1565
  }
1401
1566
 
1402
- /** One past the last byte that may be sent: a Bind still open is held back until `bindEnd()` has written its lengths. */
1567
+ /**
1568
+ * One past the last byte that may be sent: a Bind still open is held back
1569
+ * until `bindEnd()` has written its lengths.
1570
+ * @returns An index into `outputBuffer()`; equal to `outputStart()` when
1571
+ * there is nothing to send.
1572
+ */
1403
1573
  outputEnd(): i32 {
1404
1574
  return this.bindAt >= 0 ? this.bindAt : this.outEnd
1405
1575
  }
1406
1576
 
1407
- /** Records that `n` bytes from `outputStart()` were written to the socket. */
1577
+ /**
1578
+ * Records that `n` bytes from `outputStart()` were written to the socket.
1579
+ * Panics on a negative `n` or one past `outputEnd() - outputStart()`.
1580
+ * @param n The bytes the write took.
1581
+ */
1408
1582
  sent(n: i32): void {
1409
1583
  if (n < 0 || n > this.outputEnd() - this.outStart) {
1410
1584
  panic("nish/net/postgres: sent more than was queued")
@@ -1418,7 +1592,12 @@ export class PgConnection {
1418
1592
  }
1419
1593
  }
1420
1594
 
1421
- /** Reports the end of the stream: unless it already has, the connection fails with `PG_ERR_CLOSED`. */
1595
+ /**
1596
+ * Reports the end of the stream (a read of 0 bytes, or a socket error):
1597
+ * unless it already has, the connection fails with `PG_ERR_CLOSED`, which
1598
+ * wipes the password. Input already received and not yet read is dropped.
1599
+ * @returns `PG_FAILED`, as every later `next()` does.
1600
+ */
1422
1601
  closed(): i32 {
1423
1602
  if (this.state !== PG_STATE_FAILED) {
1424
1603
  return this.fail(PG_ERR_CLOSED)
@@ -1431,12 +1610,17 @@ export class PgConnection {
1431
1610
  * once the proof is computed, the connection has failed or `dispose()` has
1432
1611
  * run (and for an empty password). It reads the copy itself, so a test can
1433
1612
  * see the wipe happen; a program has no use for it.
1613
+ * @returns True when the copy holds only zero bytes.
1434
1614
  */
1435
1615
  passwordWiped(): boolean {
1436
1616
  return this.password.wiped()
1437
1617
  }
1438
1618
 
1439
- /** Wipes the password if the connection still holds it. A program that drops a connection before it is ready calls this. */
1619
+ /**
1620
+ * Wipes the password if the connection still holds it. A program that drops
1621
+ * a connection before it is ready calls this. It does not close anything or
1622
+ * queue a Terminate: that is `terminate()`, and the socket is the program's.
1623
+ */
1440
1624
  dispose(): void {
1441
1625
  if (!this.password.gone) {
1442
1626
  this.password.wipe()
@@ -1445,7 +1629,16 @@ export class PgConnection {
1445
1629
 
1446
1630
  // --- Reading -----------------------------------------------------------------
1447
1631
 
1448
- /** The next event from the input. */
1632
+ /**
1633
+ * Reads input until it has an event to answer. Each call may move the
1634
+ * unread input to the start of the buffer or replace the buffer, which ends
1635
+ * the windows the last event gave (`colStart`, the tag) and calls for a
1636
+ * fresh `inputBuffer()`.
1637
+ * @returns `PG_NEED_MORE` when it needs more input; `PG_READY`, `PG_ROW`,
1638
+ * `PG_COMPLETE`, `PG_ERROR`, `PG_GROUP_DONE`, `PG_NOTICE` or
1639
+ * `PG_DESCRIBED` (the module header says what each means); or `PG_FAILED`,
1640
+ * final, with `failure` saying why.
1641
+ */
1449
1642
  next(): i32 {
1450
1643
  while (true) {
1451
1644
  if (this.state === PG_STATE_FAILED) {
@@ -2106,7 +2299,12 @@ export class PgConnection {
2106
2299
  setI32BE(this.out, at + 1, this.outEnd - at - 1)
2107
2300
  }
2108
2301
 
2109
- /** Whether another group may start, or the open one take another message. */
2302
+ /**
2303
+ * Whether another group may start, or the open one take another message.
2304
+ * @returns True once the connection is ready (after `PG_READY`, until
2305
+ * `PG_FAILED`) and either a group is open or fewer than `maxInFlight`
2306
+ * wait for their answers. Room under `maxOutput` is not part of it.
2307
+ */
2110
2308
  canSend(): boolean {
2111
2309
  return this.state === PG_STATE_READY && (this.groupOpen || this.inFlight < this.config.maxInFlight)
2112
2310
  }
@@ -2128,8 +2326,16 @@ export class PgConnection {
2128
2326
  * unnamed one), its parameters' types given by `paramTypes` (OIDs, 0 to let
2129
2327
  * the server infer one, and parameters past the array are inferred too).
2130
2328
  * The server answers `PG_DESCRIBED`. False, and nothing written, when
2131
- * `canSend()` is false, a bind is open, `name` or `sql` holds a NUL, or the
2132
- * message would pass `maxOutput`.
2329
+ * `canSend()` is false, a bind is open, `name` or `sql` holds a NUL, more
2330
+ * than 65535 types are given, or the message would pass `maxOutput`. It
2331
+ * opens a group when none is open; `sync()` ends it.
2332
+ * @param name The statement's name; a named statement lasts until
2333
+ * `closeStatement` or the connection's end, the unnamed one until the next
2334
+ * `prepare("")`.
2335
+ * @param sql The statement's text, `$1`, `$2`, ... for its parameters.
2336
+ * @param paramTypes The parameters' type OIDs (23 `int4`, 20 `int8`, 25
2337
+ * `text`), or 0 for one the server infers; read, not kept.
2338
+ * @returns True when the Parse and Describe were queued.
2133
2339
  */
2134
2340
  prepare(name: string, sql: string, paramTypes: i32[]): boolean {
2135
2341
  const nameLength: i32 = toI32(name.length)
@@ -2156,7 +2362,13 @@ export class PgConnection {
2156
2362
  return true
2157
2363
  }
2158
2364
 
2159
- /** Close: forgets the prepared statement `name`. False as `prepare` is. */
2365
+ /**
2366
+ * Close: forgets the prepared statement `name` on the server. False, and
2367
+ * nothing written, as `prepare` is. It opens a group when none is open.
2368
+ * @param name The statement to close; closing one that does not exist is
2369
+ * not an error to the server.
2370
+ * @returns True when the Close was queued.
2371
+ */
2160
2372
  closeStatement(name: string): boolean {
2161
2373
  if (pgHasNul(name) || toI32(name.length) > PG_MAX_CAP || !this.canOpen(7 + toI32(name.length))) {
2162
2374
  return false
@@ -2170,7 +2382,12 @@ export class PgConnection {
2170
2382
 
2171
2383
  /**
2172
2384
  * Starts a Bind of the prepared statement `name`; its parameters follow, in
2173
- * order, then `bindEnd()`. False as `prepare` is.
2385
+ * order, then `bindEnd()`. False, and nothing written, as `prepare` is. It
2386
+ * opens a group when none is open. Until `bindEnd()` or `bindCancel()`,
2387
+ * `outputEnd()` holds the Bind's bytes back.
2388
+ * @param name A statement prepared on this connection, in this group or an
2389
+ * earlier one.
2390
+ * @returns True when the Bind was opened.
2174
2391
  */
2175
2392
  bindStart(name: string): boolean {
2176
2393
  return this.openBind(name, false)
@@ -2188,6 +2405,8 @@ export class PgConnection {
2188
2405
  * with this when its `binary` is set, and reads their routing ordinals with
2189
2406
  * `binaryInt`. Its `bindEnd()` writes two bytes more, kept free under
2190
2407
  * `maxOutput` from here on. False as `prepare` is.
2408
+ * @param name A statement prepared on this connection.
2409
+ * @returns True when the Bind was opened.
2191
2410
  */
2192
2411
  bindStartBinary(name: string): boolean {
2193
2412
  return this.openBind(name, true)
@@ -2271,7 +2490,12 @@ export class PgConnection {
2271
2490
  // open, the bind has 65535 parameters already, or the parameter would pass
2272
2491
  // `maxOutput`; a program that checked `bindStart()` meets only the last.
2273
2492
 
2274
- /** A text parameter. */
2493
+ /**
2494
+ * A text parameter: the string's bytes as they are. Panics while an array
2495
+ * parameter is open.
2496
+ * @param value The parameter's text; "" is an empty string, not NULL.
2497
+ * @returns True when it was written; false as every `param...` call is.
2498
+ */
2275
2499
  paramText(value: string): boolean {
2276
2500
  const at: i32 = this.startParam(toI32(value.length))
2277
2501
  if (at < 0) {
@@ -2282,7 +2506,16 @@ export class PgConnection {
2282
2506
  return true
2283
2507
  }
2284
2508
 
2285
- /** A text parameter from `bytes[start, start + length)`, UTF-8; false too when the window is not inside `bytes`. */
2509
+ /**
2510
+ * A text parameter from `bytes[start, start + length)`, UTF-8, copied into
2511
+ * the Bind so the caller may reuse `bytes` at once. Panics while an array
2512
+ * parameter is open.
2513
+ * @param bytes The buffer the text lies in.
2514
+ * @param start The text's first byte.
2515
+ * @param length The text's length in bytes.
2516
+ * @returns True when it was written; false as every `param...` call is, and
2517
+ * when the window is not inside `bytes`.
2518
+ */
2286
2519
  paramBytes(bytes: u8[], start: i32, length: i32): boolean {
2287
2520
  this.noArrayOpen()
2288
2521
  if (start < 0 || length < 0 || length > toI32(bytes.length) - start) {
@@ -2299,7 +2532,11 @@ export class PgConnection {
2299
2532
  return true
2300
2533
  }
2301
2534
 
2302
- /** A NULL parameter. */
2535
+ /**
2536
+ * A NULL parameter, of whatever type the statement gives it. Panics while
2537
+ * an array parameter is open.
2538
+ * @returns True when it was written; false as every `param...` call is.
2539
+ */
2303
2540
  paramNull(): boolean {
2304
2541
  if (this.startParam(toI32(0)) < 0) {
2305
2542
  return false
@@ -2308,7 +2545,14 @@ export class PgConnection {
2308
2545
  return true
2309
2546
  }
2310
2547
 
2311
- /** An integer parameter, in decimal. */
2548
+ /**
2549
+ * An integer parameter, in decimal text, which the server reads as the
2550
+ * statement's type (`int2`, `int4`, `int8`, `numeric`, ...). Panics while an
2551
+ * array parameter is open.
2552
+ * @param value The integer; one outside the parameter's type is the
2553
+ * server's error (22003) for that execution.
2554
+ * @returns True when it was written; false as every `param...` call is.
2555
+ */
2312
2556
  paramInt(value: i64): boolean {
2313
2557
  const at: i32 = this.startParam(toI32(20))
2314
2558
  if (at < 0) {
@@ -2327,8 +2571,14 @@ export class PgConnection {
2327
2571
  }
2328
2572
 
2329
2573
  /**
2330
- * An `int8[]` parameter from `values[start, start + count)`, in decimal;
2331
- * panics when the range is not inside `values`.
2574
+ * An `int8[]` parameter from `values[start, start + count)`, in decimal
2575
+ * text (`{1,2,3}`, or `{}` for none); panics when the range is not inside
2576
+ * `values`, or while an array parameter is open.
2577
+ * @param values The integers; read now, not kept.
2578
+ * @param start The first element of the window.
2579
+ * @param count The elements to send, 0 for an empty array.
2580
+ * @returns True when it was written; false, and nothing written, as every
2581
+ * `param...` call is.
2332
2582
  */
2333
2583
  paramIntArray(values: i64[], start: i32, count: i32): boolean {
2334
2584
  if (start < 0 || count < 0 || count > toI32(values.length) - start) {
@@ -2361,7 +2611,14 @@ export class PgConnection {
2361
2611
  return true
2362
2612
  }
2363
2613
 
2364
- /** A `text[]` parameter: every element quoted, `"` and `\` escaped. */
2614
+ /**
2615
+ * A `text[]` parameter: every element quoted, `"` and `\` escaped, so no
2616
+ * element reads as NULL (build one with `arrayNull` for that). Panics while
2617
+ * an array parameter is open.
2618
+ * @param items The elements, in order; read now, not kept. Empty sends `{}`.
2619
+ * @returns True when it was written; false, and nothing written, as every
2620
+ * `param...` call is.
2621
+ */
2365
2622
  paramTextArray(items: string[]): boolean {
2366
2623
  // Its exact size first, so that room is asked for once and a refusal writes nothing.
2367
2624
  let size: i64 = 2
@@ -2415,7 +2672,12 @@ export class PgConnection {
2415
2672
  /**
2416
2673
  * An `int4[]` parameter in binary from `values[start, start + count)`;
2417
2674
  * false as the `param...` calls are. Panics, writing nothing, when the
2418
- * window is not inside `values` or an element is outside `int4`.
2675
+ * window is not inside `values` or an element is outside `int4`, and while
2676
+ * an array parameter is open.
2677
+ * @param values The integers, each within -2^31..2^31-1; read now, not kept.
2678
+ * @param start The first element of the window.
2679
+ * @param count The elements to send, 0 for an empty array.
2680
+ * @returns True when it was written.
2419
2681
  */
2420
2682
  paramInt4Array(values: i64[], start: i32, count: i32): boolean {
2421
2683
  pgIntWindow(values, start, count)
@@ -2431,7 +2693,11 @@ export class PgConnection {
2431
2693
  /**
2432
2694
  * An `int8[]` parameter in binary from `values[start, start + count)`;
2433
2695
  * false as the `param...` calls are. Panics when the window is not inside
2434
- * `values`.
2696
+ * `values`, and while an array parameter is open.
2697
+ * @param values The integers; read now, not kept.
2698
+ * @param start The first element of the window.
2699
+ * @param count The elements to send, 0 for an empty array.
2700
+ * @returns True when it was written.
2435
2701
  */
2436
2702
  paramInt8Array(values: i64[], start: i32, count: i32): boolean {
2437
2703
  pgIntWindow(values, start, count)
@@ -2485,7 +2751,13 @@ export class PgConnection {
2485
2751
  // with none open and a second `arrayStart()`; `sync()`, `prepare`,
2486
2752
  // `closeStatement` and `bindStart` answer false, the bind being open.
2487
2753
 
2488
- /** Opens an array parameter, `{}` so far; false as the `param...` calls are. */
2754
+ /**
2755
+ * Opens a text array parameter, `{}` so far, which `arrayElement`,
2756
+ * `arrayInt` and `arrayNull` fill and `arrayEnd()` closes. Panics while an
2757
+ * array is open.
2758
+ * @returns True when it was opened; false, and nothing written, as the
2759
+ * `param...` calls are.
2760
+ */
2489
2761
  arrayStart(): boolean {
2490
2762
  if (this.arrayAt >= 0) {
2491
2763
  panic("nish/net/postgres: arrayStart() while an array is open")
@@ -2519,7 +2791,12 @@ export class PgConnection {
2519
2791
  /**
2520
2792
  * A text element from `bytes[start, start + length)`, UTF-8, quoted with
2521
2793
  * `"` and `\` escaped; false, and nothing written, when there is no room.
2522
- * Panics when no array is open or the window is not inside `bytes`.
2794
+ * Panics when no text array is open or the window is not inside `bytes`.
2795
+ * @param bytes The buffer the element lies in; copied, so it may be reused at once.
2796
+ * @param start The element's first byte.
2797
+ * @param length The element's length in bytes; 0 is the empty string.
2798
+ * @returns True when it was written; false leaves the array open with the
2799
+ * elements it has.
2523
2800
  */
2524
2801
  arrayElement(bytes: u8[], start: i32, length: i32): boolean {
2525
2802
  this.arrayOpen()
@@ -2557,7 +2834,11 @@ export class PgConnection {
2557
2834
  return true
2558
2835
  }
2559
2836
 
2560
- /** A NULL element; false, and nothing written, when there is no room. Panics when no array is open. */
2837
+ /**
2838
+ * A NULL element of the open text array. Panics when no text array is open.
2839
+ * @returns True when it was written; false, and nothing written, when there
2840
+ * is no room.
2841
+ */
2561
2842
  arrayNull(): boolean {
2562
2843
  this.arrayOpen()
2563
2844
  if (!this.elementRoom(toI64(4))) {
@@ -2575,7 +2856,13 @@ export class PgConnection {
2575
2856
  this.arrayCount += 1
2576
2857
  }
2577
2858
 
2578
- /** An integer element, in decimal; false, and nothing written, when there is no room. Panics when no array is open. */
2859
+ /**
2860
+ * An integer element of the open text array, in decimal. Panics when no
2861
+ * text array is open.
2862
+ * @param value The element.
2863
+ * @returns True when it was written; false, and nothing written, when there
2864
+ * is no room.
2865
+ */
2579
2866
  arrayInt(value: i64): boolean {
2580
2867
  this.arrayOpen()
2581
2868
  if (!this.elementRoom(toI64(pgDecimalLength(value)))) {
@@ -2592,7 +2879,14 @@ export class PgConnection {
2592
2879
  // The text builder's rules hold, and a text element in a binary array, or a
2593
2880
  // binary element in a text one, panics.
2594
2881
 
2595
- /** Opens a binary array parameter of `elementOid`'s elements; false as the `param...` calls are. Panics on another OID, or while an array is open. */
2882
+ /**
2883
+ * Opens a binary array parameter of `elementOid`'s elements, which
2884
+ * `binaryArrayInt` and `binaryArrayNull` fill and `arrayEnd()` closes.
2885
+ * Panics on another OID, or while an array is open.
2886
+ * @param elementOid 23 for an `int4[]`, 20 for an `int8[]`.
2887
+ * @returns True when it was opened; false, and nothing written, as the
2888
+ * `param...` calls are.
2889
+ */
2596
2890
  binaryArrayStart(elementOid: i32): boolean {
2597
2891
  if (this.arrayAt >= 0) {
2598
2892
  panic("nish/net/postgres: binaryArrayStart() while an array is open")
@@ -2624,6 +2918,8 @@ export class PgConnection {
2624
2918
  * An integer element of the open binary array; false, and nothing written,
2625
2919
  * when there is no room. Panics when no binary array is open, or when it is
2626
2920
  * an `int4[]` and `value` is outside `int4`.
2921
+ * @param value The element: four bytes in an `int4[]`, eight in an `int8[]`.
2922
+ * @returns True when it was written.
2627
2923
  */
2628
2924
  binaryArrayInt(value: i64): boolean {
2629
2925
  this.binaryArrayOpen()
@@ -2646,7 +2942,12 @@ export class PgConnection {
2646
2942
  return true
2647
2943
  }
2648
2944
 
2649
- /** A NULL element of the open binary array, length -1; false, and nothing written, when there is no room. Panics when no binary array is open. */
2945
+ /**
2946
+ * A NULL element of the open binary array, length -1. Panics when no binary
2947
+ * array is open.
2948
+ * @returns True when it was written; false, and nothing written, when there
2949
+ * is no room.
2950
+ */
2650
2951
  binaryArrayNull(): boolean {
2651
2952
  this.binaryArrayOpen()
2652
2953
  if (!this.room(toI32(4))) {
@@ -2658,7 +2959,11 @@ export class PgConnection {
2658
2959
  return true
2659
2960
  }
2660
2961
 
2661
- /** Ends the open array parameter, text or binary; never refused for room, which its elements kept. Panics when no array is open. */
2962
+ /**
2963
+ * Ends the open array parameter, text or binary; never refused for room,
2964
+ * which its elements kept. An array with no elements is sent as the empty
2965
+ * array. Panics when no array is open.
2966
+ */
2662
2967
  arrayEnd(): void {
2663
2968
  if (this.arrayAt < 0) {
2664
2969
  panic("nish/net/postgres: arrayEnd() with no arrayStart()")
@@ -2686,7 +2991,9 @@ export class PgConnection {
2686
2991
  * Ends the Bind (every result column in text, or in binary after
2687
2992
  * `bindStartBinary`) and queues its Execute, for every row. False, and
2688
2993
  * nothing written, when no bind is open; never for room, which the calls
2689
- * before it kept.
2994
+ * before it kept. Panics while an array parameter is open. The Bind's bytes
2995
+ * count toward `outputEnd()` from here on.
2996
+ * @returns True when the Bind and Execute were queued.
2690
2997
  */
2691
2998
  bindEnd(): boolean {
2692
2999
  if (this.bindAt < 0) {
@@ -2723,6 +3030,7 @@ export class PgConnection {
2723
3030
  * Drops the open bind, and the array open in it, unsent, so that a program
2724
3031
  * whose parameter was refused for room can send the group without it; a
2725
3032
  * group the bind opened is closed again. False when no bind is open.
3033
+ * @returns True when an open bind was dropped.
2726
3034
  */
2727
3035
  bindCancel(): boolean {
2728
3036
  if (this.bindAt < 0) {
@@ -2766,7 +3074,12 @@ export class PgConnection {
2766
3074
  this.paramCountAt = from + codes
2767
3075
  }
2768
3076
 
2769
- /** Sync: ends the open group, which the server answers with `PG_GROUP_DONE`. False when no group is open or a bind is; never for room. */
3077
+ /**
3078
+ * Sync: ends the open group, which the server answers with
3079
+ * `PG_GROUP_DONE`; the group stays in `inFlight` until then.
3080
+ * @returns True when the Sync was queued; false when no group is open or a
3081
+ * bind is; never for room.
3082
+ */
2770
3083
  sync(): boolean {
2771
3084
  if (!this.groupOpen || this.bindAt >= 0) {
2772
3085
  return false
@@ -2778,7 +3091,11 @@ export class PgConnection {
2778
3091
  return true
2779
3092
  }
2780
3093
 
2781
- /** Terminate: tells the server the connection is ending; close the socket once it is sent. A bind still open is dropped unsent. */
3094
+ /**
3095
+ * Terminate: tells the server the connection is ending; close the socket
3096
+ * once it is sent. A bind still open is dropped unsent. It is queued in any
3097
+ * state, and is never refused for room.
3098
+ */
2782
3099
  terminate(): void {
2783
3100
  if (this.bindAt >= 0) {
2784
3101
  this.dropBind()
@@ -2790,22 +3107,39 @@ export class PgConnection {
2790
3107
 
2791
3108
  // --- Results -----------------------------------------------------------------
2792
3109
 
2793
- /** Column `c`'s first byte in `inputBuffer()`. */
3110
+ /**
3111
+ * Column `c`'s first byte in `inputBuffer()`, valid until the next `next()`.
3112
+ * @param c The column, 0 to `columns - 1`.
3113
+ * @returns An index into `inputBuffer()`.
3114
+ */
2794
3115
  colStart(c: i32): i32 {
2795
3116
  return this.colStarts[c]
2796
3117
  }
2797
3118
 
2798
- /** Column `c`'s length, -1 for NULL. */
3119
+ /**
3120
+ * Column `c`'s length.
3121
+ * @param c The column, 0 to `columns - 1`.
3122
+ * @returns The length in bytes, or -1 for NULL.
3123
+ */
2799
3124
  colLength(c: i32): i32 {
2800
3125
  return this.colLengths[c]
2801
3126
  }
2802
3127
 
2803
- /** Whether column `c` is NULL. */
3128
+ /**
3129
+ * Whether column `c` of the current row is NULL.
3130
+ * @param c The column, 0 to `columns - 1`.
3131
+ * @returns True when the column is NULL.
3132
+ */
2804
3133
  isNull(c: i32): boolean {
2805
3134
  return this.colLengths[c] < 0
2806
3135
  }
2807
3136
 
2808
- /** Column `c` as a string; the one result read that allocates. "" for NULL. */
3137
+ /**
3138
+ * Column `c` as a string; the one result read that allocates, and the string
3139
+ * outlives the row.
3140
+ * @param c The column, 0 to `columns - 1`.
3141
+ * @returns The column's bytes as a string; "" for NULL and for an empty value.
3142
+ */
2809
3143
  columnText(c: i32): string {
2810
3144
  const length: i32 = this.colLengths[c]
2811
3145
  if (length <= 0) {
@@ -2815,37 +3149,70 @@ export class PgConnection {
2815
3149
  return String.fromBytes(this.input, start, start + length)
2816
3150
  }
2817
3151
 
2818
- /** Column `c` of the statement just described: its type's OID (23 is `int4`, 25 `text`). */
3152
+ /**
3153
+ * Column `c` of the statement just described, after `PG_DESCRIBED`.
3154
+ * @param c The column, 0 to `columns - 1`.
3155
+ * @returns Its type's OID (23 is `int4`, 25 `text`).
3156
+ */
2819
3157
  columnType(c: i32): i32 {
2820
3158
  return this.colTypes[c]
2821
3159
  }
2822
3160
 
2823
- /** Column `c` as an integer; NULL or a bad value sets `text.failed`. */
3161
+ /**
3162
+ * Text column `c` as an integer, through `text.int`; NULL or a bad value
3163
+ * sets `text.failed`.
3164
+ * @param c The column, 0 to `columns - 1`.
3165
+ * @returns The value, or 0 when it sets `text.failed`.
3166
+ */
2824
3167
  int(c: i32): i64 {
2825
3168
  return this.text.int(this.input, this.colStarts[c], this.colLengths[c])
2826
3169
  }
2827
3170
 
2828
- /** Column `c` as a boolean; NULL or a bad value sets `text.failed`. */
3171
+ /**
3172
+ * Text column `c` as a boolean, through `text.bool`; NULL or a bad value
3173
+ * sets `text.failed`.
3174
+ * @param c The column, 0 to `columns - 1`.
3175
+ * @returns True for `t`; false for `f`, and when it sets `text.failed`.
3176
+ */
2829
3177
  bool(c: i32): boolean {
2830
3178
  return this.text.bool(this.input, this.colStarts[c], this.colLengths[c])
2831
3179
  }
2832
3180
 
2833
- /** Binary column `c`, an `int2`, `int4`, `int8` or a time's microseconds, as an integer; NULL or another length sets `binary.failed`. */
3181
+ /**
3182
+ * Binary column `c`, an `int2`, `int4`, `int8` or a time's microseconds
3183
+ * since 2000, as an integer; NULL or another length sets `binary.failed`.
3184
+ * @param c The column, 0 to `columns - 1`.
3185
+ * @returns The value, or 0 when it sets `binary.failed`.
3186
+ */
2834
3187
  binaryInt(c: i32): i64 {
2835
3188
  return this.binary.int(this.input, this.colStarts[c], this.colLengths[c])
2836
3189
  }
2837
3190
 
2838
- /** Binary column `c` as a boolean; NULL or a bad value sets `binary.failed`. */
3191
+ /**
3192
+ * Binary column `c` as a boolean; NULL or a bad value sets `binary.failed`.
3193
+ * @param c The column, 0 to `columns - 1`.
3194
+ * @returns True for 1; false for 0, and when it sets `binary.failed`.
3195
+ */
2839
3196
  binaryBool(c: i32): boolean {
2840
3197
  return this.binary.bool(this.input, this.colStarts[c], this.colLengths[c])
2841
3198
  }
2842
3199
 
2843
- /** Binary column `c`, a `float8`, as an f64; NULL or another length sets `binary.failed`. */
3200
+ /**
3201
+ * Binary column `c`, a `float8`; NULL or another length sets `binary.failed`.
3202
+ * @param c The column, 0 to `columns - 1`.
3203
+ * @returns The value, or 0 when it sets `binary.failed`.
3204
+ */
2844
3205
  binaryFloat(c: i32): f64 {
2845
3206
  return this.binary.float(this.input, this.colStarts[c], this.colLengths[c])
2846
3207
  }
2847
3208
 
2848
- /** Whether the tag of the execution just completed starts with the word `word` (`INSERT`, `SELECT`, ...). */
3209
+ /**
3210
+ * Whether the tag of the execution just completed starts with the word
3211
+ * `word`, read after `PG_COMPLETE` and before the next `next()`.
3212
+ * @param word The command word, as the server spells it (`INSERT`,
3213
+ * `SELECT`, `UPDATE`, ...); case matters, and `INS` does not match `INSERT`.
3214
+ * @returns True when the tag is `word` or begins with `word` and a space.
3215
+ */
2849
3216
  tagIs(word: string): boolean {
2850
3217
  const n: i32 = toI32(word.length)
2851
3218
  if (n > this.tagLength || !pgBytesAre(this.input, this.tagStart, n, word)) {
@@ -2854,7 +3221,13 @@ export class PgConnection {
2854
3221
  return n === this.tagLength || toI32(this.input[this.tagStart + n]) === 32
2855
3222
  }
2856
3223
 
2857
- /** The row count the tag ends with (`INSERT 0 3` is 3, `SELECT 5` is 5), or -1 when it has none or it does not fit an i64. */
3224
+ /**
3225
+ * The row count the tag of the execution just completed ends with, read
3226
+ * after `PG_COMPLETE` and before the next `next()`; `text.failed` is left
3227
+ * as it was.
3228
+ * @returns The count (`INSERT 0 3` is 3, `SELECT 5` is 5), or -1 when the
3229
+ * tag has none (`BEGIN`) or it does not fit an i64.
3230
+ */
2858
3231
  tagRows(): i64 {
2859
3232
  const end: i32 = this.tagStart + this.tagLength
2860
3233
  let p: i32 = end
@@ -2904,15 +3277,27 @@ const PG_SLOT_DRAINING: i32 = 4
2904
3277
 
2905
3278
  /** One of a pool's connections, and the groups it has in flight. */
2906
3279
  class PgPoolSlot {
3280
+ /** @internal Used by `PgPool.dispatch`, `PgPool.wanted`, `PgPool.connect`, `PgPool.next` and `PgPool.anyReady` in this module. */
2907
3281
  state: i32 = 0
3282
+ /** @internal Used by `PgPool.dispatch`, `PgPool.connect`, `PgPool.connection` and `PgPool.dispose` in this module. */
2908
3283
  conn: PgConnection | null = null
2909
- /** How many registered statements this connection has queued, and how many the server has described. */
3284
+ /**
3285
+ * How many registered statements this connection has queued, and how many the server has described.
3286
+ * @internal Used by `PgPool.dispatch`, `PgPool.connect` and `PgPool.next` in this module.
3287
+ */
2910
3288
  queued: i32 = 0
3289
+ /** @internal Used by `PgPool.connect` and `PgPool.next` in this module. */
2911
3290
  described: i32 = 0
2912
- /** The groups in flight, oldest first, in a ring: each one's ticket, and how many of the pool's own prepares lead it. */
3291
+ /**
3292
+ * The groups in flight, oldest first, in a ring: each one's ticket, and how many of the pool's own prepares lead it.
3293
+ * @internal Used by `PgPool.next` in this module.
3294
+ */
2913
3295
  readonly tickets: i32[]
3296
+ /** @internal Used by `PgPool.next` in this module. */
2914
3297
  readonly leads: i32[]
3298
+ /** @internal Used by `PgPool.connect` and `PgPool.next` in this module. */
2915
3299
  head: i32 = 0
3300
+ /** @internal Used by `PgPool.inFlight`, `PgPool.send`, `PgPool.connect` and `PgPool.next` in this module. */
2916
3301
  count: i32 = 0
2917
3302
 
2918
3303
  constructor(ring: i32) {
@@ -2920,6 +3305,7 @@ class PgPoolSlot {
2920
3305
  this.leads = new Array<i32>(ring)
2921
3306
  }
2922
3307
 
3308
+ /** @internal Used by `PgPool.dispatch` and `PgPool.next` in this module. */
2923
3309
  push(ticket: i32, leads: i32): void {
2924
3310
  const at: i32 = (this.head + this.count) % toI32(this.tickets.length)
2925
3311
  this.tickets[at] = ticket
@@ -2927,6 +3313,7 @@ class PgPoolSlot {
2927
3313
  this.count += 1
2928
3314
  }
2929
3315
 
3316
+ /** @internal Used by `PgPool.next` in this module. */
2930
3317
  pop(): void {
2931
3318
  this.head = (this.head + 1) % toI32(this.tickets.length)
2932
3319
  this.count -= 1
@@ -2975,6 +3362,12 @@ export class PgPool {
2975
3362
  * waiting requests (1 to 2^20). `password` is copied and kept until
2976
3363
  * `dispose()`, since a connection is made again after a failure. Panics as
2977
3364
  * `PgConnection` does on `config`, and on a `maxInFlight` over 1024.
3365
+ *
3366
+ * @param config The settings every connection of the pool is made with; kept, not copied.
3367
+ * @param password The password every connection authenticates with. The pool keeps its
3368
+ * own copy, so the caller may wipe this one as soon as the constructor returns.
3369
+ * @param size The most connections the pool makes, from 1 to 1024.
3370
+ * @param queueSize The most requests that may wait for a connection, from 1 to 2^20.
2978
3371
  */
2979
3372
  constructor(config: PgConfig, password: Secret<u8[]>, size: i32, queueSize: i32) {
2980
3373
  pgCheckConfig(config)
@@ -3004,6 +3397,11 @@ export class PgPool {
3004
3397
  * Registers a statement for every connection to prepare before its first
3005
3398
  * request. False when a connection has been made already, `name` or `sql`
3006
3399
  * holds a NUL, or 256 are registered.
3400
+ *
3401
+ * @param name The statement's name, which the program's binds use; no NUL.
3402
+ * @param sql The statement's text, with `$1`, `$2`... for its parameters; no NUL.
3403
+ * @param paramTypes The type OID of each parameter, 0 to let the server infer it; copied.
3404
+ * @returns True when the statement was registered.
3007
3405
  */
3008
3406
  register(name: string, sql: string, paramTypes: i32[]): boolean {
3009
3407
  if (
@@ -3024,7 +3422,12 @@ export class PgPool {
3024
3422
  return true
3025
3423
  }
3026
3424
 
3027
- /** Queues a request and answers its ticket, or `PG_POOL_FULL` when `queueSize` are waiting. */
3425
+ /**
3426
+ * Queues a request and answers its ticket, or `PG_POOL_FULL` when `queueSize` are waiting.
3427
+ *
3428
+ * @returns The request's ticket, from 0 to 2^31-1 and counting up from 0, wrapping to 0
3429
+ * after 2^31-1; or `PG_POOL_FULL`.
3430
+ */
3028
3431
  request(): i32 {
3029
3432
  const room: i32 = toI32(this.queue.length)
3030
3433
  if (this.queueCount === room) {
@@ -3037,12 +3440,21 @@ export class PgPool {
3037
3440
  return ticket
3038
3441
  }
3039
3442
 
3040
- /** The number of requests waiting for a connection. */
3443
+ /**
3444
+ * How many requests wait for a connection.
3445
+ *
3446
+ * @returns The requests queued and not yet given a connection.
3447
+ */
3041
3448
  waiting(): i32 {
3042
3449
  return this.queueCount
3043
3450
  }
3044
3451
 
3045
- /** The number of groups in flight on every connection, sent and not yet done: the `inFlight` a `PgBatchClock` reads. */
3452
+ /**
3453
+ * How many groups are in flight across every connection: the `inFlight` a
3454
+ * `PgBatchClock` reads.
3455
+ *
3456
+ * @returns The groups sent and not yet done, summed over every connection.
3457
+ */
3046
3458
  inFlight(): i32 {
3047
3459
  let n: i32 = 0
3048
3460
  for (const slot of this.slots) {
@@ -3061,6 +3473,8 @@ export class PgPool {
3061
3473
  * waiting requests that the connections already starting cannot take. A
3062
3474
  * request handed out is the program's to end with `send()`: until then no
3063
3475
  * other is handed out.
3476
+ *
3477
+ * @returns The slot the request was handed to, from 0 to `size - 1`, or `PG_POOL_NONE`.
3064
3478
  */
3065
3479
  dispatch(): i32 {
3066
3480
  if (this.building >= 0 || this.queueCount === 0) {
@@ -3117,6 +3531,8 @@ export class PgPool {
3117
3531
  * is none; when a bind is still open, so finish it and call again; and
3118
3532
  * when no message of the group was written, so the request is dropped and
3119
3533
  * gets no events (`PG_LOST` if its connection has failed).
3534
+ *
3535
+ * @returns True when the group's Sync was written and the request is in flight.
3120
3536
  */
3121
3537
  send(): boolean {
3122
3538
  const s: i32 = this.building
@@ -3140,7 +3556,11 @@ export class PgPool {
3140
3556
  return false
3141
3557
  }
3142
3558
 
3143
- /** A slot that needs a socket, or `PG_POOL_NONE`: connect it, then call `connect(slot, nonce)`. */
3559
+ /**
3560
+ * A slot that needs a socket, or `PG_POOL_NONE`: connect it, then call `connect(slot, nonce)`.
3561
+ *
3562
+ * @returns The lowest wanted slot, or `PG_POOL_NONE` when no slot is wanted.
3563
+ */
3144
3564
  wanted(): i32 {
3145
3565
  for (let s: i32 = 0; s < this.size; s++) {
3146
3566
  if (this.slots[s].state === PG_SLOT_WANTED) {
@@ -3155,6 +3575,10 @@ export class PgPool {
3155
3575
  * send its output once the socket is connected, and if the socket fails,
3156
3576
  * call `connection(slot).closed()`. Panics when `slot` is not wanted or the
3157
3577
  * pool is disposed.
3578
+ *
3579
+ * @param slot The slot `wanted()` answered.
3580
+ * @param nonce At least 18 fresh random bytes for the SCRAM client nonce, as the
3581
+ * `PgConnection` constructor takes them; a new one for every connection.
3158
3582
  */
3159
3583
  connect(slot: i32, nonce: u8[]): void {
3160
3584
  if (slot < 0 || slot >= this.size || this.slots[slot].state !== PG_SLOT_WANTED) {
@@ -3173,7 +3597,13 @@ export class PgPool {
3173
3597
  this.started = true
3174
3598
  }
3175
3599
 
3176
- /** The connection in `slot`, its buffers the carrier's to fill and drain; the last one made after it fails. Panics when none was made. */
3600
+ /**
3601
+ * The connection in `slot`, its buffers the carrier's to fill and drain; the last one made
3602
+ * after it fails. Panics when none was made.
3603
+ *
3604
+ * @param slot The slot, from 0 to `size - 1`.
3605
+ * @returns The slot's connection, owned by the pool: a later `connect` on the slot replaces it.
3606
+ */
3177
3607
  connection(slot: i32): PgConnection {
3178
3608
  const conn: PgConnection | null = slot < 0 || slot >= this.size ? null : this.slots[slot].conn
3179
3609
  if (conn === null) {
@@ -3193,6 +3623,9 @@ export class PgPool {
3193
3623
  * server that cannot be reached empties the queue rather than holds it.
3194
3624
  * `PG_NEED_MORE` once `PG_FAILED` was answered, until `connect` builds the
3195
3625
  * slot again. Panics as `connection(slot)` does.
3626
+ *
3627
+ * @param slot The slot whose input the carrier has just filled, from 0 to `size - 1`.
3628
+ * @returns A `PG_` event; `ticket` names the request it is about.
3196
3629
  */
3197
3630
  next(slot: i32): i32 {
3198
3631
  const conn: PgConnection = this.connection(slot)
@@ -3249,7 +3682,13 @@ export class PgPool {
3249
3682
  return false
3250
3683
  }
3251
3684
 
3252
- /** Whether every byte of the pool's copy of the password is zero, as `PgConnection.passwordWiped()` reads its own. */
3685
+ /**
3686
+ * Whether every byte of the pool's copy of the password is zero, as
3687
+ * `PgConnection.passwordWiped()` reads its own: true once it is wiped, and
3688
+ * for an empty password before any wipe.
3689
+ *
3690
+ * @returns True once the pool's copy is wiped; the connections' copies are not read.
3691
+ */
3253
3692
  passwordWiped(): boolean {
3254
3693
  return this.password.wiped()
3255
3694
  }
@@ -3365,23 +3804,46 @@ export class PgBatchConfig {
3365
3804
 
3366
3805
  /** One execution's requests, grouped by key, and how far its rows have been routed. */
3367
3806
  class PgBatchRun {
3368
- /** Key `k`'s requests' tags are `tags[first[k], first[k + 1])`, in the order they were added; grown by `take` to the batch. */
3807
+ /**
3808
+ * Key `k`'s requests' tags are `tags[first[k], first[k + 1])`, in the order they were added; grown by `take` to the batch.
3809
+ * @internal Used by `PgBatcher.take`, `PgBatcher.emit`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module.
3810
+ */
3369
3811
  tags: i32[]
3812
+ /** @internal Used by `PgBatcher.take`, `PgBatcher.emit` and `PgBatcher.nextUnsorted` in this module. */
3370
3813
  first: i32[]
3371
- /** Under `sorted` false, whether key `k` has had a row; grown by `take` with `tags`, and empty when sorted. */
3814
+ /**
3815
+ * Under `sorted` false, whether key `k` has had a row; grown by `take` with `tags`, and empty when sorted.
3816
+ * @internal Used by `PgBatcher.take`, `PgBatcher.row` and `PgBatcher.nextUnsorted` in this module.
3817
+ */
3372
3818
  had: boolean[]
3819
+ /** @internal Used by `PgBatcher.row`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module. */
3373
3820
  keys: i32 = 0
3374
- /** The key rows are being read for, whether it has had one, and the next of its requests to answer. */
3821
+ /**
3822
+ * The key rows are being read for, whether it has had one, and the next of its requests to answer.
3823
+ * @internal Used by `PgBatcher.row`, `PgBatcher.emit`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module.
3824
+ */
3375
3825
  cur: i32 = 0
3826
+ /** @internal Used by `PgBatcher.next` in this module. */
3376
3827
  curRows: boolean = false
3828
+ /** @internal Used by `PgBatcher.emit`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module. */
3377
3829
  at: i32 = 0
3378
- /** The key whose `PG_BATCH_ROW` events are owed for the connection's current row; -1 for none. */
3830
+ /**
3831
+ * The key whose `PG_BATCH_ROW` events are owed for the connection's current row; -1 for none.
3832
+ * @internal Used by `PgBatcher.quietRun`, `PgBatcher.row`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module.
3833
+ */
3379
3834
  target: i32 = -1
3380
- /** The handle `take` gave for the run's execution, and how many takes it has had, mod `PG_BATCH_USES`. */
3835
+ /**
3836
+ * The handle `take` gave for the run's execution, and how many takes it has had, mod `PG_BATCH_USES`.
3837
+ * @internal Used by `PgBatcher.take` and `PgBatcher.run` in this module.
3838
+ */
3381
3839
  handle: i32 = -1
3840
+ /** @internal Used by `PgBatcher.take` in this module. */
3382
3841
  uses: i32 = 0
3842
+ /** @internal Used by `PgBatcher.take`, `PgBatcher.run`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module. */
3383
3843
  open: boolean = false
3844
+ /** @internal Used by `PgBatcher.quietRun`, `PgBatcher.end`, `PgBatcher.fail`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module. */
3384
3845
  ended: boolean = false
3846
+ /** @internal Used by `PgBatcher.row`, `PgBatcher.fail`, `PgBatcher.next` and `PgBatcher.nextUnsorted` in this module. */
3385
3847
  failed: boolean = false
3386
3848
 
3387
3849
  constructor() {
@@ -3390,7 +3852,10 @@ class PgBatchRun {
3390
3852
  this.had = []
3391
3853
  }
3392
3854
 
3393
- /** Opens the run for `keys` keys, none of whose rows have been read. */
3855
+ /**
3856
+ * Opens the run for `keys` keys, none of whose rows have been read.
3857
+ * @internal Used by `PgBatcher.take` in this module.
3858
+ */
3394
3859
  reset(keys: i32): void {
3395
3860
  this.open = true
3396
3861
  this.keys = keys
@@ -3471,7 +3936,10 @@ export class PgBatcher {
3471
3936
  refused: i32 = 0
3472
3937
  /** The number of `row`, `end` and `fail` calls on a spent handle, each ignored, stopping at 2^31 - 1. */
3473
3938
  stray: i32 = 0
3474
- /** The most requests one execution takes, from `PgBatchConfig.maxRequests`. */
3939
+ /**
3940
+ * The most requests one execution takes, from `PgBatchConfig.maxRequests`.
3941
+ * @internal Used by `PgCarrier.routeBatch` in std/net/postgres-carrier.ts.
3942
+ */
3475
3943
  readonly maxRequests: i32
3476
3944
  private readonly keyType: i32
3477
3945
  private readonly maxBytes: i32
@@ -3481,7 +3949,14 @@ export class PgBatcher {
3481
3949
  private head: i32 = 0
3482
3950
  private count: i32 = 0
3483
3951
 
3484
- /** A batcher for `config`; panics when a name or query is empty or holds a NUL, or a cap is out of range. */
3952
+ /**
3953
+ * A batcher for `config`; panics when a name or query is empty or holds a NUL, or a cap is out
3954
+ * of range.
3955
+ *
3956
+ * @param config The statement shape and caps, read once here: later changes to it do nothing.
3957
+ * `maxRequests` is 1 to 65536, `maxBytes` at least 22, `queueSize` 1 to 2^20, `runs` 1 to
3958
+ * 1024, and `queueBytes` at least 0 (a text batcher with 0 can queue only empty keys).
3959
+ */
3485
3960
  constructor(config: PgBatchConfig) {
3486
3961
  const keyType: i32 = config.keyType
3487
3962
  if (keyType !== PG_BATCH_INT && keyType !== PG_BATCH_TEXT) {
@@ -3547,15 +4022,21 @@ export class PgBatcher {
3547
4022
  }
3548
4023
  }
3549
4024
 
3550
- /** The number of requests waiting for `take`. */
4025
+ /**
4026
+ * How many requests wait for `take`.
4027
+ *
4028
+ * @returns The requests queued and not yet taken into a batch.
4029
+ */
3551
4030
  waiting(): i32 {
3552
4031
  return this.count
3553
4032
  }
3554
4033
 
3555
4034
  /**
3556
- * Drops the oldest waiting request and answers its tag, or -1 when none
3557
- * waits: for a program that cannot reach the server to fail requests
3558
- * rather than hold them.
4035
+ * Drops the oldest waiting request, so that a carrier that cannot reach the
4036
+ * server fails its requests rather than holds them.
4037
+ *
4038
+ * @returns The dropped request's tag, or -1 when none waits.
4039
+ * @internal Used by `PgCarrier.next` in std/net/postgres-carrier.ts.
3559
4040
  */
3560
4041
  shed(): i32 {
3561
4042
  if (this.count === 0) {
@@ -3570,7 +4051,15 @@ export class PgBatcher {
3570
4051
  return tag
3571
4052
  }
3572
4053
 
3573
- /** Queues a request for the int8 `key`; false when `queueSize` are waiting. Panics on a text batcher. */
4054
+ /**
4055
+ * Queues a request for the int8 `key`; false when `queueSize` are waiting. Panics on a text
4056
+ * batcher.
4057
+ *
4058
+ * @param key The key the statement's `q.key` is bound to.
4059
+ * @param tag The caller's own number for the request, which `tag` holds when `next(run)`
4060
+ * answers an event about it; best not -1, which `tag` holds for none.
4061
+ * @returns True when the request was queued.
4062
+ */
3574
4063
  addInt(key: i64, tag: i32): boolean {
3575
4064
  if (this.keyType !== PG_BATCH_INT) {
3576
4065
  panic("nish/net/postgres: PgBatcher.addInt on a text batcher")
@@ -3591,6 +4080,14 @@ export class PgBatcher {
3591
4080
  * the key would not fit in `queueBytes` beside those waiting, or it is too
3592
4081
  * long for one execution's `maxBytes`. Panics on an int8 batcher, or when
3593
4082
  * the window is not inside `bytes`.
4083
+ *
4084
+ * @param bytes The buffer holding the key; only the window is read, and the caller may reuse
4085
+ * the buffer as soon as the call returns.
4086
+ * @param start The index of the key's first byte in `bytes`.
4087
+ * @param length The key's length in bytes, 0 for the empty key.
4088
+ * @param tag The caller's own number for the request, which `tag` holds when `next(run)`
4089
+ * answers an event about it; best not -1, which `tag` holds for none.
4090
+ * @returns True when the request was queued.
3594
4091
  */
3595
4092
  addText(bytes: u8[], start: i32, length: i32, tag: i32): boolean {
3596
4093
  if (this.keyType !== PG_BATCH_TEXT) {
@@ -3684,6 +4181,12 @@ export class PgBatcher {
3684
4181
  * answers -1. The program calls `clock.arrived(now)` for each request it
3685
4182
  * adds. Panics when the clock's waiting count is not this batcher's, or its
3686
4183
  * `maxCount` is below `maxRequests`.
4184
+ *
4185
+ * @param conn The free connection to bind the batch on, as `take` takes it.
4186
+ * @param clock The clock that mirrors this batcher's queue, one `arrived` per request added.
4187
+ * @param nowUs The time now, in the clock's microseconds.
4188
+ * @param inFlight The program's executions or groups still running, for the idle bypass.
4189
+ * @returns The run handle `take` answered, or -1 when no batch was taken.
3687
4190
  */
3688
4191
  takeDue(conn: PgConnection, clock: PgBatchClock, nowUs: i64, inFlight: i32): i32 {
3689
4192
  if (clock.waiting() !== this.count || clock.maxCount < this.maxRequests) {
@@ -3709,6 +4212,10 @@ export class PgBatcher {
3709
4212
  * the connection's `maxOutput`; those not taken stay queued. -1, and
3710
4213
  * nothing written, when none waits, every run is in flight, or `conn`
3711
4214
  * refused the bind or the first key.
4215
+ *
4216
+ * @param conn A connection with no bind open, on which `sql` has been prepared under `name`.
4217
+ * @returns The run handle, from 0 to `runs` * 2^20 - 1, to pass to `row`, `end`, `fail` and
4218
+ * `next` for this execution's events; or -1.
3712
4219
  */
3713
4220
  take(conn: PgConnection): i32 {
3714
4221
  if (this.count === 0) {
@@ -3892,6 +4399,10 @@ export class PgBatcher {
3892
4399
  * one before the key the last row was for): that counts in `refused` and
3893
4400
  * fails the run; and on a spent handle, which counts in `stray`. Panics on a handle
3894
4401
  * `take` cannot give, or when the run's events are not all answered.
4402
+ *
4403
+ * @param r The run handle `take` answered for the execution the row belongs to.
4404
+ * @param conn The connection whose `next()` has just answered `PG_ROW` for that execution.
4405
+ * @returns True when the row was routed, and `next(r)` answers its `PG_BATCH_ROW` events.
3895
4406
  */
3896
4407
  row(r: i32, conn: PgConnection): boolean {
3897
4408
  const run: PgBatchRun | null = this.quietRun(r, "row")
@@ -3935,7 +4446,12 @@ export class PgBatcher {
3935
4446
  return true
3936
4447
  }
3937
4448
 
3938
- /** Ends run `r`'s execution, on its `PG_COMPLETE`: `next(r)` then closes every request left. Ignores a spent handle, and panics, as `row` does. */
4449
+ /**
4450
+ * Ends run `r`'s execution, on its `PG_COMPLETE`: `next(r)` then closes every request left.
4451
+ * Ignores a spent handle, and panics, as `row` does.
4452
+ *
4453
+ * @param r The run handle `take` answered for the execution.
4454
+ */
3939
4455
  end(r: i32): void {
3940
4456
  const run: PgBatchRun | null = this.quietRun(r, "end")
3941
4457
  if (run !== null) {
@@ -3943,7 +4459,12 @@ export class PgBatcher {
3943
4459
  }
3944
4460
  }
3945
4461
 
3946
- /** Fails run `r`'s execution, on its `PG_ERROR` or `PG_LOST`: `next(r)` then answers `PG_BATCH_FAILED` for every request left. Ignores a spent handle, and panics, as `row` does. */
4462
+ /**
4463
+ * Fails run `r`'s execution, on its `PG_ERROR` or `PG_LOST`: `next(r)` then answers
4464
+ * `PG_BATCH_FAILED` for every request left. Ignores a spent handle, and panics, as `row` does.
4465
+ *
4466
+ * @param r The run handle `take` answered for the execution.
4467
+ */
3947
4468
  fail(r: i32): void {
3948
4469
  const run: PgBatchRun | null = this.quietRun(r, "fail")
3949
4470
  if (run !== null) {
@@ -3969,6 +4490,9 @@ export class PgBatcher {
3969
4490
  * Once `end` or `fail` has had all its events the run is over, free for
3970
4491
  * `take` again, and its handle spent: `PG_BATCH_NONE` ever after. Panics
3971
4492
  * on a handle `take` cannot give.
4493
+ *
4494
+ * @param r The run handle `take` answered for the execution.
4495
+ * @returns A `PG_BATCH_*` event: call again until it is `PG_BATCH_NONE`.
3972
4496
  */
3973
4497
  next(r: i32): i32 {
3974
4498
  const found: PgBatchRun | null = this.run(r)
@@ -4120,6 +4644,7 @@ export class PgBatchClock {
4120
4644
  lastReason: i32 = 0
4121
4645
  /** How long the oldest item of the last batch waited, in microseconds. */
4122
4646
  lastWaitUs: i64 = 0
4647
+ /** @internal Used by `PgBatcher.takeDue` in this module. */
4123
4648
  readonly maxCount: i32
4124
4649
  private readonly minCount: i32
4125
4650
  private readonly factor: f64
@@ -4138,7 +4663,12 @@ export class PgBatchClock {
4138
4663
  private last: i64 = 0
4139
4664
  private due: i32 = 0
4140
4665
 
4141
- /** A clock for `config`; panics when a setting is out of the range its field names. */
4666
+ /**
4667
+ * A clock for `config`; panics when a setting is out of the range its field names, or
4668
+ * `minCount` is above `maxCount`.
4669
+ *
4670
+ * @param config The settings, read once here: later changes to it do nothing.
4671
+ */
4142
4672
  constructor(config: PgBatchClockConfig) {
4143
4673
  const factor: f64 = config.factor
4144
4674
  const weight: f64 = config.weight
@@ -4171,7 +4701,11 @@ export class PgBatchClock {
4171
4701
  this.starts = new Array<i64>(5)
4172
4702
  }
4173
4703
 
4174
- /** The number of items waiting. */
4704
+ /**
4705
+ * How many items wait for a batch.
4706
+ *
4707
+ * @returns The items queued and not yet started in a batch.
4708
+ */
4175
4709
  waiting(): i32 {
4176
4710
  return this.count
4177
4711
  }
@@ -4180,6 +4714,9 @@ export class PgBatchClock {
4180
4714
  * Records an item queued at `nowUs`; false when `queueSize` are waiting. A
4181
4715
  * time before the last one given counts as the last one, so a clock that
4182
4716
  * steps back cannot make an item older than its neighbours.
4717
+ *
4718
+ * @param nowUs The time the item was queued, in microseconds from the program's fixed point.
4719
+ * @returns True when the item was recorded.
4183
4720
  */
4184
4721
  arrived(nowUs: i64): boolean {
4185
4722
  const ring: i32 = toI32(this.times.length)
@@ -4201,7 +4738,11 @@ export class PgBatchClock {
4201
4738
  return true
4202
4739
  }
4203
4740
 
4204
- /** The count that starts a batch now: the larger of `minCount` and the average times `factor`, at most `maxCount`. */
4741
+ /**
4742
+ * The count that starts a batch now.
4743
+ *
4744
+ * @returns The larger of `minCount` and the average times `factor`, at most `maxCount`.
4745
+ */
4205
4746
  target(): i32 {
4206
4747
  const scaled: f64 = Math.ceil(this.average * this.factor)
4207
4748
  let target: i32 = this.minCount
@@ -4215,6 +4756,12 @@ export class PgBatchClock {
4215
4756
  * The reason a batch should start at `nowUs`, with `inFlight` batches (or
4216
4757
  * groups) still running, or `PG_CLOCK_WAIT`. It only says; the program
4217
4758
  * starts the batch when a connection is free, then calls `started`.
4759
+ *
4760
+ * @param nowUs The time now, in the clock's microseconds.
4761
+ * @param inFlight The batches or groups still running; 0 or less lets the idle bypass fire.
4762
+ * @returns `PG_CLOCK_COUNT`, `PG_CLOCK_AVERAGE`, `PG_CLOCK_TIMER`, `PG_CLOCK_IDLE`, or
4763
+ * `PG_CLOCK_WAIT`, always `PG_CLOCK_WAIT` when nothing waits. The next `started` records it
4764
+ * as `lastReason`.
4218
4765
  */
4219
4766
  check(nowUs: i64, inFlight: i32): i32 {
4220
4767
  let reason: i32 = PG_CLOCK_WAIT
@@ -4232,7 +4779,11 @@ export class PgBatchClock {
4232
4779
  return reason
4233
4780
  }
4234
4781
 
4235
- /** When the oldest waiting item has waited `maxWaitUs`, in the caller's microseconds; -1 when none waits. */
4782
+ /**
4783
+ * When the oldest waiting item will have waited `maxWaitUs`.
4784
+ *
4785
+ * @returns That time in the caller's microseconds, or -1 when none waits.
4786
+ */
4236
4787
  deadline(): i64 {
4237
4788
  if (this.count === 0) {
4238
4789
  return -1
@@ -4244,6 +4795,10 @@ export class PgBatchClock {
4244
4795
  * Records a batch of the `size` oldest items started at `nowUs`, and moves
4245
4796
  * the average toward it; the first batch sets it. Panics when `size` is
4246
4797
  * below 1 or more than are waiting or than `maxCount`.
4798
+ *
4799
+ * @param size The number of items the batch took, oldest first.
4800
+ * @param nowUs The time the batch started, in the clock's microseconds; `lastWaitUs` is
4801
+ * measured to it, and is 0 when it is before the oldest item's arrival.
4247
4802
  */
4248
4803
  started(size: i32, nowUs: i64): void {
4249
4804
  if (size < 1 || size > this.count || size > this.maxCount) {
@@ -4263,7 +4818,13 @@ export class PgBatchClock {
4263
4818
  this.due = PG_CLOCK_WAIT
4264
4819
  }
4265
4820
 
4266
- /** How many batches have started for `reason`, one of the `PG_CLOCK_*` (`PG_CLOCK_WAIT` counts those started without a due `check`). */
4821
+ /**
4822
+ * How many batches have started for `reason`, one of the `PG_CLOCK_*` (`PG_CLOCK_WAIT` counts
4823
+ * those started without a due `check`). Panics on any other `reason`.
4824
+ *
4825
+ * @param reason `PG_CLOCK_WAIT` to `PG_CLOCK_IDLE`.
4826
+ * @returns The count since the clock was made.
4827
+ */
4267
4828
  startsFor(reason: i32): i64 {
4268
4829
  if (reason < 0 || reason > PG_CLOCK_IDLE) {
4269
4830
  panic("nish/net/postgres: PgBatchClock.startsFor with a reason out of range")
@@ -4312,12 +4873,18 @@ export class PgBatchTurns {
4312
4873
  /** The clock the turns read and record into. */
4313
4874
  readonly clock: PgBatchClock
4314
4875
  /** The number of slots. */
4315
- readonly size: i32
4876
+ private readonly size: i32
4316
4877
  private readonly busy: boolean[]
4317
4878
  private running: i32 = 0
4318
4879
  private woken: i32 = -1
4319
4880
 
4320
- /** Turns over `size` slots (1 to 1024), all free; panics on a size out of range. */
4881
+ /**
4882
+ * Turns over `size` slots (1 to 1024), all free; panics on a size out of range.
4883
+ *
4884
+ * @param clock The clock the program's batches are formed by; kept. `push` and `started`
4885
+ * record into it, so the program does not call its `arrived` or `started` itself.
4886
+ * @param size The number of connections, numbered 0 to `size - 1`.
4887
+ */
4321
4888
  constructor(clock: PgBatchClock, size: i32) {
4322
4889
  if (size < 1 || size > PG_POOL_MAX_SLOTS) {
4323
4890
  panic("nish/net/postgres: a PgBatchTurns size out of range")
@@ -4327,7 +4894,11 @@ export class PgBatchTurns {
4327
4894
  this.busy = new Array<boolean>(size)
4328
4895
  }
4329
4896
 
4330
- /** The slot that collects: the lowest-numbered free one, or `PG_TURNS_NONE` when every slot holds a batch. */
4897
+ /**
4898
+ * The slot that collects the next batch.
4899
+ *
4900
+ * @returns The lowest-numbered free slot, or `PG_TURNS_NONE` when every slot holds a batch.
4901
+ */
4331
4902
  collector(): i32 {
4332
4903
  for (let i: i32 = 0; i < this.size; i++) {
4333
4904
  if (!this.busy[i]) {
@@ -4337,17 +4908,31 @@ export class PgBatchTurns {
4337
4908
  return PG_TURNS_NONE
4338
4909
  }
4339
4910
 
4340
- /** The number of slots holding a batch. */
4911
+ /**
4912
+ * How many slots hold a batch.
4913
+ *
4914
+ * @returns The slots whose batch has `started` and not yet `finished`.
4915
+ */
4341
4916
  inFlight(): i32 {
4342
4917
  return this.running
4343
4918
  }
4344
4919
 
4345
- /** When the collector's timer fires, `PgBatchClock.deadline()`; -1 when nothing waits. */
4920
+ /**
4921
+ * When the collector's timer fires, as `PgBatchClock.deadline()` gives it.
4922
+ *
4923
+ * @returns That time in the caller's microseconds, or -1 when nothing waits.
4924
+ */
4346
4925
  deadline(): i64 {
4347
4926
  return this.clock.deadline()
4348
4927
  }
4349
4928
 
4350
- /** Records an item queued at `nowUs` and answers the slot to wake, or `PG_TURNS_FULL` when the clock is full. */
4929
+ /**
4930
+ * Records an item queued at `nowUs` and answers the slot to wake, or `PG_TURNS_FULL` when the
4931
+ * clock is full.
4932
+ *
4933
+ * @param nowUs The time the item was queued, in the clock's microseconds.
4934
+ * @returns The slot to wake, `PG_TURNS_NONE` when none is to be woken, or `PG_TURNS_FULL`.
4935
+ */
4351
4936
  push(nowUs: i64): i32 {
4352
4937
  if (!this.clock.arrived(nowUs)) {
4353
4938
  return PG_TURNS_FULL
@@ -4355,7 +4940,12 @@ export class PgBatchTurns {
4355
4940
  return this.poll(nowUs)
4356
4941
  }
4357
4942
 
4358
- /** The slot to wake at `nowUs`, when a batch is due and no slot is named already. */
4943
+ /**
4944
+ * The slot to wake at `nowUs`, when a batch is due and no slot is named already.
4945
+ *
4946
+ * @param nowUs The time now, in the clock's microseconds; call at `deadline()`.
4947
+ * @returns The collector's slot, or `PG_TURNS_NONE`.
4948
+ */
4359
4949
  poll(nowUs: i64): i32 {
4360
4950
  if (this.woken >= 0) {
4361
4951
  return PG_TURNS_NONE
@@ -4368,7 +4958,17 @@ export class PgBatchTurns {
4368
4958
  return slot
4369
4959
  }
4370
4960
 
4371
- /** Records `slot` starting a batch of `size` items at `nowUs`, and answers the next slot to wake. Panics on a slot out of range or holding a batch already, or as `PgBatchClock.started`. */
4961
+ /**
4962
+ * Records `slot` starting a batch of `size` items at `nowUs`, and answers the next slot to
4963
+ * wake. Panics on a slot out of range or holding a batch already, or as
4964
+ * `PgBatchClock.started`.
4965
+ *
4966
+ * @param slot The slot that took the batch, from 0 to `size - 1`; it holds the batch until
4967
+ * `finished`.
4968
+ * @param size The number of items the batch took.
4969
+ * @param nowUs The time the batch started, in the clock's microseconds.
4970
+ * @returns The slot to wake, or `PG_TURNS_NONE`.
4971
+ */
4372
4972
  started(slot: i32, size: i32, nowUs: i64): i32 {
4373
4973
  this.free(slot)
4374
4974
  this.clock.started(size, nowUs)
@@ -4380,7 +4980,14 @@ export class PgBatchTurns {
4380
4980
  return this.poll(nowUs)
4381
4981
  }
4382
4982
 
4383
- /** Records `slot`'s batch done at `nowUs`, and answers the slot to wake. Panics on a slot out of range or holding no batch. */
4983
+ /**
4984
+ * Records `slot`'s batch done at `nowUs`, and answers the slot to wake. Panics on a slot out
4985
+ * of range or holding no batch.
4986
+ *
4987
+ * @param slot The slot whose batch is done, from 0 to `size - 1`.
4988
+ * @param nowUs The time now, in the clock's microseconds.
4989
+ * @returns The slot to wake, or `PG_TURNS_NONE`.
4990
+ */
4384
4991
  finished(slot: i32, nowUs: i64): i32 {
4385
4992
  if (slot < 0 || slot >= this.size || !this.busy[slot]) {
4386
4993
  panic("nish/net/postgres: PgBatchTurns.finished on a slot holding no batch")
@@ -4390,7 +4997,12 @@ export class PgBatchTurns {
4390
4997
  return this.poll(nowUs)
4391
4998
  }
4392
4999
 
4393
- /** Gives back a wake that started nothing, so the next push or poll can wake a slot again. */
5000
+ /**
5001
+ * Gives back a wake that started nothing, so the next push or poll can wake a slot again.
5002
+ * Panics on a slot out of range or holding a batch.
5003
+ *
5004
+ * @param slot The slot that was woken and took no batch.
5005
+ */
4394
5006
  release(slot: i32): void {
4395
5007
  this.free(slot)
4396
5008
  if (this.woken === slot) {
@@ -4462,6 +5074,11 @@ const pgTargetFailed = (failure: i32): PgTarget => {
4462
5074
  * empty host, a `,` (more than one host) or a NUL byte is refused, and so is
4463
5075
  * a socket path over 107 bytes (an `@` name over 107 after its `@`), never
4464
5076
  * cut short.
5077
+ *
5078
+ * @param host The host, a socket directory starting with `/`, or an abstract name starting
5079
+ * with `@`; taken as it is, not percent-decoded.
5080
+ * @param port The TCP port, or the number in the socket's name, from 1 to 65535.
5081
+ * @returns The target; read `failure` before anything else.
4465
5082
  */
4466
5083
  export const pgTarget = (host: string, port: i32): PgTarget => {
4467
5084
  if (port < 1 || port > 65535) {
@@ -4533,6 +5150,9 @@ const pgPortValue = (text: string): i32 => {
4533
5150
  * would use its default socket directory. An empty port or query value is
4534
5151
  * refused, where libpq would take it as unset.
4535
5152
  * The decoded host is then resolved as `pgTarget` resolves one.
5153
+ *
5154
+ * @param url The URL; any user or password it holds is not kept in the target.
5155
+ * @returns The target; read `failure` before anything else.
4536
5156
  */
4537
5157
  export const pgTargetUrl = (url: string): PgTarget => {
4538
5158
  let at: i32 = 0