sandlot 0.1.4 → 0.2.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 (115) hide show
  1. package/dist/browser/bundler.d.ts +68 -0
  2. package/dist/browser/bundler.d.ts.map +1 -0
  3. package/dist/browser/executor.d.ts +46 -0
  4. package/dist/browser/executor.d.ts.map +1 -0
  5. package/dist/browser/index.d.ts +9 -0
  6. package/dist/browser/index.d.ts.map +1 -0
  7. package/dist/browser/index.js +2692 -0
  8. package/dist/browser/preset.d.ts +63 -0
  9. package/dist/browser/preset.d.ts.map +1 -0
  10. package/dist/commands/index.d.ts +20 -11
  11. package/dist/commands/index.d.ts.map +1 -1
  12. package/dist/commands/types.d.ts +31 -132
  13. package/dist/commands/types.d.ts.map +1 -1
  14. package/dist/core/bundler-utils.d.ts +142 -0
  15. package/dist/core/bundler-utils.d.ts.map +1 -0
  16. package/dist/core/esm-types-resolver.d.ts +125 -0
  17. package/dist/core/esm-types-resolver.d.ts.map +1 -0
  18. package/dist/core/executor.d.ts +35 -0
  19. package/dist/core/executor.d.ts.map +1 -0
  20. package/dist/{fs.d.ts → core/fs.d.ts} +27 -29
  21. package/dist/core/fs.d.ts.map +1 -0
  22. package/dist/core/sandbox.d.ts +30 -0
  23. package/dist/core/sandbox.d.ts.map +1 -0
  24. package/dist/core/sandlot.d.ts +30 -0
  25. package/dist/core/sandlot.d.ts.map +1 -0
  26. package/dist/core/shared-module-registry.d.ts +46 -0
  27. package/dist/core/shared-module-registry.d.ts.map +1 -0
  28. package/dist/core/typechecker.d.ts +60 -0
  29. package/dist/core/typechecker.d.ts.map +1 -0
  30. package/dist/index.d.ts +11 -16
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1399 -2010
  33. package/dist/node/bundler.d.ts +48 -0
  34. package/dist/node/bundler.d.ts.map +1 -0
  35. package/dist/node/executor.d.ts +48 -0
  36. package/dist/node/executor.d.ts.map +1 -0
  37. package/dist/node/index.d.ts +9 -0
  38. package/dist/node/index.d.ts.map +1 -0
  39. package/dist/node/index.js +2646 -0
  40. package/dist/node/preset.d.ts +62 -0
  41. package/dist/node/preset.d.ts.map +1 -0
  42. package/dist/types.d.ts +525 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/package.json +16 -6
  45. package/src/browser/bundler.ts +294 -0
  46. package/src/browser/executor.ts +71 -0
  47. package/src/browser/index.ts +57 -0
  48. package/src/browser/preset.ts +179 -0
  49. package/src/commands/index.ts +526 -43
  50. package/src/commands/types.ts +82 -146
  51. package/src/core/bundler-utils.ts +630 -0
  52. package/src/core/esm-types-resolver.ts +432 -0
  53. package/src/core/executor.ts +161 -0
  54. package/src/{fs.ts → core/fs.ts} +59 -37
  55. package/src/core/sandbox.ts +621 -0
  56. package/src/core/sandlot.ts +77 -0
  57. package/src/core/shared-module-registry.ts +138 -0
  58. package/src/core/typechecker.ts +607 -0
  59. package/src/index.ts +104 -139
  60. package/src/node/bundler.ts +194 -0
  61. package/src/node/executor.ts +87 -0
  62. package/src/node/index.ts +39 -0
  63. package/src/node/preset.ts +178 -0
  64. package/src/types.ts +668 -0
  65. package/README.md +0 -243
  66. package/dist/build-emitter.d.ts +0 -47
  67. package/dist/build-emitter.d.ts.map +0 -1
  68. package/dist/builder.d.ts +0 -370
  69. package/dist/builder.d.ts.map +0 -1
  70. package/dist/bundler.d.ts +0 -152
  71. package/dist/bundler.d.ts.map +0 -1
  72. package/dist/commands/compile.d.ts +0 -13
  73. package/dist/commands/compile.d.ts.map +0 -1
  74. package/dist/commands/packages.d.ts +0 -17
  75. package/dist/commands/packages.d.ts.map +0 -1
  76. package/dist/commands/run.d.ts +0 -40
  77. package/dist/commands/run.d.ts.map +0 -1
  78. package/dist/commands.d.ts +0 -179
  79. package/dist/commands.d.ts.map +0 -1
  80. package/dist/fs.d.ts.map +0 -1
  81. package/dist/internal.d.ts +0 -79
  82. package/dist/internal.d.ts.map +0 -1
  83. package/dist/internal.js +0 -1942
  84. package/dist/loader.d.ts +0 -164
  85. package/dist/loader.d.ts.map +0 -1
  86. package/dist/packages.d.ts +0 -199
  87. package/dist/packages.d.ts.map +0 -1
  88. package/dist/runner.d.ts +0 -314
  89. package/dist/runner.d.ts.map +0 -1
  90. package/dist/sandbox-manager.d.ts +0 -261
  91. package/dist/sandbox-manager.d.ts.map +0 -1
  92. package/dist/sandbox.d.ts +0 -267
  93. package/dist/sandbox.d.ts.map +0 -1
  94. package/dist/shared-modules.d.ts +0 -148
  95. package/dist/shared-modules.d.ts.map +0 -1
  96. package/dist/shared-resources.d.ts +0 -102
  97. package/dist/shared-resources.d.ts.map +0 -1
  98. package/dist/ts-libs.d.ts +0 -85
  99. package/dist/ts-libs.d.ts.map +0 -1
  100. package/dist/typechecker.d.ts +0 -127
  101. package/dist/typechecker.d.ts.map +0 -1
  102. package/src/build-emitter.ts +0 -64
  103. package/src/builder.ts +0 -498
  104. package/src/bundler.ts +0 -575
  105. package/src/commands/compile.ts +0 -236
  106. package/src/commands/packages.ts +0 -154
  107. package/src/commands/run.ts +0 -245
  108. package/src/internal.ts +0 -119
  109. package/src/loader.ts +0 -229
  110. package/src/packages.ts +0 -936
  111. package/src/sandbox.ts +0 -398
  112. package/src/shared-modules.ts +0 -280
  113. package/src/shared-resources.ts +0 -166
  114. package/src/ts-libs.ts +0 -218
  115. package/src/typechecker.ts +0 -635
@@ -1,102 +0,0 @@
1
- /**
2
- * Shared resources for sandbox environments.
3
- *
4
- * Provides centralized management of expensive shared resources:
5
- * - TypeScript lib files (~5MB) - loaded once, shared across all sandboxes
6
- * - esbuild WASM (~10MB) - singleton bundler initialization
7
- * - Types cache - avoids redundant network fetches when multiple sandboxes
8
- * install the same packages
9
- */
10
- import { type TypesCache } from "./packages";
11
- export type { TypesCache } from "./packages";
12
- export { InMemoryTypesCache } from "./packages";
13
- /**
14
- * Shared resources that can be reused across multiple sandboxes
15
- */
16
- export interface SharedResources {
17
- /**
18
- * Pre-loaded TypeScript lib files for type checking
19
- */
20
- libFiles: Map<string, string>;
21
- /**
22
- * Promise that resolves when the bundler is ready
23
- */
24
- bundlerReady: Promise<void>;
25
- /**
26
- * Cache for package type definitions.
27
- * Avoids redundant network fetches when multiple sandboxes
28
- * install the same packages.
29
- */
30
- typesCache: TypesCache;
31
- }
32
- /**
33
- * Options for creating shared resources
34
- */
35
- export interface SharedResourcesOptions {
36
- /**
37
- * TypeScript libs to load. Defaults to browser libs (ES2020 + DOM).
38
- */
39
- libs?: string[];
40
- /**
41
- * If true, skip fetching TypeScript libs.
42
- * libFiles will be an empty Map.
43
- * Default: false
44
- */
45
- skipLibs?: boolean;
46
- /**
47
- * If true, skip pre-initializing the bundler.
48
- * bundlerReady will resolve immediately.
49
- * Default: false
50
- */
51
- skipBundler?: boolean;
52
- }
53
- /**
54
- * Create a new SharedResources instance.
55
- *
56
- * Use this when you want to manage resource lifecycle explicitly,
57
- * or when you need custom libs configuration.
58
- *
59
- * @example
60
- * ```ts
61
- * // Create resources with custom libs
62
- * const resources = await createSharedResources({
63
- * libs: ['es2022', 'dom', 'webworker'],
64
- * });
65
- *
66
- * // Pass to sandbox creation
67
- * const sandbox = await createSandbox({
68
- * resources,
69
- * fsOptions: { ... },
70
- * });
71
- * ```
72
- */
73
- export declare function createSharedResources(options?: SharedResourcesOptions): Promise<SharedResources>;
74
- /**
75
- * Get the default shared resources singleton.
76
- *
77
- * Loads resources once and returns the same instance for all callers.
78
- * This is the recommended way to get shared resources for most use cases.
79
- *
80
- * @example
81
- * ```ts
82
- * // Get default resources (creates on first call)
83
- * const resources = await getDefaultResources();
84
- *
85
- * // Create multiple sandboxes sharing the same resources
86
- * const sandbox1 = await createSandbox({ resources, ... });
87
- * const sandbox2 = await createSandbox({ resources, ... });
88
- * ```
89
- */
90
- export declare function getDefaultResources(): Promise<SharedResources>;
91
- /**
92
- * Clear the default resources singleton (for testing).
93
- *
94
- * Note: This doesn't unload the bundler WASM - that stays in memory
95
- * until page reload. This only clears the cached lib files reference.
96
- */
97
- export declare function clearDefaultResources(): void;
98
- /**
99
- * Check if the default resources have been initialized.
100
- */
101
- export declare function hasDefaultResources(): boolean;
102
- //# sourceMappingURL=shared-resources.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared-resources.d.ts","sourceRoot":"","sources":["../src/shared-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGjE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B;;OAEG;IACH,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,eAAe,CAAC,CAqB1B;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,CAAC,CAapE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C"}
package/dist/ts-libs.d.ts DELETED
@@ -1,85 +0,0 @@
1
- /**
2
- * TypeScript standard library fetcher and cache.
3
- *
4
- * Fetches TypeScript's lib.*.d.ts files from jsDelivr CDN and caches
5
- * them in memory. These files provide types for built-in JavaScript APIs
6
- * (Array, Number, String) and browser APIs (console, window, document).
7
- */
8
- /**
9
- * Default libs for browser environment with ES2020 target.
10
- * These provide types for console, DOM APIs, and modern JS features.
11
- */
12
- export declare function getDefaultBrowserLibs(): string[];
13
- /**
14
- * Parse `/// <reference lib="..." />` directives from a lib file.
15
- * These directives indicate dependencies on other lib files.
16
- *
17
- * @param content - The content of a lib.*.d.ts file
18
- * @returns Array of lib names referenced (without "lib." prefix or ".d.ts" suffix)
19
- */
20
- export declare function parseLibReferences(content: string): string[];
21
- /**
22
- * Convert a lib name to its filename.
23
- * e.g., "es2020" -> "lib.es2020.d.ts"
24
- */
25
- export declare function libNameToFileName(name: string): string;
26
- /**
27
- * Extract lib name from a file path.
28
- * e.g., "/node_modules/typescript/lib/lib.es2020.d.ts" -> "es2020"
29
- * "lib.dom.d.ts" -> "dom"
30
- */
31
- export declare function extractLibName(filePath: string): string | null;
32
- /**
33
- * Fetch a single lib file from the CDN.
34
- *
35
- * @param name - The lib name (e.g., "es2020", "dom")
36
- * @returns The content of the lib file
37
- * @throws Error if the fetch fails
38
- */
39
- export declare function fetchLibFile(name: string): Promise<string>;
40
- /**
41
- * Recursively fetch all lib files needed for the given libs.
42
- * Parses `/// <reference lib="..." />` directives and fetches dependencies.
43
- *
44
- * @param libs - Initial lib names to fetch (e.g., ["es2020", "dom"])
45
- * @returns Map of lib name to content
46
- */
47
- export declare function fetchAllLibs(libs: string[]): Promise<Map<string, string>>;
48
- /**
49
- * LibCache provides in-memory caching for TypeScript lib files.
50
- *
51
- * Usage:
52
- * ```ts
53
- * const cache = new LibCache();
54
- * const libs = await cache.getOrFetch(getDefaultBrowserLibs());
55
- * ```
56
- */
57
- export declare class LibCache {
58
- /**
59
- * Get cached libs if available, otherwise fetch from CDN and cache.
60
- *
61
- * @param libs - Lib names to fetch (e.g., ["es2020", "dom"])
62
- * @returns Map of lib name to content (includes all transitive dependencies)
63
- */
64
- getOrFetch(libs: string[]): Promise<Map<string, string>>;
65
- /**
66
- * Get cached libs if available.
67
- */
68
- get(): Map<string, string> | null;
69
- /**
70
- * Store libs in the cache.
71
- */
72
- set(libs: Map<string, string>): void;
73
- /**
74
- * Clear all cached libs.
75
- */
76
- clear(): void;
77
- }
78
- /**
79
- * Convenience function to fetch and cache libs in one call.
80
- *
81
- * @param libs - Lib names to fetch (defaults to getDefaultBrowserLibs())
82
- * @returns Map of lib name to content
83
- */
84
- export declare function fetchAndCacheLibs(libs?: string[]): Promise<Map<string, string>>;
85
- //# sourceMappingURL=ts-libs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ts-libs.d.ts","sourceRoot":"","sources":["../src/ts-libs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAY5D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUhE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6C/E;AAQD;;;;;;;;GAQG;AACH,qBAAa,QAAQ;IACnB;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAuB9D;;OAEG;IACH,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAIjC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAIpC;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,GAAE,MAAM,EAA4B,GACvC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAG9B"}
@@ -1,127 +0,0 @@
1
- import type { IFileSystem } from "just-bash/browser";
2
- /**
3
- * Options for type checking
4
- */
5
- export interface TypecheckOptions {
6
- /**
7
- * The virtual filesystem to read source files from
8
- */
9
- fs: IFileSystem;
10
- /**
11
- * Entry point path (absolute path in the virtual filesystem).
12
- * TypeScript will discover all imported files from this root.
13
- */
14
- entryPoint: string;
15
- /**
16
- * Path to tsconfig.json in the virtual filesystem.
17
- * Default: "/tsconfig.json"
18
- */
19
- tsconfigPath?: string;
20
- /**
21
- * Pre-loaded TypeScript lib files (e.g., lib.dom.d.ts, lib.es2020.d.ts).
22
- * Map from lib name (e.g., "dom", "es2020") to file content.
23
- * If provided, enables proper type checking for built-in APIs.
24
- * Use fetchAndCacheLibs() from ts-libs to fetch these.
25
- */
26
- libFiles?: Map<string, string>;
27
- }
28
- /**
29
- * A single diagnostic message from type checking
30
- */
31
- export interface Diagnostic {
32
- /**
33
- * File path where the error occurred (null for global errors)
34
- */
35
- file: string | null;
36
- /**
37
- * 1-based line number (null if not applicable)
38
- */
39
- line: number | null;
40
- /**
41
- * 1-based column number (null if not applicable)
42
- */
43
- column: number | null;
44
- /**
45
- * TypeScript error code (e.g., 2322 for type mismatch)
46
- */
47
- code: number;
48
- /**
49
- * Severity category
50
- */
51
- category: "error" | "warning" | "suggestion" | "message";
52
- /**
53
- * Human-readable error message
54
- */
55
- message: string;
56
- }
57
- /**
58
- * Result of type checking
59
- */
60
- export interface TypecheckResult {
61
- /**
62
- * All diagnostics from type checking
63
- */
64
- diagnostics: Diagnostic[];
65
- /**
66
- * True if there are any errors (not just warnings)
67
- */
68
- hasErrors: boolean;
69
- /**
70
- * List of files that were checked
71
- */
72
- checkedFiles: string[];
73
- }
74
- /**
75
- * Type check TypeScript files from a virtual filesystem
76
- *
77
- * @example
78
- * ```ts
79
- * const fs = Filesystem.create({
80
- * initialFiles: {
81
- * "/tsconfig.json": JSON.stringify({
82
- * compilerOptions: {
83
- * target: "ES2020",
84
- * module: "ESNext",
85
- * strict: true
86
- * }
87
- * }),
88
- * "/src/index.ts": `
89
- * const x: number = "hello"; // Type error!
90
- * export { x };
91
- * `,
92
- * }
93
- * });
94
- *
95
- * const result = await typecheck({
96
- * fs,
97
- * entryPoint: "/src/index.ts",
98
- * });
99
- *
100
- * console.log(result.hasErrors); // true
101
- * console.log(result.diagnostics[0].message); // Type 'string' is not assignable...
102
- * ```
103
- */
104
- export declare function typecheck(options: TypecheckOptions): Promise<TypecheckResult>;
105
- /**
106
- * Format diagnostics as a human-readable string
107
- *
108
- * @example
109
- * ```ts
110
- * const result = await typecheck({ fs, entryPoint: "/src/index.ts" });
111
- * console.log(formatDiagnostics(result.diagnostics));
112
- * // /src/index.ts:3:7 - error TS2322: Type 'string' is not assignable to type 'number'.
113
- * ```
114
- */
115
- export declare function formatDiagnostics(diagnostics: Diagnostic[]): string;
116
- /**
117
- * Format diagnostics in a concise format suitable for AI agents
118
- *
119
- * @example
120
- * ```ts
121
- * const result = await typecheck({ fs, entryPoint: "/src/index.ts" });
122
- * console.log(formatDiagnosticsForAgent(result.diagnostics));
123
- * // Error in /src/index.ts at line 3: Type 'string' is not assignable to type 'number'. (TS2322)
124
- * ```
125
- */
126
- export declare function formatDiagnosticsForAgent(diagnostics: Diagnostic[]): string;
127
- //# sourceMappingURL=typechecker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"typechecker.d.ts","sourceRoot":"","sources":["../src/typechecker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,EAAE,EAAE,WAAW,CAAC;IAEhB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IAEzD;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;IAE1B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAkZD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA2DnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CASnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAwB3E"}
@@ -1,64 +0,0 @@
1
- /**
2
- * Build event emitter for sandbox environments.
3
- *
4
- * Simple typed event emitter for successful build results.
5
- * Used internally by the sandbox to notify listeners when a build succeeds.
6
- */
7
-
8
- import type { BuildOutput } from "./commands/types";
9
-
10
- /**
11
- * Simple typed event emitter for build results.
12
- *
13
- * Only emits on successful builds—build failures are communicated via
14
- * the bash command's exit code and stderr.
15
- *
16
- * For most use cases, prefer using `createBuilder()` which handles
17
- * build result capture automatically.
18
- */
19
- export class BuildEmitter {
20
- private listeners = new Set<(result: BuildOutput) => void | Promise<void>>();
21
-
22
- /**
23
- * Emit a build result to all listeners.
24
- * Called internally when a build command succeeds.
25
- */
26
- emit = async (result: BuildOutput): Promise<void> => {
27
- const promises: Promise<void>[] = [];
28
- for (const listener of this.listeners) {
29
- const ret = listener(result);
30
- if (ret instanceof Promise) {
31
- promises.push(ret);
32
- }
33
- }
34
- await Promise.all(promises);
35
- };
36
-
37
- /**
38
- * Subscribe to build events. Returns an unsubscribe function.
39
- *
40
- * The callback is invoked each time a build succeeds, receiving
41
- * the BuildOutput with the bundle and loaded module.
42
- *
43
- * @example
44
- * ```ts
45
- * let lastBuild: BuildOutput | null = null;
46
- * const unsubscribe = sandbox.onBuild((result) => {
47
- * lastBuild = result;
48
- * });
49
- *
50
- * await sandbox.bash.exec('build /src/index.ts');
51
- * unsubscribe();
52
- *
53
- * if (lastBuild) {
54
- * const App = lastBuild.module.App as React.ComponentType;
55
- * }
56
- * ```
57
- */
58
- on(callback: (result: BuildOutput) => void | Promise<void>): () => void {
59
- this.listeners.add(callback);
60
- return () => {
61
- this.listeners.delete(callback);
62
- };
63
- }
64
- }