@steve31415/baselib 3.54.0 → 3.55.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.
package/dist/db.js CHANGED
@@ -75,6 +75,19 @@ export const DEFAULT_STATEMENT_TIMEOUT_MS = 10 * 60_000;
75
75
  * outside that and well inside the 15 s checkout timeout, so a stall that
76
76
  * the timeout later kills has already been seen to be slow. */
77
77
  export const SLOW_CONNECT_MS = 2_000;
78
+ // Headroom judged 2026-11-05 (coder task cec8d1c7), for this threshold and
79
+ // `connectionTimeoutMillis` below: 6 slow-but-successful connects in the
80
+ // week to 2026-11-05 across ~16 apps, 2.1–4.4 s, at most 0.29 of the 15 s
81
+ // timeout. Two causes, both accepted: (1) Cloud SQL's IAM login itself
82
+ // taking 2.5–4.4 s with tcp/tls fast (radar, always-on CPU; ~2 a week,
83
+ // one of them a 4.4 s wait on Steve's own page load); (2) a CPU-starved
84
+ // process stretching every step alike — a LISTEN bridge reconnecting with
85
+ // no request in flight on a throttled-CPU service after the Thursday idle
86
+ // reset (chime, todo), or reader under corpus's daily 11:05 UTC burst of
87
+ // ~700 lookups at 12-way concurrency. Neither approaches the timeout, and
88
+ // a retry would not shorten a server-side login. Keep 15 s; revisit if a
89
+ // login-only stall reaches 7.5 s (half the timeout) or the login-only
90
+ // kind exceeds 4 a week (KNOWN_LOG_PATTERNS.md, "new connection was slow").
78
91
  /** Pool settings every fleet pool carries; `createPool` applies them and
79
92
  * is the way to get them (a hand-built pool spreads this, but prefer
80
93
  * `createPool` with `user` / `sessionOptions` over building one). Decided
@@ -279,7 +292,13 @@ const CONNECT_TIMING_MESSAGE = 'database pool: new connection was slow or failed
279
292
  * each step finished, in ms from the start — `tcpMs` (socket connected),
280
293
  * `tlsMs` (TLS done; the Cloud SQL connector's socket only), `authMs`
281
294
  * (the server accepted the login; with IAM authentication Cloud SQL checks
282
- * the token here). The point is the step a stall sits in: before `tcp` is
295
+ * the token here). These marks are cumulative; `stepsMs` gives each
296
+ * step's own duration (`tcp`, `tls`, `login` — login runs from the end of
297
+ * TLS, or of TCP without TLS), so a reader need not subtract (triage
298
+ * 2026-11-05 read a cumulative `authMs` as "all in the login"). Each mark
299
+ * is taken when the event loop handles the event, so a CPU-starved
300
+ * process stretches every step alike, while a slow server-side login
301
+ * shows fast tcp/tls and a long login. The point is the step a stall sits in: before `tcp` is
283
302
  * the network path, between `tcp` and `tls` the Cloud SQL front end or the
284
303
  * certificate, between `tls`/`tcp` and `authenticated` the database login.
285
304
  * pg-pool's own events cannot say this, and a handshake whose checkout
@@ -320,6 +339,14 @@ function timeNewConnections(pool, logger, options) {
320
339
  if (!err)
321
340
  this.#reached = 'ready';
322
341
  const expiry = options.credentialExpiry?.();
342
+ const { tcp, tls, authenticated } = this.#marks;
343
+ const stepsMs = {};
344
+ if (tcp !== undefined)
345
+ stepsMs.tcp = tcp;
346
+ if (tls !== undefined && tcp !== undefined)
347
+ stepsMs.tls = tls - tcp;
348
+ if (authenticated !== undefined)
349
+ stepsMs.login = authenticated - (tls ?? tcp ?? 0);
323
350
  const meta = {
324
351
  outcome: err ? 'failed' : 'slow',
325
352
  reached: this.#reached,
@@ -327,6 +354,7 @@ function timeNewConnections(pool, logger, options) {
327
354
  tcpMs: this.#marks.tcp,
328
355
  tlsMs: this.#marks.tls,
329
356
  authMs: this.#marks.authenticated,
357
+ stepsMs,
330
358
  pool: { total: pool.totalCount, idle: pool.idleCount, waiting: pool.waitingCount, max: pool.options.max },
331
359
  ...(options.credentialExpiry ? (expiry === undefined ? { credentialUnknown: true } : { credentialRemainingMs: expiry - Date.now() }) : {}),
332
360
  ...(err ? { error: err } : {}),
package/dist/rum.d.ts CHANGED
@@ -11,7 +11,11 @@ export interface RumOptions {
11
11
  * The same-origin resource of one initiator type (`script`, `fetch`) that
12
12
  * finished last before `before` (ms since navigation start) — for a single-page
13
13
  * app, the entry script and the first data fetch that first paint waited on.
14
- * Times are ms since navigation start; `bytes` 0 means served from cache.
14
+ * `start_ms`, `sent_ms`, `first_byte_ms` and `end_ms` are ms since navigation
15
+ * start; `dns_ms` and `connect_ms` are durations. A request the browser (or an
16
+ * extension in it) held before sending shows as `sent_ms - start_ms` well over
17
+ * `dns_ms + connect_ms`; a cold network shows in those two; `bytes` 0 means
18
+ * served from cache.
15
19
  */
16
20
  export declare function lastResourceBefore(entries: readonly PerformanceResourceTiming[], initiatorType: string, before: number): Record<string, string | number | undefined> | undefined;
17
21
  /**
package/dist/rum.js CHANGED
@@ -35,7 +35,11 @@ function resourcePath(url) {
35
35
  * The same-origin resource of one initiator type (`script`, `fetch`) that
36
36
  * finished last before `before` (ms since navigation start) — for a single-page
37
37
  * app, the entry script and the first data fetch that first paint waited on.
38
- * Times are ms since navigation start; `bytes` 0 means served from cache.
38
+ * `start_ms`, `sent_ms`, `first_byte_ms` and `end_ms` are ms since navigation
39
+ * start; `dns_ms` and `connect_ms` are durations. A request the browser (or an
40
+ * extension in it) held before sending shows as `sent_ms - start_ms` well over
41
+ * `dns_ms + connect_ms`; a cold network shows in those two; `bytes` 0 means
42
+ * served from cache.
39
43
  */
40
44
  export function lastResourceBefore(entries, initiatorType, before) {
41
45
  let pick;
@@ -56,10 +60,15 @@ export function lastResourceBefore(entries, initiatorType, before) {
56
60
  }
57
61
  if (!pick)
58
62
  return undefined;
63
+ const positive = (n) => (n > 0 ? n : undefined);
64
+ const span = (from, to) => (from > 0 && to >= from ? to - from : undefined);
59
65
  return {
60
66
  path: resourcePath(pick.name),
61
67
  start_ms: ms(pick.startTime),
62
- first_byte_ms: ms(pick.responseStart > 0 ? pick.responseStart : undefined),
68
+ sent_ms: ms(positive(pick.requestStart)),
69
+ dns_ms: ms(span(pick.domainLookupStart, pick.domainLookupEnd)),
70
+ connect_ms: ms(span(pick.connectStart, pick.connectEnd)),
71
+ first_byte_ms: ms(positive(pick.responseStart)),
63
72
  end_ms: ms(pick.responseEnd),
64
73
  bytes: pick.transferSize,
65
74
  protocol: pick.nextHopProtocol || undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steve31415/baselib",
3
- "version": "3.54.0",
3
+ "version": "3.55.0",
4
4
  "description": "Plasticine new-world shared platform library: logging, auth, service-to-service auth, db, HTTP, sync, app updates",
5
5
  "type": "module",
6
6
  "license": "MIT",