@superblocksteam/sdk 2.0.6-next.2 → 2.0.6-next.21

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 (27) hide show
  1. package/dist/application-build.mjs +4 -0
  2. package/dist/application-build.mjs.map +1 -1
  3. package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
  4. package/dist/cli-replacement/automatic-upgrades.js +140 -77
  5. package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
  6. package/dist/dev-utils/dev-server.d.mts.map +1 -1
  7. package/dist/dev-utils/dev-server.mjs +5 -1
  8. package/dist/dev-utils/dev-server.mjs.map +1 -1
  9. package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts +10 -0
  10. package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts.map +1 -0
  11. package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs +27 -0
  12. package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs.map +1 -0
  13. package/dist/dev-utils/vite-plugin-sb-cdn.d.mts.map +1 -1
  14. package/dist/dev-utils/vite-plugin-sb-cdn.mjs +13 -3
  15. package/dist/dev-utils/vite-plugin-sb-cdn.mjs.map +1 -1
  16. package/dist/vite-plugin-generate-build-manifest.d.mts +21 -0
  17. package/dist/vite-plugin-generate-build-manifest.d.mts.map +1 -0
  18. package/dist/vite-plugin-generate-build-manifest.mjs +131 -0
  19. package/dist/vite-plugin-generate-build-manifest.mjs.map +1 -0
  20. package/package.json +6 -4
  21. package/src/application-build.mts +5 -2
  22. package/src/cli-replacement/automatic-upgrades.ts +163 -97
  23. package/src/dev-utils/dev-server.mts +7 -1
  24. package/src/dev-utils/vite-plugin-build-manifest-stub.mts +30 -0
  25. package/src/dev-utils/vite-plugin-sb-cdn.mts +14 -3
  26. package/src/vite-plugin-generate-build-manifest.mts +193 -0
  27. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,21 @@
1
+ import type { Plugin } from "vite";
2
+ export declare const scopeFileBaseName = "scope.ts";
3
+ export declare const apiFileBaseName = "api.yaml";
4
+ /**
5
+ * Vite plugin that generates a build manifest for the application.
6
+ *
7
+ * This plugin will:
8
+ * 1. Read all api.yaml and api.yml files in the application
9
+ * 2. Read all scope.ts files in the application
10
+ * 3. Generate a build manifest for the application
11
+ * 4. Write the build manifest to a file in the build output directory
12
+ *
13
+ * The build manifest is a JSON object with the following properties:
14
+ * - apis: a map of all apis in the application keyed by their file path
15
+ * - apiDependencies: an array where each item represents an api and its dependencies
16
+ *
17
+ * @param root - The root directory of the application
18
+ * @returns A Vite plugin that generates a build manifest for the application
19
+ */
20
+ export declare function generateBuildManifestPlugin(root: string): Plugin;
21
+ //# sourceMappingURL=vite-plugin-generate-build-manifest.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin-generate-build-manifest.d.mts","sourceRoot":"","sources":["../src/vite-plugin-generate-build-manifest.mts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,eAAO,MAAM,eAAe,aAAa,CAAC;AAQ1C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAwGjD,MAAM,CACZ"}
@@ -0,0 +1,131 @@
1
+ import path from "node:path";
2
+ import { parse } from "@babel/parser";
3
+ import { getClientApiId } from "@superblocksteam/library-shared";
4
+ import { resolveLanguageSpecificStepContentFromBlocks } from "@superblocksteam/util";
5
+ import { getPageName } from "@superblocksteam/vite-plugin-file-sync";
6
+ import { extractIdentifierPathsFromApi, extractApiDependencies, } from "@superblocksteam/vite-plugin-file-sync/binding-extraction";
7
+ import { getScope, extractImportsFromAst, } from "@superblocksteam/vite-plugin-file-sync/parsing";
8
+ import { yellow, red } from "colorette";
9
+ import fg from "fast-glob";
10
+ import fs from "fs-extra";
11
+ import { createLogger } from "vite";
12
+ import yaml from "yaml";
13
+ import { getLogger } from "./dev-utils/dev-logger.mjs";
14
+ export const scopeFileBaseName = "scope.ts";
15
+ export const apiFileBaseName = "api.yaml";
16
+ /**
17
+ * Vite plugin that generates a build manifest for the application.
18
+ *
19
+ * This plugin will:
20
+ * 1. Read all api.yaml and api.yml files in the application
21
+ * 2. Read all scope.ts files in the application
22
+ * 3. Generate a build manifest for the application
23
+ * 4. Write the build manifest to a file in the build output directory
24
+ *
25
+ * The build manifest is a JSON object with the following properties:
26
+ * - apis: a map of all apis in the application keyed by their file path
27
+ * - apiDependencies: an array where each item represents an api and its dependencies
28
+ *
29
+ * @param root - The root directory of the application
30
+ * @returns A Vite plugin that generates a build manifest for the application
31
+ */
32
+ export function generateBuildManifestPlugin(root) {
33
+ const viteLogger = createLogger();
34
+ const logger = getLogger();
35
+ viteLogger.info = logger.info;
36
+ viteLogger.warn = (msg) => {
37
+ logger.warn(yellow(msg));
38
+ };
39
+ viteLogger.warnOnce = (msg) => {
40
+ logger.warn(yellow(msg));
41
+ };
42
+ viteLogger.error = (msg) => {
43
+ logger.error(red(msg));
44
+ };
45
+ viteLogger.clearScreen = () => { };
46
+ const scopesByPage = {};
47
+ const apiFiles = {};
48
+ let buildManifest = { apis: {}, apiDependencies: [] };
49
+ return {
50
+ name: "sb-generate-build-manifest",
51
+ apply: "build",
52
+ enforce: "pre",
53
+ async buildStart() {
54
+ const apiDocuments = await fg(["**/api.yaml", "**/api.yml"], {
55
+ cwd: root,
56
+ });
57
+ for (const apiFilePath of apiDocuments) {
58
+ const absoluteApiFilePath = path.join(root, apiFilePath);
59
+ const document = await fs.readFile(absoluteApiFilePath, "utf-8");
60
+ const apiPb = yaml.parse(document);
61
+ await resolveLanguageSpecificStepContentFromBlocks(path.dirname(absoluteApiFilePath), apiPb.blocks ?? [], {});
62
+ const pageName = getPageName(apiFilePath);
63
+ apiPb.metadata.id = getClientApiId(apiPb.metadata.name, pageName);
64
+ apiFiles[apiFilePath] = { apiPb, pageName };
65
+ }
66
+ },
67
+ transform(code, id) {
68
+ if (id.endsWith(scopeFileBaseName)) {
69
+ const ast = parse(code, {
70
+ sourceType: "module",
71
+ sourceFilename: id,
72
+ plugins: [["typescript", {}]],
73
+ });
74
+ const scopeFileMeta = {
75
+ code,
76
+ ast,
77
+ imports: extractImportsFromAst(ast),
78
+ };
79
+ const scope = getScope(id, scopeFileMeta);
80
+ scopesByPage[getPageName(id)] = scope;
81
+ }
82
+ return code;
83
+ },
84
+ async generateBundle() {
85
+ const allApiNames = getAllUniqueApiNames(apiFiles);
86
+ const allApis = Object.entries(apiFiles).reduce((acc, [id, api]) => {
87
+ acc[id] = {
88
+ api,
89
+ scopeId: scopesByPage[api.pageName]?.scopeId ?? "",
90
+ };
91
+ return acc;
92
+ }, {});
93
+ const deps = await getApiDependencies(allApiNames, apiFiles);
94
+ buildManifest = {
95
+ apis: allApis,
96
+ apiDependencies: deps,
97
+ };
98
+ this.emitFile({
99
+ type: "prebuilt-chunk",
100
+ fileName: "assets/build-manifest.js",
101
+ code: `export default ${JSON.stringify(buildManifest)}`,
102
+ exports: ["default"],
103
+ });
104
+ },
105
+ };
106
+ }
107
+ function getAllUniqueApiNames(apiFiles) {
108
+ const allApiNamesSet = new Set(Object.values(apiFiles).map((api) => api.apiPb.metadata.name));
109
+ return Array.from(allApiNamesSet);
110
+ }
111
+ async function getApiDependencies(apiNames, apiFiles) {
112
+ const deps = [];
113
+ // TODO: This logic is a copy of the extractApiParamsAndDependencies function in the
114
+ // fileSyncVitePlugin (https://github.com/superblocksteam/superblocks/blob/474c0b11d79a1d6988864fb20d5ec26f92931fde/packages/vite-plugin-file-sync/src/file-sync-vite-plugin.ts#L261-L280).
115
+ //
116
+ // This logic should be refactored so that it can be shared between the two plugins.
117
+ await Promise.all([
118
+ ...Object.values(apiFiles).map(async (api) => {
119
+ const bindings = await extractIdentifierPathsFromApi(api);
120
+ const allIdentifiers = bindings.flatMap((binding) => binding.bindings);
121
+ const apiDependencies = extractApiDependencies(apiNames, bindings);
122
+ deps.push({
123
+ apiName: api.apiPb.metadata.name,
124
+ params: allIdentifiers,
125
+ dependencies: apiDependencies,
126
+ });
127
+ }),
128
+ ]);
129
+ return deps;
130
+ }
131
+ //# sourceMappingURL=vite-plugin-generate-build-manifest.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin-generate-build-manifest.mjs","sourceRoot":"","sources":["../src/vite-plugin-generate-build-manifest.mts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "2.0.6-next.2",
3
+ "version": "2.0.6-next.21",
4
4
  "type": "module",
5
5
  "description": "Superblocks JS SDK",
6
6
  "homepage": "https://www.superblocks.com",
@@ -30,9 +30,11 @@
30
30
  "@opentelemetry/semantic-conventions": "^1.28.0",
31
31
  "@rollup/wasm-node": "^4.35.0",
32
32
  "@superblocksteam/bucketeer-sdk": "0.5.0",
33
- "@superblocksteam/shared": "0.9160.0",
34
- "@superblocksteam/util": "2.0.6-next.2",
35
- "@superblocksteam/vite-plugin-file-sync": "2.0.6-next.2",
33
+ "@superblocksteam/library": "2.0.6-next.21",
34
+ "@superblocksteam/library-shared": "2.0.6-next.21",
35
+ "@superblocksteam/shared": "0.9198.0",
36
+ "@superblocksteam/util": "2.0.6-next.21",
37
+ "@superblocksteam/vite-plugin-file-sync": "2.0.6-next.21",
36
38
  "@vitejs/plugin-react": "^4.3.4",
37
39
  "axios": "^1.4.0",
38
40
  "chokidar": "^4.0.3",
@@ -9,8 +9,8 @@ import { customComponentsPlugin } from "./dev-utils/custom-build.mjs";
9
9
  import { getLogger } from "./dev-utils/dev-logger.mjs";
10
10
  import { ddRumPlugin } from "./dev-utils/vite-plugin-dd-rum.mjs";
11
11
  import { superblocksCdnPlugin } from "./dev-utils/vite-plugin-sb-cdn.mjs";
12
+ import { generateBuildManifestPlugin } from "./vite-plugin-generate-build-manifest.mjs";
12
13
  import { injectSuperblocksIdsPlugin } from "./vite-plugin-inject-sb-ids-transform.mjs";
13
- import type { Plugin } from "vite";
14
14
 
15
15
  export async function buildApplication({
16
16
  root,
@@ -133,7 +133,7 @@ async function buildWithVite({
133
133
  logLevel: "info",
134
134
  plugins: [
135
135
  tsconfigPaths(),
136
- injectIndexVitePlugin({ assetsCdnUrl, logger }) as Plugin,
136
+ injectIndexVitePlugin({ assetsCdnUrl, logger }),
137
137
  customComponentsPlugin(),
138
138
  injectSuperblocksIdsPlugin(root),
139
139
  superblocksCdnPlugin({
@@ -142,12 +142,15 @@ async function buildWithVite({
142
142
  "react/jsx-runtime": "https://esm.sh/react@18.2.0/jsx-runtime.mjs",
143
143
  "react/jsx-dev-runtime":
144
144
  "https://esm.sh/react@18.2.0/jsx-dev-runtime.mjs",
145
+ "./user-facing/build-manifest.js": "/assets/build-manifest.js",
146
+ "/assets/user-facing/build-manifest.js": "/assets/build-manifest.js",
145
147
  },
146
148
  cssImports: {
147
149
  "@superblocksteam/library/index.css": `${libraryUrl}/index.css`,
148
150
  },
149
151
  }),
150
152
  react(),
153
+ generateBuildManifestPlugin(root),
151
154
 
152
155
  ddRumPlugin({
153
156
  clientToken: ddClientToken ?? "",
@@ -1,11 +1,13 @@
1
1
  import * as child_process from "node:child_process";
2
2
  import { promisify } from "node:util";
3
3
  import { isNativeError } from "node:util/types";
4
+ import { traceFunction } from "@superblocksteam/shared";
4
5
  import { resolveCommand, type DetectResult } from "package-manager-detector";
5
6
  import { detect } from "package-manager-detector/detect";
6
7
  import gt from "semver/functions/gt.js";
7
8
  import valid from "semver/functions/valid.js";
8
9
  import { getLogger } from "../dev-utils/dev-logger.mjs";
10
+ import tracer from "../dev-utils/dev-tracer.js";
9
11
  import type { ResponseMeta } from "../socket/handlers.js";
10
12
  import type { ApplicationConfig } from "../types/common.js";
11
13
  import type { LockService } from "@superblocksteam/vite-plugin-file-sync/lock-service";
@@ -256,106 +258,170 @@ export async function checkVersionsAndUpgrade(
256
258
  lockService: LockService,
257
259
  config?: ApplicationConfig,
258
260
  ) {
259
- // Detect package manager
260
- const pm = await detect({
261
- strategies: [
262
- "packageManager-field",
263
- "lockfile",
264
- "install-metadata",
265
- "devEngines-field",
266
- ],
267
- cwd: process.cwd(),
261
+ const cliUpdated = false;
262
+ const libraryUpdated = false;
263
+ let hasFailedToUpgrade = false;
264
+
265
+ await traceFunction({
266
+ name: "checkVersionsAndUpgrade",
267
+ tracer,
268
+ fn: async () => {
269
+ // Detect package manager
270
+ const pm = await traceFunction({
271
+ name: "detectPackageManager",
272
+ tracer,
273
+ fn: async () => {
274
+ return await detect({
275
+ strategies: [
276
+ "packageManager-field",
277
+ "lockfile",
278
+ "install-metadata",
279
+ "devEngines-field",
280
+ ],
281
+ cwd: process.cwd(),
282
+ });
283
+ },
284
+ });
285
+
286
+ if (!pm || !config?.id) return;
287
+
288
+ // Get current versions
289
+ const currentCliVersion = await traceFunction({
290
+ name: "getCurrentCliVersion",
291
+ tracer,
292
+ fn: async () => {
293
+ return await getCurrentCliVersion();
294
+ },
295
+ });
296
+ const currentLibraryInfo = await traceFunction({
297
+ name: "getCurrentLibraryVersion",
298
+ tracer,
299
+ fn: async () => {
300
+ return await getCurrentLibraryVersion(pm);
301
+ },
302
+ });
303
+
304
+ // Skip if we're in local development
305
+ if (
306
+ !currentCliVersion ||
307
+ !valid(currentCliVersion) ||
308
+ currentCliVersion.startsWith("file:") ||
309
+ currentCliVersion.startsWith("link:") ||
310
+ !currentLibraryInfo ||
311
+ !valid(currentLibraryInfo.version) ||
312
+ currentLibraryInfo.version.startsWith("file:") ||
313
+ currentLibraryInfo.version.startsWith("link:")
314
+ ) {
315
+ return;
316
+ }
317
+
318
+ // Get target versions from server
319
+ const targetVersions = await traceFunction({
320
+ name: "getRemoteVersions",
321
+ tracer,
322
+ fn: async () => {
323
+ return await getRemoteVersions(config);
324
+ },
325
+ });
326
+ if (!targetVersions) return;
327
+
328
+ let cliNeedsUpgrade: boolean | string;
329
+ let libraryNeedsUpgrade: boolean | string;
330
+ try {
331
+ // If version is latest, then semver can throw an error
332
+ // Check if CLI needs upgrade
333
+ cliNeedsUpgrade =
334
+ targetVersions.cli && gt(targetVersions.cli, currentCliVersion);
335
+
336
+ // Check if library needs upgrade
337
+ libraryNeedsUpgrade =
338
+ targetVersions.library &&
339
+ gt(targetVersions.library, currentLibraryInfo.version);
340
+ } catch (error) {
341
+ console.warn(
342
+ "Error checking versions to upgrade, releasing lock and exiting",
343
+ error,
344
+ );
345
+ await traceFunction({
346
+ name: "shutdownLockService",
347
+ tracer,
348
+ fn: async () => {
349
+ await lockService.shutdown({
350
+ serverInitiated: false,
351
+ });
352
+ },
353
+ });
354
+ hasFailedToUpgrade = true;
355
+ return;
356
+ }
357
+
358
+ if (!cliNeedsUpgrade && !libraryNeedsUpgrade) {
359
+ return; // Everything is up to date
360
+ }
361
+
362
+ let cliUpdated = false;
363
+ let libraryUpdated = false;
364
+
365
+ // Upgrade CLI if needed
366
+ if (cliNeedsUpgrade) {
367
+ const oclifUpgradeSucceeded = await traceFunction({
368
+ name: "upgradeCliWithOclif",
369
+ tracer,
370
+ fn: async () => {
371
+ return await upgradeCliWithOclif(targetVersions.cli);
372
+ },
373
+ });
374
+ if (!oclifUpgradeSucceeded) {
375
+ // Fall back to package manager upgrade
376
+ await traceFunction({
377
+ name: "upgradePackageWithPackageManager",
378
+ tracer,
379
+ fn: async () => {
380
+ await upgradePackageWithPackageManager(
381
+ pm,
382
+ "cli",
383
+ targetVersions.cli,
384
+ );
385
+ },
386
+ });
387
+ cliUpdated = true;
388
+ }
389
+ }
390
+
391
+ // Upgrade library if needed
392
+ if (libraryNeedsUpgrade) {
393
+ await traceFunction({
394
+ name: "upgradePackageWithPackageManager",
395
+ tracer,
396
+ fn: async () => {
397
+ await upgradePackageWithPackageManager(
398
+ pm,
399
+ "library",
400
+ targetVersions.library,
401
+ currentLibraryInfo.alias,
402
+ );
403
+ },
404
+ });
405
+ libraryUpdated = true;
406
+ }
407
+
408
+ // Log what was updated
409
+ if (cliUpdated && libraryUpdated) {
410
+ logger.info(
411
+ "@superblocksteam/cli and @superblocksteam/library have been updated.",
412
+ );
413
+ } else if (cliUpdated) {
414
+ logger.info("@superblocksteam/cli has been updated.");
415
+ } else if (libraryUpdated) {
416
+ logger.info("@superblocksteam/library has been updated.");
417
+ }
418
+ },
268
419
  });
269
420
 
270
- if (!pm || !config?.id) return;
271
-
272
- // Get current versions
273
- const currentCliVersion = await getCurrentCliVersion();
274
- const currentLibraryInfo = await getCurrentLibraryVersion(pm);
275
-
276
- // Skip if we're in local development
277
- if (
278
- !currentCliVersion ||
279
- !valid(currentCliVersion) ||
280
- currentCliVersion.startsWith("file:") ||
281
- currentCliVersion.startsWith("link:") ||
282
- !currentLibraryInfo ||
283
- !valid(currentLibraryInfo.version) ||
284
- currentLibraryInfo.version.startsWith("file:") ||
285
- currentLibraryInfo.version.startsWith("link:")
286
- ) {
287
- return;
288
- }
289
-
290
- // Get target versions from server
291
- const targetVersions = await getRemoteVersions(config);
292
- if (!targetVersions) return;
293
-
294
- let cliNeedsUpgrade: boolean | string;
295
- let libraryNeedsUpgrade: boolean | string;
296
- try {
297
- // If version is latest, then semver can throw an error
298
- // Check if CLI needs upgrade
299
- cliNeedsUpgrade =
300
- targetVersions.cli && gt(targetVersions.cli, currentCliVersion);
301
-
302
- // Check if library needs upgrade
303
- libraryNeedsUpgrade =
304
- targetVersions.library &&
305
- gt(targetVersions.library, currentLibraryInfo.version);
306
- } catch (error) {
307
- console.warn(
308
- "Error checking versions to upgrade, releasing lock and exiting",
309
- error,
310
- );
311
- await lockService.shutdown({
312
- serverInitiated: false,
313
- });
314
- process.exit(1);
315
- }
316
-
317
- if (!cliNeedsUpgrade && !libraryNeedsUpgrade) {
318
- return; // Everything is up to date
319
- }
320
-
321
- let cliUpdated = false;
322
- let libraryUpdated = false;
323
-
324
- // Upgrade CLI if needed
325
- if (cliNeedsUpgrade) {
326
- const oclifUpgradeSucceeded = await upgradeCliWithOclif(targetVersions.cli);
327
-
328
- if (!oclifUpgradeSucceeded) {
329
- // Fall back to package manager upgrade
330
- await upgradePackageWithPackageManager(pm, "cli", targetVersions.cli);
331
- cliUpdated = true;
332
- }
333
- }
334
-
335
- // Upgrade library if needed
336
- if (libraryNeedsUpgrade) {
337
- await upgradePackageWithPackageManager(
338
- pm,
339
- "library",
340
- targetVersions.library,
341
- currentLibraryInfo.alias,
342
- );
343
- libraryUpdated = true;
344
- }
345
-
346
- // Log what was updated
347
- if (cliUpdated && libraryUpdated) {
348
- logger.info(
349
- "@superblocksteam/cli and @superblocksteam/library have been updated.",
350
- );
351
- } else if (cliUpdated) {
352
- logger.info("@superblocksteam/cli has been updated.");
353
- } else if (libraryUpdated) {
354
- logger.info("@superblocksteam/library has been updated.");
355
- }
356
-
357
421
  // Restart CLI if anything was updated
358
- if (cliUpdated || libraryUpdated) {
422
+ if (hasFailedToUpgrade) {
423
+ process.exit(1);
424
+ } else if (cliUpdated || libraryUpdated) {
359
425
  logger.info("Restarting the CLI…");
360
426
  await lockService.releaseLock();
361
427
  process.exit(AUTO_UPGRADE_EXIT_CODE);
@@ -19,6 +19,7 @@ import {
19
19
  isCustomComponentsEnabled,
20
20
  } from "./custom-build.mjs";
21
21
  import { getLogger } from "./dev-logger.mjs";
22
+ import { buildManifestStubPlugin } from "./vite-plugin-build-manifest-stub.mjs";
22
23
  import { ddRumPlugin } from "./vite-plugin-dd-rum.mjs";
23
24
  import { superblocksCdnPlugin } from "./vite-plugin-sb-cdn.mjs";
24
25
  import type { AiService } from "@superblocksteam/vite-plugin-file-sync/ai-service";
@@ -276,6 +277,8 @@ async function startVite({
276
277
  const isCustomBuildEnabled = await isCustomComponentsEnabled();
277
278
  const customFolder = path.join(root, "custom");
278
279
 
280
+ const draftsFolder = path.join(root, ".superblocks");
281
+
279
282
  const cdnUrl = process.env.SUPERBLOCKS_CDN_URL ?? "http://localhost:4040/cdn";
280
283
 
281
284
  const env = loadEnv(mode, root, "");
@@ -313,7 +316,7 @@ async function startVite({
313
316
  server: {
314
317
  middlewareMode: true,
315
318
  watch: {
316
- ignored: [`${customFolder}/**/*`],
319
+ ignored: [`${customFolder}/**/*`, `${draftsFolder}/**/*`],
317
320
  },
318
321
  hmr: hmrOptions,
319
322
  cors: {
@@ -347,6 +350,9 @@ async function startVite({
347
350
  { isCustomBuildEnabled },
348
351
  ) as Plugin,
349
352
 
353
+ // Add a virtual "stub" module for the build manifest
354
+ buildManifestStubPlugin(),
355
+
350
356
  // for now, only use the CDN locally
351
357
  superblocksCdnPlugin({
352
358
  imports: {
@@ -0,0 +1,30 @@
1
+ import type { Plugin } from "vite";
2
+
3
+ const BUILD_MANIFEST_MODULE_PATH = "./user-facing/build-manifest.js";
4
+ const VIRTUAL_MODULE_ID = "\0virtual:build-manifest.js";
5
+
6
+ /**
7
+ * This plugin is used to stub the build manifest module. It creates a virtual module
8
+ * for the build manifest module and returns an empty object.
9
+ *
10
+ * This is meant to be used to avoid errors when the build manifest module is not found.
11
+ * This plugin only runs in dev server mode.
12
+ */
13
+ export const buildManifestStubPlugin = (): Plugin => {
14
+ return {
15
+ name: "build-manifest-stub",
16
+ enforce: "pre",
17
+ apply: "serve",
18
+
19
+ resolveId(source) {
20
+ if (source === BUILD_MANIFEST_MODULE_PATH) {
21
+ return VIRTUAL_MODULE_ID;
22
+ }
23
+ },
24
+ load(id) {
25
+ if (id === VIRTUAL_MODULE_ID) {
26
+ return "export default {}";
27
+ }
28
+ },
29
+ };
30
+ };
@@ -224,8 +224,8 @@ async function analyzeModuleGraph(
224
224
  { content: string; binary: ArrayBuffer }
225
225
  > = new Map(),
226
226
  ): Promise<AnalysisResult> {
227
- // Avoid circular dependencies
228
- if (visited.has(url)) {
227
+ // Avoid circular dependencies and skip the shared library's build manifest reference
228
+ if (visited.has(url) || url.endsWith("/user-facing/build-manifest.js")) {
229
229
  return {
230
230
  dependencies: new Set(),
231
231
  content: "",
@@ -474,6 +474,13 @@ const wellKnownPackages = new Map<string, string>([
474
474
  ["react-dom", "https://esm.sh/react-dom@18.2.0"],
475
475
  ["react/jsx-runtime", "https://esm.sh/react@18.2.0/jsx-runtime"],
476
476
  ["react/jsx-dev-runtime", "https://esm.sh/react@18.2.0/jsx-dev-runtime"],
477
+ ["./user-facing/build-manifest.js", "/assets/build-manifest.js"],
478
+ ["/assets/user-facing/build-manifest.js", "/assets/build-manifest.js"],
479
+ ]);
480
+
481
+ const packagesToExcludeFromCdnRedirect = new Set<string>([
482
+ "./user-facing/build-manifest.js",
483
+ "/assets/user-facing/build-manifest.js",
477
484
  ]);
478
485
 
479
486
  const react18CdnUrl = "https://esm.sh/react@18.2.0";
@@ -773,8 +780,12 @@ export async function superblocksCdnPlugin(
773
780
  // Externalize modules specified in the import map
774
781
  // The cdn: prefix ensures they're properly resolved to the CDN URL
775
782
  if (imports.includes(id)) {
783
+ const shouldRedirectToCdn = !packagesToExcludeFromCdnRedirect.has(id);
776
784
  debug(`Externalizing module for CDN resolution: ${id}`);
777
- return { id: `cdn:${id}`, external: true };
785
+ return {
786
+ id: `${shouldRedirectToCdn ? "cdn:" : ""}${id}`,
787
+ external: true,
788
+ };
778
789
  }
779
790
 
780
791
  return null;