@superblocksteam/sdk 2.0.119-next.1 → 2.0.120-next.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 (85) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/cli-replacement/dev-s3-restore.test.mjs +116 -0
  3. package/dist/cli-replacement/dev-s3-restore.test.mjs.map +1 -1
  4. package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs +1 -0
  5. package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs.map +1 -1
  6. package/dist/cli-replacement/dev.d.mts +6 -0
  7. package/dist/cli-replacement/dev.d.mts.map +1 -1
  8. package/dist/cli-replacement/dev.mjs +77 -6
  9. package/dist/cli-replacement/dev.mjs.map +1 -1
  10. package/dist/client.d.ts +67 -6
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +94 -0
  13. package/dist/client.js.map +1 -1
  14. package/dist/dev-utils/dedupe-async.d.ts +16 -0
  15. package/dist/dev-utils/dedupe-async.d.ts.map +1 -0
  16. package/dist/dev-utils/dedupe-async.js +27 -0
  17. package/dist/dev-utils/dedupe-async.js.map +1 -0
  18. package/dist/dev-utils/dedupe-async.test.d.ts +2 -0
  19. package/dist/dev-utils/dedupe-async.test.d.ts.map +1 -0
  20. package/dist/dev-utils/dedupe-async.test.js +120 -0
  21. package/dist/dev-utils/dedupe-async.test.js.map +1 -0
  22. package/dist/dev-utils/dev-server-metrics.d.mts +95 -0
  23. package/dist/dev-utils/dev-server-metrics.d.mts.map +1 -0
  24. package/dist/dev-utils/dev-server-metrics.mjs +193 -0
  25. package/dist/dev-utils/dev-server-metrics.mjs.map +1 -0
  26. package/dist/dev-utils/dev-server-persist.test.mjs +117 -17
  27. package/dist/dev-utils/dev-server-persist.test.mjs.map +1 -1
  28. package/dist/dev-utils/dev-server.d.mts +19 -1
  29. package/dist/dev-utils/dev-server.d.mts.map +1 -1
  30. package/dist/dev-utils/dev-server.mjs +296 -28
  31. package/dist/dev-utils/dev-server.mjs.map +1 -1
  32. package/dist/flag.d.ts +1 -1
  33. package/dist/flag.d.ts.map +1 -1
  34. package/dist/flag.js +3 -3
  35. package/dist/flag.js.map +1 -1
  36. package/dist/index.d.ts +4 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +3 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/sdk.d.ts +8 -1
  41. package/dist/sdk.d.ts.map +1 -1
  42. package/dist/sdk.js +24 -1
  43. package/dist/sdk.js.map +1 -1
  44. package/dist/sdk.test.js +102 -1
  45. package/dist/sdk.test.js.map +1 -1
  46. package/dist/telemetry/index.d.ts +2 -1
  47. package/dist/telemetry/index.d.ts.map +1 -1
  48. package/dist/telemetry/index.js +8 -1
  49. package/dist/telemetry/index.js.map +1 -1
  50. package/dist/telemetry/logging.d.ts +1 -2
  51. package/dist/telemetry/logging.d.ts.map +1 -1
  52. package/dist/telemetry/logging.js +1 -1
  53. package/dist/telemetry/logging.js.map +1 -1
  54. package/dist/telemetry/memory-metrics.d.ts +3 -0
  55. package/dist/telemetry/memory-metrics.d.ts.map +1 -0
  56. package/dist/telemetry/memory-metrics.js +59 -0
  57. package/dist/telemetry/memory-metrics.js.map +1 -0
  58. package/dist/types/common.d.ts +1 -1
  59. package/dist/types/common.d.ts.map +1 -1
  60. package/dist/version-control.d.mts.map +1 -1
  61. package/dist/version-control.mjs +14 -19
  62. package/dist/version-control.mjs.map +1 -1
  63. package/eslint.config.js +6 -0
  64. package/package.json +8 -8
  65. package/src/cli-replacement/dev-s3-restore.test.mts +156 -0
  66. package/src/cli-replacement/dev-startup-git-before-dbfs-order.test.mts +1 -0
  67. package/src/cli-replacement/dev.mts +104 -14
  68. package/src/client.ts +189 -6
  69. package/src/dev-utils/dedupe-async.test.ts +151 -0
  70. package/src/dev-utils/dedupe-async.ts +45 -0
  71. package/src/dev-utils/dev-server-metrics.mts +252 -0
  72. package/src/dev-utils/dev-server-persist.test.mts +170 -19
  73. package/src/dev-utils/dev-server.mts +366 -32
  74. package/src/flag.ts +4 -4
  75. package/src/index.ts +19 -1
  76. package/src/sdk.test.ts +145 -6
  77. package/src/sdk.ts +36 -0
  78. package/src/telemetry/index.ts +9 -1
  79. package/src/telemetry/logging.ts +2 -2
  80. package/src/telemetry/memory-metrics.ts +90 -0
  81. package/src/types/common.ts +1 -1
  82. package/src/version-control.mts +11 -30
  83. package/test/version-control.test.mts +0 -2
  84. package/tsconfig.tsbuildinfo +1 -1
  85. package/turbo.json +1 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Dev-server connection-phase metrics.
3
+ *
4
+ * Records counters and histograms for the dev-server endpoints that the editor
5
+ * and SABS hit during a live-edit connection: `/_sb_health`, `/_sb_connect`,
6
+ * `/_sb_activate`, `/_sb_disconnect`, `/_sb_status`, `/_sb_activity`, plus
7
+ * WebSocket upgrades, Vite eager-init, and warm-standby activation.
8
+ *
9
+ * Metrics are scoped to the dev-server's existing OTel pipeline. When telemetry
10
+ * has not yet initialized (warm-standby pre-activation), record calls are
11
+ * buffered and replayed by `flush()` once `configureTelemetry` completes, so
12
+ * warm-standby observations are not silently dropped into the no-op meter.
13
+ */
14
+ import { isTelemetryInitialized } from "@superblocksteam/telemetry";
15
+ import { getMeter } from "../telemetry/index.js";
16
+ /**
17
+ * Allowlisted HTTP methods recorded as the `method` metric label. Anything
18
+ * outside this set — `req.method` is client-controlled, and `/_sb_health` is
19
+ * unauthenticated — is bucketed as `'OTHER'` to keep label cardinality bounded.
20
+ */
21
+ const ALLOWED_METHODS = new Set([
22
+ "GET",
23
+ "HEAD",
24
+ "POST",
25
+ "PUT",
26
+ "PATCH",
27
+ "DELETE",
28
+ "OPTIONS",
29
+ ]);
30
+ function sanitizeMethod(method) {
31
+ const upper = method.toUpperCase();
32
+ return ALLOWED_METHODS.has(upper) ? upper : "OTHER";
33
+ }
34
+ /**
35
+ * Soft cap on buffered pre-init events. Warm-standby reasonably emits ~1
36
+ * `recordWarmPrewarm` + ~1 `recordWarmActivation` before activation, so the
37
+ * cap is generously above the expected load — it exists only to bound memory
38
+ * if `flush()` is somehow never called.
39
+ */
40
+ const MAX_BUFFERED_EVENTS = 256;
41
+ /**
42
+ * Records dev-server connection-phase metrics.
43
+ *
44
+ * Calls made before `configureTelemetry` completes are queued and replayed by
45
+ * `flush()` once telemetry is online. Without this, warm-standby observations
46
+ * are routed through `getMeter()`'s no-op fallback meter and silently dropped
47
+ * — defeating the metric's purpose, since warm activation is exactly the path
48
+ * we want to observe. The buffer is bounded to bound memory; instruments are
49
+ * still NOT cached, so each replayed call resolves a fresh meter.
50
+ */
51
+ class DevServerMetrics {
52
+ /**
53
+ * Pre-init replay queue. Entries are bound `() => void` recorders that close
54
+ * over their args at call time, so labels are captured even if the buffer is
55
+ * drained much later.
56
+ */
57
+ bufferedRecorders = [];
58
+ /**
59
+ * Routes a recorder to the live OTel meter when telemetry is up, or buffers
60
+ * it for replay when telemetry has not yet initialized.
61
+ */
62
+ record(recorder) {
63
+ if (isTelemetryInitialized()) {
64
+ recorder();
65
+ return;
66
+ }
67
+ if (this.bufferedRecorders.length >= MAX_BUFFERED_EVENTS) {
68
+ // Drop the oldest event rather than the new one — the most recent
69
+ // observations are typically the most informative for an investigator.
70
+ this.bufferedRecorders.shift();
71
+ }
72
+ this.bufferedRecorders.push(recorder);
73
+ }
74
+ /**
75
+ * Replays buffered recorders against the (now-initialized) meter and clears
76
+ * the queue. Idempotent — safe to call multiple times. Callers should invoke
77
+ * this immediately after `configureTelemetry()` resolves.
78
+ *
79
+ * No-ops if telemetry did not actually come up (e.g., `configureTelemetry`
80
+ * returned `false` due to a missing config or an internal init failure).
81
+ * Draining the buffer through a still-no-op meter would silently lose every
82
+ * observation AND clear the queue, so a later successful re-init via
83
+ * `onTokenReceived` could not recover them. Keeping the buffer intact lets
84
+ * a subsequent `flush()` call replay them once telemetry is genuinely live.
85
+ */
86
+ flush() {
87
+ if (!isTelemetryInitialized()) {
88
+ return;
89
+ }
90
+ if (this.bufferedRecorders.length === 0) {
91
+ return;
92
+ }
93
+ const events = this.bufferedRecorders;
94
+ this.bufferedRecorders = [];
95
+ for (const e of events) {
96
+ e();
97
+ }
98
+ }
99
+ /**
100
+ * Records the outcome of a dev-server HTTP endpoint request.
101
+ */
102
+ recordEndpoint(endpoint, method, status, durationMs, failureType = "none") {
103
+ const labels = {
104
+ endpoint,
105
+ method: sanitizeMethod(method),
106
+ status: String(status),
107
+ failure_type: failureType,
108
+ };
109
+ this.record(() => {
110
+ const meter = getMeter();
111
+ meter
112
+ .createCounter("dev_server_endpoint_requests_total", {
113
+ description: "Count of dev-server endpoint requests by endpoint, status, and failure type.",
114
+ })
115
+ .add(1, labels);
116
+ meter
117
+ .createHistogram("dev_server_endpoint_duration_ms", {
118
+ description: "Latency of dev-server endpoint requests in milliseconds.",
119
+ unit: "ms",
120
+ })
121
+ .record(durationMs, labels);
122
+ });
123
+ }
124
+ /**
125
+ * Records a WebSocket upgrade attempt against the dev-server's HTTP socket.
126
+ */
127
+ recordSocketUpgrade(outcome) {
128
+ this.record(() => {
129
+ getMeter()
130
+ .createCounter("dev_server_socket_upgrade_total", {
131
+ description: "Count of WebSocket upgrade attempts against the dev-server HTTP socket.",
132
+ })
133
+ .add(1, { outcome });
134
+ });
135
+ }
136
+ /**
137
+ * Records the duration and outcome of Vite eager-init (the call that creates
138
+ * the user-facing Vite server during /_sb_connect ramp-up).
139
+ */
140
+ recordViteEagerInit(durationMs, outcome) {
141
+ this.record(() => {
142
+ getMeter()
143
+ .createHistogram("dev_server_vite_eager_init_duration_ms", {
144
+ description: "Duration of eager Vite server initialization in milliseconds.",
145
+ unit: "ms",
146
+ })
147
+ .record(durationMs, { outcome });
148
+ });
149
+ }
150
+ /**
151
+ * Records the duration and outcome of warm-pod Vite dep-cache pre-warm.
152
+ */
153
+ recordWarmPrewarm(durationMs, outcome) {
154
+ this.record(() => {
155
+ getMeter()
156
+ .createHistogram("dev_server_warm_prewarm_duration_ms", {
157
+ description: "Duration of warm-standby Vite dep-cache pre-warm in milliseconds.",
158
+ unit: "ms",
159
+ })
160
+ .record(durationMs, { outcome });
161
+ });
162
+ }
163
+ /**
164
+ * Records a warm-standby activation request outcome.
165
+ */
166
+ recordWarmActivation(outcome) {
167
+ this.record(() => {
168
+ getMeter()
169
+ .createCounter("dev_server_warm_activation_total", {
170
+ description: "Count of warm-standby /_sb_activate requests by outcome.",
171
+ })
172
+ .add(1, { outcome });
173
+ });
174
+ }
175
+ /**
176
+ * Records the time from receiving a successful /_sb_activate POST to the
177
+ * full Express dev-server being attached to the warm HTTP server (the
178
+ * "no-port-gap" handoff window — gateways see 502s if this stretches).
179
+ */
180
+ recordWarmHandoff(durationMs) {
181
+ this.record(() => {
182
+ getMeter()
183
+ .createHistogram("dev_server_warm_activation_handoff_duration_ms", {
184
+ description: "Time from /_sb_activate acceptance to full dev server attached, in milliseconds.",
185
+ unit: "ms",
186
+ })
187
+ .record(durationMs);
188
+ });
189
+ }
190
+ }
191
+ /** Process-wide dev-server metrics singleton. */
192
+ export const devServerMetrics = new DevServerMetrics();
193
+ //# sourceMappingURL=dev-server-metrics.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-server-metrics.mjs","sourceRoot":"","sources":["../../src/dev-utils/dev-server-metrics.mts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
1
  import { EventEmitter } from "node:events";
2
+ import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
2
5
  import { PassThrough } from "node:stream";
3
- import { describe, expect, it, vi } from "vitest";
6
+ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
4
7
  const { spawnMock } = vi.hoisted(() => ({
5
8
  spawnMock: vi.fn(),
6
9
  }));
@@ -15,6 +18,10 @@ vi.mock("node:child_process", async () => {
15
18
  spawn: spawnMock,
16
19
  };
17
20
  });
21
+ // Use a static import so the slow `dev-server.mjs` module graph (vite, react
22
+ // plugin, workspace deps) loads during file evaluation rather than inside each
23
+ // test, where the cold-import cost easily exceeds the default 5s test timeout.
24
+ import { createWorkspacePersistArchive, getSuperblocksTarExcludes, } from "./dev-server.mjs";
18
25
  function createMockProcess() {
19
26
  return Object.assign(new EventEmitter(), {
20
27
  stdin: new PassThrough(),
@@ -22,8 +29,44 @@ function createMockProcess() {
22
29
  stderr: new PassThrough(),
23
30
  });
24
31
  }
32
+ describe("getSuperblocksTarExcludes", () => {
33
+ let tempRoot;
34
+ beforeAll(() => {
35
+ tempRoot = mkdtempSync(join(tmpdir(), "persist-test-"));
36
+ });
37
+ afterAll(() => {
38
+ rmSync(tempRoot, { recursive: true, force: true });
39
+ });
40
+ it("excludes .superblocks entirely when the directory does not exist", () => {
41
+ const result = getSuperblocksTarExcludes(tempRoot);
42
+ expect(result).toEqual(["--exclude", ".superblocks"]);
43
+ });
44
+ it("excludes subdirs not in the safelist and keeps context/drafts", () => {
45
+ const sb = join(tempRoot, ".superblocks");
46
+ mkdirSync(sb);
47
+ mkdirSync(join(sb, "context"));
48
+ mkdirSync(join(sb, "drafts"));
49
+ mkdirSync(join(sb, "recordings"));
50
+ mkdirSync(join(sb, "scratch"));
51
+ mkdirSync(join(sb, "system-skills"));
52
+ const result = getSuperblocksTarExcludes(tempRoot);
53
+ // Safelisted dirs must NOT appear
54
+ expect(result).not.toContain(".superblocks/context");
55
+ expect(result).not.toContain(".superblocks/drafts");
56
+ // Non-safelisted dirs must be excluded
57
+ expect(result).toContain(".superblocks/recordings");
58
+ expect(result).toContain(".superblocks/scratch");
59
+ expect(result).toContain(".superblocks/system-skills");
60
+ // Each excluded dir has a preceding --exclude flag
61
+ for (const name of ["recordings", "scratch", "system-skills"]) {
62
+ const idx = result.indexOf(`.superblocks/${name}`);
63
+ expect(idx).toBeGreaterThan(0);
64
+ expect(result[idx - 1]).toBe("--exclude");
65
+ }
66
+ });
67
+ });
25
68
  describe("createWorkspacePersistArchive", () => {
26
- it("excludes node_modules from the tar archive", async () => {
69
+ it("archive respects excludes", async () => {
27
70
  const tarProc = createMockProcess();
28
71
  const zstdProc = createMockProcess();
29
72
  spawnMock.mockImplementation((command) => {
@@ -37,23 +80,13 @@ describe("createWorkspacePersistArchive", () => {
37
80
  });
38
81
  return zstdProc;
39
82
  });
40
- const { createWorkspacePersistArchive } = await import("./dev-server.mjs");
41
83
  await expect(createWorkspacePersistArchive("/workspace")).resolves.toEqual(Buffer.from("archive"));
42
84
  const tarCall = spawnMock.mock.calls.find(([command]) => command === "tar");
43
85
  expect(tarCall).toBeDefined();
44
- expect(tarCall?.[1]).toEqual([
45
- "cf",
46
- "-",
47
- "--exclude",
48
- ".git",
49
- "--exclude",
50
- "node_modules",
51
- "--exclude",
52
- ".superblocks",
53
- "-C",
54
- "/workspace",
55
- ".",
56
- ]);
86
+ const args = tarCall?.[1];
87
+ // Standard excludes are always present
88
+ expect(args).toContain(".git");
89
+ expect(args).toContain("node_modules");
57
90
  });
58
91
  it("rejects if tar fails after zstd closes successfully", async () => {
59
92
  const tarProc = createMockProcess();
@@ -70,8 +103,75 @@ describe("createWorkspacePersistArchive", () => {
70
103
  });
71
104
  return zstdProc;
72
105
  });
73
- const { createWorkspacePersistArchive } = await import("./dev-server.mjs");
74
106
  await expect(createWorkspacePersistArchive("/workspace")).rejects.toThrowError(/^tar archival failed \(code 2\): tar failed$/);
75
107
  });
76
108
  });
109
+ describe("createWorkspacePersistUploadHeaders", () => {
110
+ it("forwards presigned upload headers and adds the archive content length", async () => {
111
+ const { createWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
112
+ expect(createWorkspacePersistUploadHeaders(123, {
113
+ "Content-Type": "application/custom-zstd",
114
+ "x-amz-server-side-encryption": "AES256",
115
+ })).toEqual({
116
+ "content-length": "123",
117
+ "content-type": "application/custom-zstd",
118
+ "x-amz-server-side-encryption": "AES256",
119
+ });
120
+ });
121
+ it("normalizes presigned upload header names case-insensitively", async () => {
122
+ const { createWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
123
+ expect(createWorkspacePersistUploadHeaders(789, {
124
+ "content-type": "application/custom-zstd",
125
+ "content-length": "1",
126
+ "x-amz-server-side-encryption": "AES256",
127
+ })).toEqual({
128
+ "content-length": "789",
129
+ "content-type": "application/custom-zstd",
130
+ "x-amz-server-side-encryption": "AES256",
131
+ });
132
+ });
133
+ it("keeps the legacy content headers when SABS sends only a URL", async () => {
134
+ const { createWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
135
+ expect(createWorkspacePersistUploadHeaders(456)).toEqual({
136
+ "content-length": "456",
137
+ "content-type": "application/zstd",
138
+ });
139
+ });
140
+ });
141
+ describe("isWorkspacePersistUploadHeaders", () => {
142
+ it("accepts undefined (legacy SABS payloads with no uploadHeaders)", async () => {
143
+ const { isWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
144
+ expect(isWorkspacePersistUploadHeaders(undefined)).toBe(true);
145
+ });
146
+ it("accepts a valid string map", async () => {
147
+ const { isWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
148
+ expect(isWorkspacePersistUploadHeaders({
149
+ "content-type": "application/zstd",
150
+ "x-amz-server-side-encryption": "AES256",
151
+ })).toBe(true);
152
+ });
153
+ it("rejects null, arrays, and non-string values", async () => {
154
+ const { isWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
155
+ expect(isWorkspacePersistUploadHeaders(null)).toBe(false);
156
+ expect(isWorkspacePersistUploadHeaders([])).toBe(false);
157
+ expect(isWorkspacePersistUploadHeaders({ "x-foo": 1 })).toBe(false);
158
+ });
159
+ it("rejects case-insensitive duplicate keys", async () => {
160
+ const { isWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
161
+ expect(isWorkspacePersistUploadHeaders({
162
+ "Content-Type": "application/zstd",
163
+ "content-type": "application/custom-zstd",
164
+ })).toBe(false);
165
+ });
166
+ it("rejects header names with illegal characters", async () => {
167
+ const { isWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
168
+ // Spaces are not allowed in HTTP token names.
169
+ expect(isWorkspacePersistUploadHeaders({ "bad header": "value" })).toBe(false);
170
+ });
171
+ it("rejects header values with illegal characters", async () => {
172
+ const { isWorkspacePersistUploadHeaders } = await import("./dev-server.mjs");
173
+ // CR/LF in header values is not allowed (header injection guard).
174
+ expect(isWorkspacePersistUploadHeaders({ "x-foo": "bad\r\nvalue" })).toBe(false);
175
+ });
176
+ });
77
177
  //# sourceMappingURL=dev-server-persist.test.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server-persist.test.mjs","sourceRoot":"","sources":["../../src/dev-utils/dev-server-persist.test.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev-server-persist.test.mjs","sourceRoot":"","sources":["../../src/dev-utils/dev-server-persist.test.mts"],"names":[],"mappings":"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"}
@@ -5,7 +5,16 @@ import type { LockService } from "@superblocksteam/vite-plugin-file-sync/lock-se
5
5
  import type { OperationQueue } from "@superblocksteam/vite-plugin-file-sync/operation-queue";
6
6
  import type { SyncService } from "@superblocksteam/vite-plugin-file-sync/sync-service";
7
7
  import type { SuperblocksSdk } from "../sdk.js";
8
+ /**
9
+ * Build tar --exclude flags for .superblocks/ subdirectories that are NOT
10
+ * in the safelist. If .superblocks/ doesn't exist we exclude it entirely.
11
+ */
12
+ export declare function getSuperblocksTarExcludes(root: string): string[];
8
13
  export declare function createWorkspacePersistArchive(root: string): Promise<Buffer<ArrayBufferLike>>;
14
+ export declare function createWorkspacePersistUploadHeaders(archiveLength: number, uploadHeaders?: Record<string, string>): {
15
+ [k: string]: string;
16
+ };
17
+ export declare function isWorkspacePersistUploadHeaders(uploadHeaders: unknown): uploadHeaders is Record<string, string> | undefined;
9
18
  export declare const RESTART_EXIT_CODE = 98;
10
19
  interface CreateDevServerOptions {
11
20
  root: string;
@@ -30,8 +39,17 @@ interface CreateDevServerOptions {
30
39
  * causes 502s from the gateway during the warm -> full server transition.
31
40
  */
32
41
  existingServer?: http.Server;
42
+ /**
43
+ * Wall-clock timestamp (Date.now()) when the warm-standby /_sb_activate POST
44
+ * was accepted. When provided, the dev server records the elapsed time from
45
+ * activation acceptance to full Express handler attachment as the
46
+ * `dev_server_warm_activation_handoff_duration_ms` histogram — the window
47
+ * during which the gateway can return 502s if the warm server stops
48
+ * responding before the full server takes over.
49
+ */
50
+ warmActivationStart?: number;
33
51
  }
34
- export declare function createDevServer({ root, mode, fsOperationQueue, syncService, lockService, aiService, gitService, gitBootstrapFailed, activateGitService, snapshotManager, logger: loggerOverride, port, sdk, superblocksBaseUrl: explicitBaseUrl, existingServer, }: CreateDevServerOptions): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
52
+ export declare function createDevServer({ root, mode, fsOperationQueue, syncService, lockService, aiService, gitService, gitBootstrapFailed, activateGitService, snapshotManager, logger: loggerOverride, port, sdk, superblocksBaseUrl: explicitBaseUrl, existingServer, warmActivationStart, }: CreateDevServerOptions): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
35
53
  export declare function preWarmViteCache(root: string): Promise<void>;
36
54
  export {};
37
55
  //# sourceMappingURL=dev-server.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.d.mts","sourceRoot":"","sources":["../../src/dev-utils/dev-server.mts"],"names":[],"mappings":"AAEA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAwBlC,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EAChB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oDAAoD,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qDAAqD,CAAC;AACvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qDAAqD,CAAC;AAGvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAyFhD,wBAAsB,6BAA6B,CAAC,IAAI,EAAE,MAAM,oCAwF/D;AAED,eAAO,MAAM,iBAAiB,KAAK,CAAC;AA6CpC,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,cAAc,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,MAAM,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;CAC9B;AAKD,wBAAsB,eAAe,CAAC,EACpC,IAAI,EACJ,IAAI,EACJ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,MAAM,EAAE,cAAc,EACtB,IAAI,EACJ,GAAG,EACH,kBAAkB,EAAE,eAAe,EACnC,cAAc,GACf,EAAE,sBAAsB,iFAqgBxB;AAiND,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgClE"}
1
+ {"version":3,"file":"dev-server.d.mts","sourceRoot":"","sources":["../../src/dev-utils/dev-server.mts"],"names":[],"mappings":"AAEA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAwBlC,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EAChB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oDAAoD,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qDAAqD,CAAC;AACvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qDAAqD,CAAC;AAGvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA6JhD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAahE;AAED,wBAAsB,6BAA6B,CAAC,IAAI,EAAE,MAAM,oCAuF/D;AAED,wBAAgB,mCAAmC,CACjD,aAAa,EAAE,MAAM,EACrB,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;;EAQ3C;AAED,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,OAAO,GACrB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAqCrD;AAED,eAAO,MAAM,iBAAiB,KAAK,CAAC;AA6CpC,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,cAAc,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC,MAAM,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAC1C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AA2CD,wBAAsB,eAAe,CAAC,EACpC,IAAI,EACJ,IAAI,EACJ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,MAAM,EAAE,cAAc,EACtB,IAAI,EACJ,GAAG,EACH,kBAAkB,EAAE,eAAe,EACnC,cAAc,EACd,mBAAmB,GACpB,EAAE,sBAAsB,iFAyoBxB;AAiND,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ClE"}