@alloy-js/core 0.24.0-dev.1 → 0.24.0-dev.2

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 (34) hide show
  1. package/dist/dev/src/debug/cli.browser.js +14 -0
  2. package/dist/dev/src/debug/cli.browser.js.map +1 -0
  3. package/dist/dev/src/debug/trace-db.browser.js +11 -0
  4. package/dist/dev/src/debug/trace-db.browser.js.map +1 -0
  5. package/dist/dev/src/debug/trace-db.js +40 -0
  6. package/dist/dev/src/debug/trace-db.js.map +1 -0
  7. package/dist/dev/src/debug/trace-writer.js +3 -24
  8. package/dist/dev/src/debug/trace-writer.js.map +1 -1
  9. package/dist/dev/test/browser-build.test.js +70 -9
  10. package/dist/dev/test/browser-build.test.js.map +1 -1
  11. package/dist/src/debug/cli.browser.d.ts +13 -0
  12. package/dist/src/debug/cli.browser.d.ts.map +1 -0
  13. package/dist/src/debug/cli.browser.js +14 -0
  14. package/dist/src/debug/cli.browser.js.map +1 -0
  15. package/dist/src/debug/trace-db.browser.d.ts +9 -0
  16. package/dist/src/debug/trace-db.browser.d.ts.map +1 -0
  17. package/dist/src/debug/trace-db.browser.js +11 -0
  18. package/dist/src/debug/trace-db.browser.js.map +1 -0
  19. package/dist/src/debug/trace-db.d.ts +16 -0
  20. package/dist/src/debug/trace-db.d.ts.map +1 -0
  21. package/dist/src/debug/trace-db.js +40 -0
  22. package/dist/src/debug/trace-db.js.map +1 -0
  23. package/dist/src/debug/trace-writer.d.ts.map +1 -1
  24. package/dist/src/debug/trace-writer.js +3 -24
  25. package/dist/src/debug/trace-writer.js.map +1 -1
  26. package/dist/test/browser-build.test.js +70 -9
  27. package/dist/test/browser-build.test.js.map +1 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +6 -2
  30. package/src/debug/cli.browser.ts +17 -0
  31. package/src/debug/trace-db.browser.ts +12 -0
  32. package/src/debug/trace-db.ts +42 -0
  33. package/src/debug/trace-writer.ts +5 -27
  34. package/test/browser-build.test.ts +81 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alloy-js/core",
3
- "version": "0.24.0-dev.1",
3
+ "version": "0.24.0-dev.2",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,7 +50,11 @@
50
50
  "./dist/src/debug/source-map.js": "./dist/src/debug/source-map.browser.js",
51
51
  "./src/debug/source-map.ts": "./src/debug/source-map.browser.ts",
52
52
  "./dist/src/devtools/devtools-server.js": "./dist/src/devtools/devtools-server.browser.js",
53
- "./src/devtools/devtools-server.ts": "./src/devtools/devtools-server.browser.ts"
53
+ "./src/devtools/devtools-server.ts": "./src/devtools/devtools-server.browser.ts",
54
+ "./dist/src/debug/trace-db.js": "./dist/src/debug/trace-db.browser.js",
55
+ "./src/debug/trace-db.ts": "./src/debug/trace-db.browser.ts",
56
+ "./dist/src/debug/cli.js": "./dist/src/debug/cli.browser.js",
57
+ "./src/debug/cli.ts": "./src/debug/cli.browser.ts"
54
58
  },
55
59
  "keywords": [],
56
60
  "author": "brian.terlson@microsoft.com",
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Browser stub for CLI debug utilities.
3
+ *
4
+ * Replaces `cli.ts` in browser builds so that `cli-table3` and
5
+ * `picocolors` (Node-only packages) are never imported.
6
+ * All functions are no-ops since CLI debugging is not relevant in browsers.
7
+ */
8
+
9
+ export function debugStack(): void {}
10
+
11
+ export function debugContext(): void {}
12
+
13
+ export function debugTree(): void {}
14
+
15
+ export function debugWatch(): void {}
16
+
17
+ export function debugRender(): void {}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Browser stub for trace database initialization.
3
+ *
4
+ * Replaces `trace-db.ts` in browser builds. Returns null so that
5
+ * all trace-writer functions (which guard on `if (!db) return`) become no-ops.
6
+ */
7
+
8
+ export type DatabaseSync = null;
9
+
10
+ export async function openTraceDatabase(_path: string): Promise<null> {
11
+ return null;
12
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Database initialization for the trace writer.
3
+ *
4
+ * Isolates the `node:sqlite` and `node:fs` dependencies so that
5
+ * `trace-writer.ts` itself remains browser-safe (all functions no-op
6
+ * when db is null). In browser builds this module is replaced by
7
+ * `trace-db.browser.ts` which always returns null.
8
+ */
9
+ import type { DatabaseSync as DatabaseSyncType } from "node:sqlite";
10
+
11
+ export type { DatabaseSyncType as DatabaseSync };
12
+
13
+ /**
14
+ * Opens a fresh SQLite database at the given path, removing any existing file.
15
+ * Returns the opened database instance.
16
+ */
17
+ export async function openTraceDatabase(
18
+ path: string,
19
+ ): Promise<DatabaseSyncType> {
20
+ const { DatabaseSync } = await import("node:sqlite");
21
+ const fs = await import("node:fs");
22
+ // Remove existing trace file so each run starts fresh
23
+ try {
24
+ fs.unlinkSync(path);
25
+ } catch {
26
+ /* ignore missing */
27
+ }
28
+ try {
29
+ fs.unlinkSync(path + "-wal");
30
+ } catch {
31
+ /* ignore missing */
32
+ }
33
+ try {
34
+ fs.unlinkSync(path + "-shm");
35
+ } catch {
36
+ /* ignore missing */
37
+ }
38
+ const db = new DatabaseSync(path);
39
+ db.exec("PRAGMA journal_mode=WAL");
40
+ db.exec("PRAGMA synchronous=NORMAL");
41
+ return db;
42
+ }
@@ -5,12 +5,10 @@
5
5
  * built-in `node:sqlite` module. The database can be queried by the
6
6
  * `alloy-trace` CLI or the devtools WebSocket server.
7
7
  */
8
- import type {
9
- DatabaseSync as DatabaseSyncType,
10
- StatementSync,
11
- } from "node:sqlite";
8
+ import type { StatementSync } from "node:sqlite";
9
+ import { type DatabaseSync, openTraceDatabase } from "./trace-db.js";
12
10
 
13
- let db: DatabaseSyncType | null = null;
11
+ let db: DatabaseSync | null = null;
14
12
  let seq = 0;
15
13
 
16
14
  // Prepared statements (initialized in initTrace)
@@ -133,28 +131,8 @@ export function queryChannel(
133
131
  }
134
132
 
135
133
  export async function initTrace(path: string): Promise<void> {
136
- // Dynamic import to avoid failing in environments without node:sqlite
137
- const { DatabaseSync } = await import("node:sqlite");
138
- const fs = await import("node:fs");
139
- // Remove existing trace file so each run starts fresh
140
- try {
141
- fs.unlinkSync(path);
142
- } catch {
143
- /* ignore missing */
144
- }
145
- try {
146
- fs.unlinkSync(path + "-wal");
147
- } catch {
148
- /* ignore missing */
149
- }
150
- try {
151
- fs.unlinkSync(path + "-shm");
152
- } catch {
153
- /* ignore missing */
154
- }
155
- db = new DatabaseSync(path);
156
- db.exec("PRAGMA journal_mode=WAL");
157
- db.exec("PRAGMA synchronous=NORMAL");
134
+ db = await openTraceDatabase(path);
135
+ if (!db) return;
158
136
  createSchema();
159
137
  prepareStatements();
160
138
  }
@@ -1,29 +1,74 @@
1
1
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
2
- import { join } from "path";
2
+ import { join, resolve } from "path";
3
3
  import { build, type Rolldown } from "vite";
4
4
  import { afterAll, beforeAll, describe, expect, it } from "vitest";
5
5
 
6
6
  const tempDir = join(__dirname, ".temp", "browser-build-test");
7
7
  const entryFile = join(tempDir, "entry.js");
8
8
 
9
+ // Absolute path to the compiled browser entry point.
10
+ const corePkgDir = resolve(__dirname, "..");
11
+ const browserEntry = resolve(corePkgDir, "dist/src/index.browser.js");
12
+
9
13
  /**
10
14
  * Bundles `@alloy-js/core` for the browser using Vite and returns
11
- * the concatenated output code.
15
+ * the concatenated output code and any warnings emitted during the build.
12
16
  *
13
- * Uses the `browser` export condition from the package exports map,
14
- * which resolves to the compiled browser entry. This requires the
15
- * package to be built first (the CI pipeline and `pnpm build` handle
16
- * this automatically).
17
+ * Uses a custom resolveId plugin to force the browser entry point,
18
+ * because vitest's `resolve.conditions: ["source"]` leaks into the
19
+ * Vite build() call even with `configFile: false`, causing the test
20
+ * to resolve TypeScript source files instead of compiled dist.
17
21
  */
18
- async function bundleForBrowser(): Promise<string> {
22
+ async function bundleForBrowser(): Promise<{
23
+ code: string;
24
+ warnings: string[];
25
+ }> {
26
+ const warnings: string[] = [];
19
27
  const result = await build({
20
28
  configFile: false,
21
29
  logLevel: "silent",
22
30
  resolve: {
23
31
  conditions: ["browser", "import"],
32
+ mainFields: ["browser", "module", "main"],
24
33
  },
25
34
  // Disable automatic process.env replacement so we can detect leaks
26
35
  define: {},
36
+ plugins: [
37
+ {
38
+ name: "force-browser-entry",
39
+ enforce: "pre",
40
+ resolveId(source) {
41
+ // Force @alloy-js/core to resolve to the compiled browser entry,
42
+ // bypassing vitest's "source" condition that would resolve to TS.
43
+ if (source === "@alloy-js/core") {
44
+ return browserEntry;
45
+ }
46
+ return null;
47
+ },
48
+ },
49
+ {
50
+ name: "capture-warnings",
51
+ enforce: "post",
52
+ buildStart() {
53
+ // Hook into Vite's warning channel via rollup options
54
+ },
55
+ },
56
+ ],
57
+ customLogger: {
58
+ info() {},
59
+ error() {},
60
+ clearScreen() {},
61
+ hasErrorLogged() {
62
+ return false;
63
+ },
64
+ hasWarned: false,
65
+ warnOnce(msg: string) {
66
+ warnings.push(msg);
67
+ },
68
+ warn(msg: string) {
69
+ warnings.push(msg);
70
+ },
71
+ },
27
72
  build: {
28
73
  write: false,
29
74
  minify: false,
@@ -41,6 +86,13 @@ async function bundleForBrowser(): Promise<string> {
41
86
  // Externalize third-party deps (vue, pathe, picocolors, …)
42
87
  return true;
43
88
  },
89
+ onwarn(warning) {
90
+ warnings.push(
91
+ typeof warning === "string" ? warning : (
92
+ (warning.message ?? String(warning))
93
+ ),
94
+ );
95
+ },
44
96
  },
45
97
  },
46
98
  });
@@ -52,7 +104,7 @@ async function bundleForBrowser(): Promise<string> {
52
104
  const chunks = output.output.filter(
53
105
  (o): o is Rolldown.OutputChunk => o.type === "chunk",
54
106
  );
55
- return chunks.map((c) => c.code).join("\n");
107
+ return { code: chunks.map((c) => c.code).join("\n"), warnings };
56
108
  }
57
109
 
58
110
  describe("browser build", () => {
@@ -71,7 +123,10 @@ describe("browser build", () => {
71
123
  });
72
124
 
73
125
  it("should bundle for browser without Node.js polyfills", async () => {
74
- const code = await bundleForBrowser();
126
+ const { code, warnings } = await bundleForBrowser();
127
+
128
+ // Sanity check: the bundle should not be empty
129
+ expect(code.length).toBeGreaterThan(0);
75
130
 
76
131
  // The browser bundle must not reference the Node.js `process` global.
77
132
  // If this fails, a file is using process.env / process.cwd / etc.
@@ -80,5 +135,22 @@ describe("browser build", () => {
80
135
 
81
136
  // Should not contain static require("node:…") calls
82
137
  expect(code).not.toMatch(/require\(\s*["']node:/);
138
+
139
+ // Should not contain dynamic import("node:…") calls — these are the
140
+ // ones esbuild and other browser bundlers reject (e.g. node:sqlite, node:fs).
141
+ expect(code).not.toMatch(/import\(\s*["']node:/);
142
+
143
+ // Vite silently externalizes node:* modules for browser builds via its
144
+ // built-in rolldown:vite-resolve plugin, which hides the issue from the
145
+ // code assertions above. Catch those by checking for externalization warnings.
146
+ const nodeExternalizationWarnings = warnings.filter(
147
+ (w) =>
148
+ w.includes("externalized for browser compatibility") ||
149
+ w.includes("node:"),
150
+ );
151
+ expect(
152
+ nodeExternalizationWarnings,
153
+ `Node.js modules were externalized for browser compatibility — missing browser shims:\n${nodeExternalizationWarnings.join("\n")}`,
154
+ ).toEqual([]);
83
155
  }, 30_000);
84
156
  });