@substrat-run/control-plane-api 0.134.0 → 0.136.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 (88) hide show
  1. package/dist/aggregate-reads.d.ts.map +1 -1
  2. package/dist/aggregate-reads.js +4 -1
  3. package/dist/aggregate-reads.js.map +1 -1
  4. package/dist/aggregate-source.d.ts +17 -1
  5. package/dist/aggregate-source.d.ts.map +1 -1
  6. package/dist/aggregate-source.js +16 -10
  7. package/dist/aggregate-source.js.map +1 -1
  8. package/dist/api.d.ts.map +1 -1
  9. package/dist/api.js +1037 -66
  10. package/dist/api.js.map +1 -1
  11. package/dist/auth.d.ts +2 -13
  12. package/dist/auth.d.ts.map +1 -1
  13. package/dist/auth.js +4 -13
  14. package/dist/auth.js.map +1 -1
  15. package/dist/browser.d.ts +4 -4
  16. package/dist/browser.d.ts.map +1 -1
  17. package/dist/browser.js +6 -3
  18. package/dist/browser.js.map +1 -1
  19. package/dist/cf-observability.d.ts +6 -0
  20. package/dist/cf-observability.d.ts.map +1 -1
  21. package/dist/cf-observability.js +126 -34
  22. package/dist/cf-observability.js.map +1 -1
  23. package/dist/connect-url.d.ts +2 -2
  24. package/dist/connect-url.d.ts.map +1 -1
  25. package/dist/connect-url.js +7 -1
  26. package/dist/connect-url.js.map +1 -1
  27. package/dist/connection-relay.d.ts +4 -2
  28. package/dist/connection-relay.d.ts.map +1 -1
  29. package/dist/connection-relay.js +10 -1
  30. package/dist/connection-relay.js.map +1 -1
  31. package/dist/deploy.d.ts +3 -0
  32. package/dist/deploy.d.ts.map +1 -1
  33. package/dist/deploy.js.map +1 -1
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/errors.js +6 -4
  36. package/dist/errors.js.map +1 -1
  37. package/dist/failure-attribution.js +2 -2
  38. package/dist/failure-attribution.js.map +1 -1
  39. package/dist/index.d.ts +6 -9
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +5 -5
  42. package/dist/index.js.map +1 -1
  43. package/dist/observability.d.ts +20 -1
  44. package/dist/observability.d.ts.map +1 -1
  45. package/dist/observability.js +11 -1
  46. package/dist/observability.js.map +1 -1
  47. package/dist/platform-drain.d.ts +24 -2
  48. package/dist/platform-drain.d.ts.map +1 -1
  49. package/dist/platform-drain.js +37 -4
  50. package/dist/platform-drain.js.map +1 -1
  51. package/dist/platform-entry.d.ts +62 -6
  52. package/dist/platform-entry.d.ts.map +1 -1
  53. package/dist/platform-entry.generated.d.ts +8 -1
  54. package/dist/platform-entry.generated.d.ts.map +1 -1
  55. package/dist/platform-entry.generated.js +10 -3
  56. package/dist/platform-entry.generated.js.map +1 -1
  57. package/dist/platform-entry.js +151 -9
  58. package/dist/platform-entry.js.map +1 -1
  59. package/dist/preview-auth.js +1 -1
  60. package/dist/preview-auth.js.map +1 -1
  61. package/dist/provider-error.d.ts +9 -0
  62. package/dist/provider-error.d.ts.map +1 -0
  63. package/dist/provider-error.js +9 -0
  64. package/dist/provider-error.js.map +1 -0
  65. package/dist/staff-client.d.ts +4 -3
  66. package/dist/staff-client.d.ts.map +1 -1
  67. package/dist/staff-client.js +5 -2
  68. package/dist/staff-client.js.map +1 -1
  69. package/dist/tenant-request-query.d.ts.map +1 -1
  70. package/dist/tenant-request-query.js +3 -1
  71. package/dist/tenant-request-query.js.map +1 -1
  72. package/dist/vertical-client.d.ts +179 -40
  73. package/dist/vertical-client.d.ts.map +1 -1
  74. package/dist/vertical-client.js +357 -172
  75. package/dist/vertical-client.js.map +1 -1
  76. package/package.json +6 -5
  77. package/dist/client.d.ts +0 -111
  78. package/dist/client.d.ts.map +0 -1
  79. package/dist/client.js +0 -122
  80. package/dist/client.js.map +0 -1
  81. package/dist/identity-tenants.d.ts +0 -30
  82. package/dist/identity-tenants.d.ts.map +0 -1
  83. package/dist/identity-tenants.js +0 -23
  84. package/dist/identity-tenants.js.map +0 -1
  85. package/dist/transport.d.ts +0 -56
  86. package/dist/transport.d.ts.map +0 -1
  87. package/dist/transport.js +0 -88
  88. package/dist/transport.js.map +0 -1
package/dist/auth.d.ts CHANGED
@@ -14,19 +14,8 @@ import { type OnBehalfOf, type PlatformActorId, type TenantId } from '@substrat-
14
14
  * the log cannot name is exactly that.
15
15
  */
16
16
  export type PlatformActorAuth = (request: Request) => Promise<PlatformActorId | null> | PlatformActorId | null;
17
- /** Header the dev stub reads. Mirrors the demos' `x-principal` dev affordance. */
18
- export declare const DEV_ACTOR_HEADER = "x-platform-actor";
19
- /** Header a SERVICE (a vertical registering itself) presents — not a staff subject. */
20
- export declare const SERVICE_TOKEN_HEADER = "x-service-token";
21
- /**
22
- * Header naming the tenant a caller ACTS FOR. For a builder session it selects the
23
- * workspace (`--tenant`) the builder reader narrows to. For a staff/service caller it is
24
- * the slug-resolution pin (#417): vertical routes form `<tenantSlug>/<slug>` from it the
25
- * way a pinned push does, so `versions <bare> --tenant <t>` over a service token reaches
26
- * the same registry row a builder session would. It never widens access — staff reach
27
- * everything already, and for builders the tenant must be one of their memberships.
28
- */
29
- export declare const TENANT_HEADER = "x-substrat-tenant";
17
+ import { DEV_ACTOR_HEADER, SERVICE_TOKEN_HEADER, TENANT_HEADER } from '@substrat-run/control-plane-client';
18
+ export { DEV_ACTOR_HEADER, SERVICE_TOKEN_HEADER, TENANT_HEADER };
30
19
  /**
31
20
  * A service credential (open decision 2): a shared bearer token that resolves to
32
21
  * a fixed service actor. This is how a *vertical* authenticates to the control
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/auth.js CHANGED
@@ -1,17 +1,8 @@
1
1
  import { platformActorId } from '@substrat-run/contracts';
2
- /** Header the dev stub reads. Mirrors the demos' `x-principal` dev affordance. */
3
- export const DEV_ACTOR_HEADER = 'x-platform-actor';
4
- /** Header a SERVICE (a vertical registering itself) presents — not a staff subject. */
5
- export const SERVICE_TOKEN_HEADER = 'x-service-token';
6
- /**
7
- * Header naming the tenant a caller ACTS FOR. For a builder session it selects the
8
- * workspace (`--tenant`) the builder reader narrows to. For a staff/service caller it is
9
- * the slug-resolution pin (#417): vertical routes form `<tenantSlug>/<slug>` from it the
10
- * way a pinned push does, so `versions <bare> --tenant <t>` over a service token reaches
11
- * the same registry row a builder session would. It never widens access — staff reach
12
- * everything already, and for builders the tenant must be one of their memberships.
13
- */
14
- export const TENANT_HEADER = 'x-substrat-tenant';
2
+ // The header names live in the client package, which every caller can import without taking
3
+ // this server with it; this module re-exports them so the server reads the same spelling.
4
+ import { DEV_ACTOR_HEADER, SERVICE_TOKEN_HEADER, TENANT_HEADER } from '@substrat-run/control-plane-client';
5
+ export { DEV_ACTOR_HEADER, SERVICE_TOKEN_HEADER, TENANT_HEADER };
15
6
  /**
16
7
  * A service credential (open decision 2): a shared bearer token that resolves to
17
8
  * a fixed service actor. This is how a *vertical* authenticates to the control
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/browser.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * The browser-safe entry (`@substrat-run/control-plane-api/browser`, #971): the typed
3
3
  * client a staff console runs in a page, and the types it renders. Everything reachable
4
- * from here is `fetch` + `@substrat-run/contracts` + type-only imports — never `hono`,
5
- * never a Node builtin — so a bundler can follow it without pulling the server in.
4
+ * from here is `fetch` + `@substrat-run/contracts` + `@substrat-run/control-plane-client`
5
+ * (itself only those two) + type-only imports — never `hono`, never a Node builtin — so a
6
+ * bundler can follow it without pulling the server in.
6
7
  * `test/browser-entry.test.ts` holds that line.
7
8
  */
8
9
  export { ControlPlaneStaffClient } from './staff-client.js';
9
10
  export type { AdminLogPage, AuditLogQuery, BindHostnameInput, ConnectionHealthQuery, ConnectorCallsBucket, DoNamespace, EgressReport, IssuesQuery, MembersReading, ObservedEgressRow, OpsFailuresQuery, PageQuery, PlatformRuntime, ProvisionScopeInput, RebindScopeResult, RecentLogEvent, ScopeHealth, ServiceMetricsRow, StaffMember, SweepRunsQuery, SystemSwitchesQuery, TenantStores, } from './staff-client.js';
10
- export { ControlPlaneError } from './transport.js';
11
- export type { ControlPlaneTransportOptions } from './transport.js';
11
+ export * from '@substrat-run/control-plane-client';
12
12
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAG3B,cAAc,oCAAoC,CAAC"}
package/dist/browser.js CHANGED
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  * The browser-safe entry (`@substrat-run/control-plane-api/browser`, #971): the typed
3
3
  * client a staff console runs in a page, and the types it renders. Everything reachable
4
- * from here is `fetch` + `@substrat-run/contracts` + type-only imports — never `hono`,
5
- * never a Node builtin — so a bundler can follow it without pulling the server in.
4
+ * from here is `fetch` + `@substrat-run/contracts` + `@substrat-run/control-plane-client`
5
+ * (itself only those two) + type-only imports — never `hono`, never a Node builtin — so a
6
+ * bundler can follow it without pulling the server in.
6
7
  * `test/browser-entry.test.ts` holds that line.
7
8
  */
8
9
  export { ControlPlaneStaffClient } from './staff-client.js';
9
- export { ControlPlaneError } from './transport.js';
10
+ // The client package's whole surface, so a caller of either entry reaches it from here and
11
+ // no existing import moved (#971). `test/reexports.test.ts` pins that nothing is missing.
12
+ export * from '@substrat-run/control-plane-client';
10
13
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAyB5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAyB5D,2FAA2F;AAC3F,0FAA0F;AAC1F,cAAc,oCAAoC,CAAC"}
@@ -1,5 +1,11 @@
1
1
  import { type CubeStore } from './aggregate-source.js';
2
2
  import type { ObservabilityReader } from './observability.js';
3
+ /**
4
+ * An HTTP method as RFC 9110 §9.1 defines it: a `token` (§5.6.2), one or more `tchar`.
5
+ * Not `[A-Z]+`: the writer records `Request.method` verbatim, and `M-SEARCH` and `X1` are
6
+ * methods too.
7
+ */
8
+ export declare const HTTP_METHOD_PATTERN = "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$";
3
9
  /**
4
10
  * The Cloudflare implementation of the observability seam (`observability.ts`) —
5
11
  * GraphQL invocation analytics + the Workers Observability telemetry query API,
@@ -1 +1 @@
1
- {"version":3,"file":"cf-observability.d.ts","sourceRoot":"","sources":["../src/cf-observability.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqE,KAAK,SAAS,EAAuB,MAAM,uBAAuB,CAAC;AAG/I,OAAO,KAAK,EACV,mBAAmB,EASpB,MAAM,oBAAoB,CAAC;AAqa5B;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAuED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,sBAAsB,GAAG,mBAAmB,CA8uC7F"}
1
+ {"version":3,"file":"cf-observability.d.ts","sourceRoot":"","sources":["../src/cf-observability.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqE,KAAK,SAAS,EAAuB,MAAM,uBAAuB,CAAC;AAG/I,OAAO,KAAK,EACV,mBAAmB,EASpB,MAAM,oBAAoB,CAAC;AAG5B;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AA0enE;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAuED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,sBAAsB,GAAG,mBAAmB,CAywC7F"}
@@ -1,9 +1,23 @@
1
1
  import { resolveObservabilityWindow, observabilityBucketMinutes } from './observability-window.js';
2
- import { ControlPlaneError } from './client.js';
2
+ import { ControlPlaneError } from '@substrat-run/control-plane-client';
3
3
  import { cachedSource, cutOverSource } from './aggregate-source.js';
4
4
  import { stableDeploymentRefFor } from './deploy.js';
5
5
  import { aggregateReads } from './aggregate-reads.js';
6
- import { TENANT_METRICS_LIMIT, REQUEST_FACET_KEYS } from './observability.js';
6
+ import { TENANT_METRICS_LIMIT, REQUEST_FACET_KEYS, INVOCATION_KINDS, invocationKindOf } from './observability.js';
7
+ /**
8
+ * An HTTP method as RFC 9110 §9.1 defines it: a `token` (§5.6.2), one or more `tchar`.
9
+ * Not `[A-Z]+`: the writer records `Request.method` verbatim, and `M-SEARCH` and `X1` are
10
+ * methods too.
11
+ */
12
+ export const HTTP_METHOD_PATTERN = "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$";
13
+ /**
14
+ * #1901: a request's line, as a filter. Every request line carries its HTTP method — the
15
+ * lines written before `kind` existed included — and an async line's `method` is `null`,
16
+ * so this is the `kind = request` the lines themselves cannot spell.
17
+ */
18
+ const REQUEST_LINE_FILTER = { key: 'method', operation: 'regex', type: 'string', value: HTTP_METHOD_PATTERN };
19
+ /** #1901: the kinds of async work a scope host logs — every kind but a request. */
20
+ const ASYNC_KINDS = INVOCATION_KINDS.filter((k) => k !== 'request');
7
21
  /**
8
22
  * The filters for a tenant's stamped invocation lines (#1746), with the facet filters ANDed
9
23
  * on. `omit` leaves one facet's own filter out, which is how a facet is counted "with every
@@ -29,6 +43,14 @@ function requestFilters(scope, omit) {
29
43
  const values = scope.where?.[key] ?? [];
30
44
  if (values.length === 0)
31
45
  continue;
46
+ // #1901: `request` is a kind no line spells — a request's line has no `kind` — so it is
47
+ // matched by what every request line has and no async line does: a method. Narrowed
48
+ // HERE, before the limit, so a window full of async lines still pages its requests.
49
+ if (key === 'kind') {
50
+ const kinds = values.map((v) => v === 'request' ? REQUEST_LINE_FILTER : { key: 'kind', operation: 'eq', type: 'string', value: v });
51
+ filters.push(kinds.length === 1 ? kinds[0] : { kind: 'group', filterCombination: 'or', filters: kinds });
52
+ continue;
53
+ }
32
54
  const leaves = values.map((v) => key === 'status'
33
55
  ? { key, operation: 'eq', type: 'number', value: Number(v) }
34
56
  : { key, operation: 'eq', type: 'string', value: v });
@@ -116,6 +138,13 @@ function countOf(p) {
116
138
  function sampled(p) {
117
139
  return typeof p.sampleInterval === 'number' && p.sampleInterval > 1;
118
140
  }
141
+ /** #1901: does a raw line pass the scope's `kind` selection, a missing `kind` read as `request`? */
142
+ function kindMatches(e, scope) {
143
+ const values = scope.where?.kind ?? [];
144
+ if (values.length === 0)
145
+ return true;
146
+ return values.includes(invocationKindOf((e['source'] ?? {})['kind']));
147
+ }
119
148
  /** The stamped line of a raw event, as the Requests view lists it. */
120
149
  function requestRecordOf(e) {
121
150
  const source = (e['source'] ?? {});
@@ -141,6 +170,12 @@ function requestRecordOf(e) {
141
170
  eventTypes: strings(source['eventTypes']),
142
171
  entities: strings(source['entities']),
143
172
  versionId: str(source['versionId']),
173
+ kind: invocationKindOf(source['kind']),
174
+ outcome: str(source['outcome']),
175
+ eventType: str(source['eventType']),
176
+ eventId: str(source['eventId']),
177
+ attempt: num(source['attempt']),
178
+ latenessMs: num(source['latenessMs']),
144
179
  };
145
180
  }
146
181
  /**
@@ -219,6 +254,16 @@ function describeInvocation(e) {
219
254
  const source = (e.raw?.['source'] ?? {});
220
255
  if (source['substrat'] !== 'invocation')
221
256
  return e;
257
+ // #1901: async work has no method, path or status — it says what ran and how it ended.
258
+ const kind = invocationKindOf(source['kind']);
259
+ if (kind !== 'request') {
260
+ return {
261
+ ...e,
262
+ invocationId: typeof source['invocationId'] === 'string' ? source['invocationId'] : null,
263
+ message: describeAsync(kind, source),
264
+ level: e.level ?? (typeof source['level'] === 'string' ? source['level'] : null),
265
+ };
266
+ }
222
267
  const method = typeof source['method'] === 'string' ? source['method'] : '?';
223
268
  const path = typeof source['path'] === 'string' ? source['path'] : '?';
224
269
  const status = typeof source['status'] === 'number' ? source['status'] : null;
@@ -239,6 +284,31 @@ function describeInvocation(e) {
239
284
  level: e.level ?? (isFailedInvocation(e) ? 'error' : 'info'),
240
285
  };
241
286
  }
287
+ /**
288
+ * #1901: an async line's message, from its own fields — names and counts only, as the line
289
+ * carries nothing else:
290
+ *
291
+ * - `consumer notify ← ticket.created (attempt 2) → retrying (12 ms)`
292
+ * - `schedule digest/send → ok (40 ms, 1200 ms late)`
293
+ * - `consumer: 5 more lines withheld (consumer:dead-lettered 5)`
294
+ */
295
+ function describeAsync(kind, source) {
296
+ const n = (v) => (typeof v === 'number' ? v : null);
297
+ const outcome = str(source['outcome']) ?? '—';
298
+ if (outcome === 'suppressed') {
299
+ const by = (source['suppressedBy'] ?? {});
300
+ const parts = Object.entries(by).map(([k, v]) => `${k} ${String(v)}`);
301
+ return `${kind}: ${n(source['suppressed']) ?? '?'} more lines withheld${parts.length ? ` (${parts.join(', ')})` : ''}`;
302
+ }
303
+ const operation = str(source['operation']) ?? '?';
304
+ const ms = n(source['durationMs']);
305
+ const late = n(source['latenessMs']);
306
+ const timing = [ms === null ? null : `${ms} ms`, late === null ? null : `${late} ms late`].filter(Boolean).join(', ');
307
+ const subject = kind === 'consumer'
308
+ ? `${operation} ← ${str(source['eventType']) ?? '?'}${n(source['attempt']) === null ? '' : ` (attempt ${n(source['attempt'])})`}`
309
+ : operation;
310
+ return `${kind} ${subject} → ${outcome}${timing ? ` (${timing})` : ''}`;
311
+ }
242
312
  /**
243
313
  * The filters for a tenant's `ctx.log` lines (#1746/#1747). The tenant predicate first and
244
314
  * always, as for the invocation line; everything else is one more equality on a field the
@@ -463,38 +533,17 @@ export function createCfObservabilityReader(opts) {
463
533
  */
464
534
  const telemetry = {
465
535
  async requests(q) {
466
- const { rows, estimated, complete } = await countGrouped(q, 'invocation', [
467
- { type: 'string', value: 'tenantId' },
468
- { type: 'string', value: 'scopeId' },
469
- { type: 'string', value: 'level' },
470
- { type: 'string', value: 'operation' },
471
- { type: 'string', value: 'problemCode' },
472
- { type: 'string', value: 'principalKind' },
473
- { type: 'string', value: 'surface' },
474
- { type: 'number', value: 'status' },
536
+ return requestCube(q);
537
+ },
538
+ // #1901: the async lines alone, for the part of a window the router's datapoints serve.
539
+ async asyncRequests(q) {
540
+ return requestCube(q, [
541
+ {
542
+ kind: 'group',
543
+ filterCombination: 'or',
544
+ filters: ASYNC_KINDS.map((value) => ({ key: 'kind', operation: 'eq', type: 'string', value })),
545
+ },
475
546
  ]);
476
- return {
477
- estimated,
478
- complete,
479
- rows: rows.flatMap(({ bucket, groups, count }) => {
480
- const tenantId = str(groups.get('tenantId'));
481
- if (tenantId === null)
482
- return [];
483
- const status = groups.get('status');
484
- return [{
485
- bucket,
486
- tenantId,
487
- scopeId: str(groups.get('scopeId')),
488
- level: str(groups.get('level')),
489
- operation: str(groups.get('operation')),
490
- problemCode: str(groups.get('problemCode')),
491
- principalKind: str(groups.get('principalKind')),
492
- surface: str(groups.get('surface')),
493
- status: typeof status === 'number' ? status : typeof status === 'string' && status !== '' ? Number(status) : null,
494
- count,
495
- }];
496
- }),
497
- };
498
547
  },
499
548
  async patterns(q) {
500
549
  const { rows, estimated, complete } = await countGrouped(q, 'log', [
@@ -517,6 +566,43 @@ export function createCfObservabilityReader(opts) {
517
566
  };
518
567
  },
519
568
  };
569
+ /** The request cube over stamped lines, grouped by every facet (#1746) and `kind` (#1901). */
570
+ async function requestCube(q, extra = []) {
571
+ const { rows, estimated, complete } = await countGrouped(q, 'invocation', [
572
+ { type: 'string', value: 'tenantId' },
573
+ { type: 'string', value: 'scopeId' },
574
+ { type: 'string', value: 'level' },
575
+ { type: 'string', value: 'operation' },
576
+ { type: 'string', value: 'problemCode' },
577
+ { type: 'string', value: 'principalKind' },
578
+ { type: 'string', value: 'surface' },
579
+ { type: 'number', value: 'status' },
580
+ { type: 'string', value: 'kind' },
581
+ ], extra);
582
+ return {
583
+ estimated,
584
+ complete,
585
+ rows: rows.flatMap(({ bucket, groups, count }) => {
586
+ const tenantId = str(groups.get('tenantId'));
587
+ if (tenantId === null)
588
+ return [];
589
+ const status = groups.get('status');
590
+ return [{
591
+ bucket,
592
+ tenantId,
593
+ scopeId: str(groups.get('scopeId')),
594
+ level: str(groups.get('level')),
595
+ operation: str(groups.get('operation')),
596
+ problemCode: str(groups.get('problemCode')),
597
+ principalKind: str(groups.get('principalKind')),
598
+ surface: str(groups.get('surface')),
599
+ status: typeof status === 'number' ? status : typeof status === 'string' && status !== '' ? Number(status) : null,
600
+ kind: str(groups.get('kind')),
601
+ count,
602
+ }];
603
+ }),
604
+ };
605
+ }
520
606
  const logs = opts.cubeStore ? cachedSource(telemetry, opts.cubeStore) : telemetry;
521
607
  const routerSince = opts.requestsFromRouterSince ? Date.parse(opts.requestsFromRouterSince) : undefined;
522
608
  const routerDataset = opts.routerDataset;
@@ -637,10 +723,13 @@ export function createCfObservabilityReader(opts) {
637
723
  * answer with no order to trust. Only a single grain that is still full is paged, and a
638
724
  * cube built that way is marked incomplete so the cache never keeps it as final.
639
725
  */
640
- async function countGrouped(q, kind, groupBys) {
726
+ async function countGrouped(q, kind, groupBys,
727
+ /** #1901: more filters ANDed on — the async cube's `kind`. */
728
+ extra = []) {
641
729
  const filters = [
642
730
  ...serviceFilter([q.service]),
643
731
  { key: 'substrat', operation: 'eq', type: 'string', value: kind },
732
+ ...extra,
644
733
  ];
645
734
  const once = async (from, to, offsetBy) => {
646
735
  const calc = await queryCalculation(filters, { from, to }, {
@@ -839,6 +928,9 @@ export function createCfObservabilityReader(opts) {
839
928
  async tenantRequests(input) {
840
929
  const events = await queryRaw(requestFilters(input), { from: input.from, to: input.to }, input.limit);
841
930
  return events
931
+ // #1901: the query narrowed on kind already; this holds the answer to the same
932
+ // reading (a missing `kind` is a request) whatever the backend did with the filter.
933
+ .filter((e) => kindMatches(e, input))
842
934
  .sort((a, b) => rawTime(b) - rawTime(a))
843
935
  .slice(0, input.limit)
844
936
  .map(requestRecordOf);