@superblocksteam/sdk 2.0.0-next.13 → 2.0.0-next.131

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 (55) hide show
  1. package/dist/application-build.d.mts +12 -0
  2. package/dist/application-build.d.mts.map +1 -0
  3. package/dist/application-build.mjs +113 -0
  4. package/dist/application-build.mjs.map +1 -0
  5. package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
  6. package/dist/cli-replacement/automatic-upgrades.js +19 -5
  7. package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
  8. package/dist/cli-replacement/dev.d.mts.map +1 -1
  9. package/dist/cli-replacement/dev.mjs +7 -0
  10. package/dist/cli-replacement/dev.mjs.map +1 -1
  11. package/dist/client.d.ts +2 -1
  12. package/dist/client.d.ts.map +1 -1
  13. package/dist/client.js +7 -5
  14. package/dist/client.js.map +1 -1
  15. package/dist/dev-utils/dev-server.d.mts.map +1 -1
  16. package/dist/dev-utils/dev-server.mjs +30 -8
  17. package/dist/dev-utils/dev-server.mjs.map +1 -1
  18. package/dist/dev-utils/dev-tracer.d.ts.map +1 -1
  19. package/dist/dev-utils/dev-tracer.js +19 -0
  20. package/dist/dev-utils/dev-tracer.js.map +1 -1
  21. package/dist/dev-utils/vite-plugin-react-transform.d.mts.map +1 -1
  22. package/dist/dev-utils/vite-plugin-react-transform.mjs +1 -0
  23. package/dist/dev-utils/vite-plugin-react-transform.mjs.map +1 -1
  24. package/dist/dev-utils/vite-plugin-sb-cdn.d.mts.map +1 -1
  25. package/dist/dev-utils/vite-plugin-sb-cdn.mjs +28 -7
  26. package/dist/dev-utils/vite-plugin-sb-cdn.mjs.map +1 -1
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/socket/handlers.d.ts +2 -2
  32. package/dist/socket/handlers.d.ts.map +1 -1
  33. package/dist/socket/handlers.js.map +1 -1
  34. package/dist/socket/index.d.ts +1 -11
  35. package/dist/socket/index.d.ts.map +1 -1
  36. package/dist/socket/index.js +11 -43
  37. package/dist/socket/index.js.map +1 -1
  38. package/dist/vite-plugin-inject-sb-ids-transform.d.mts +15 -0
  39. package/dist/vite-plugin-inject-sb-ids-transform.d.mts.map +1 -0
  40. package/dist/vite-plugin-inject-sb-ids-transform.mjs +86 -0
  41. package/dist/vite-plugin-inject-sb-ids-transform.mjs.map +1 -0
  42. package/package.json +16 -7
  43. package/src/application-build.mts +160 -0
  44. package/src/cli-replacement/automatic-upgrades.ts +22 -8
  45. package/src/cli-replacement/dev.mts +10 -0
  46. package/src/client.ts +13 -4
  47. package/src/dev-utils/dev-server.mts +39 -8
  48. package/src/dev-utils/dev-tracer.ts +18 -0
  49. package/src/dev-utils/vite-plugin-react-transform.mts +1 -0
  50. package/src/dev-utils/vite-plugin-sb-cdn.mts +35 -7
  51. package/src/index.ts +2 -0
  52. package/src/socket/handlers.ts +109 -105
  53. package/src/socket/index.ts +21 -101
  54. package/src/vite-plugin-inject-sb-ids-transform.mts +104 -0
  55. package/tsconfig.tsbuildinfo +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "2.0.0-next.13",
3
+ "version": "2.0.0-next.131",
4
4
  "type": "module",
5
5
  "description": "Superblocks JS SDK",
6
6
  "homepage": "https://www.superblocks.com",
@@ -16,18 +16,23 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
+ "@babel/core": "7.24.0",
20
+ "@babel/generator": "^7.25.7",
21
+ "@babel/parser": "^7.25.8",
22
+ "@babel/traverse": "^7.25.7",
19
23
  "@opentelemetry/api": "^1.9.0",
20
24
  "@opentelemetry/context-async-hooks": "^2.0.1",
21
- "@opentelemetry/resources": "^1.28.0",
22
- "@opentelemetry/semantic-conventions": "^1.28.0",
25
+ "@opentelemetry/exporter-trace-otlp-http": "^0.55.0",
23
26
  "@opentelemetry/instrumentation-express": "^0.45.0",
24
27
  "@opentelemetry/instrumentation-http": "^0.55.0",
28
+ "@opentelemetry/resources": "^1.28.0",
25
29
  "@opentelemetry/sdk-node": "^0.55.0",
30
+ "@opentelemetry/semantic-conventions": "^1.28.0",
26
31
  "@rollup/wasm-node": "^4.35.0",
27
- "@superblocksteam/bucketeer-sdk": "0.4.1",
28
- "@superblocksteam/shared": "0.9122.0",
29
- "@superblocksteam/util": "2.0.0-next.13",
30
- "@superblocksteam/vite-plugin-file-sync": "2.0.0-next.13",
32
+ "@superblocksteam/bucketeer-sdk": "0.5.0",
33
+ "@superblocksteam/shared": "0.9160.0",
34
+ "@superblocksteam/util": "2.0.0-next.131",
35
+ "@superblocksteam/vite-plugin-file-sync": "2.0.0-next.131",
31
36
  "@vitejs/plugin-react": "^4.3.4",
32
37
  "axios": "^1.4.0",
33
38
  "chokidar": "^4.0.3",
@@ -55,7 +60,11 @@
55
60
  "yaml": "^2.4.2"
56
61
  },
57
62
  "devDependencies": {
63
+ "@babel/types": "^7.25.8",
58
64
  "@eslint/js": "^9.16.0",
65
+ "@types/babel__core": "^7.20.5",
66
+ "@types/babel__generator": "^7.6.8",
67
+ "@types/babel__traverse": "^7.20.6",
59
68
  "@types/chai": "^4",
60
69
  "@types/chai-as-promised": "^8.0.2",
61
70
  "@types/common-tags": "^1.8.4",
@@ -0,0 +1,160 @@
1
+ import path from "node:path";
2
+ import { injectIndexVitePlugin } from "@superblocksteam/vite-plugin-file-sync/inject-index";
3
+ import react from "@vitejs/plugin-react";
4
+ import { yellow, red } from "colorette";
5
+ import fs from "fs-extra";
6
+ import { build, createLogger } from "vite";
7
+ import tsconfigPaths from "vite-tsconfig-paths";
8
+ import { customComponentsPlugin } from "./dev-utils/custom-build.mjs";
9
+ import { getLogger } from "./dev-utils/dev-logger.mjs";
10
+ import { ddRumPlugin } from "./dev-utils/vite-plugin-dd-rum.mjs";
11
+ import { superblocksCdnPlugin } from "./dev-utils/vite-plugin-sb-cdn.mjs";
12
+ import { injectSuperblocksIdsPlugin } from "./vite-plugin-inject-sb-ids-transform.mjs";
13
+ import type { Plugin } from "vite";
14
+
15
+ export async function buildApplication({
16
+ root,
17
+ dest,
18
+ mode,
19
+ libraryUrl,
20
+ assetsCdnUrl,
21
+ ddClientToken,
22
+ ddApplicationId,
23
+ ddEnv,
24
+ ddVersion,
25
+ }: {
26
+ root: string;
27
+ dest: string;
28
+ mode: string;
29
+ libraryUrl: string;
30
+ assetsCdnUrl?: string;
31
+ ddClientToken?: string;
32
+ ddApplicationId?: string;
33
+ ddEnv?: string;
34
+ ddVersion?: string;
35
+ }) {
36
+ const cwd = process.cwd();
37
+ try {
38
+ // Ensure the root directory exists and change execution context to it
39
+ if (!(await fs.pathExists(root))) {
40
+ throw new Error(`Root directory "${root}" does not exist`);
41
+ }
42
+
43
+ process.chdir(root);
44
+ await buildWithVite({
45
+ root: fs.realpathSync(root),
46
+ dest: fs.realpathSync(dest),
47
+ mode,
48
+ libraryUrl,
49
+ assetsCdnUrl,
50
+ ddClientToken,
51
+ ddApplicationId,
52
+ ddEnv,
53
+ ddVersion,
54
+ });
55
+ } finally {
56
+ // Restore the original working directory before returning
57
+ process.chdir(cwd);
58
+ }
59
+ }
60
+
61
+ async function buildWithVite({
62
+ root,
63
+ dest,
64
+ mode,
65
+ libraryUrl,
66
+ assetsCdnUrl,
67
+ ddClientToken,
68
+ ddApplicationId,
69
+ ddEnv,
70
+ ddVersion,
71
+ }: {
72
+ root: string;
73
+ dest: string;
74
+ mode: string;
75
+ libraryUrl: string;
76
+ assetsCdnUrl?: string;
77
+ ddClientToken?: string;
78
+ ddApplicationId?: string;
79
+ ddEnv?: string;
80
+ ddVersion?: string;
81
+ }) {
82
+ const viteLogger = createLogger();
83
+ const logger = getLogger();
84
+ viteLogger.info = logger.info;
85
+ viteLogger.warn = (msg: string) => {
86
+ logger.warn(yellow(msg));
87
+ };
88
+ viteLogger.warnOnce = (msg: string) => {
89
+ logger.warn(yellow(msg));
90
+ };
91
+ viteLogger.error = (msg: string) => {
92
+ logger.error(red(msg));
93
+ };
94
+
95
+ viteLogger.clearScreen = () => {};
96
+
97
+ const customFolder = path.join(root, "custom");
98
+
99
+ await build({
100
+ root,
101
+ mode,
102
+ appType: "spa",
103
+ resolve: {
104
+ alias: {
105
+ "react-router": "@superblocksteam/library",
106
+ },
107
+ },
108
+ clearScreen: true,
109
+ optimizeDeps: {
110
+ include: ["lodash", "react-is"],
111
+ exclude: [],
112
+ },
113
+ build: {
114
+ outDir: dest,
115
+ emptyOutDir: true,
116
+ write: true,
117
+ commonjsOptions: {
118
+ include: ["react-is"],
119
+ transformMixedEsModules: true,
120
+ },
121
+ rollupOptions: {
122
+ external: [
123
+ `${customFolder}/**/*`,
124
+ "react",
125
+ "react-dom",
126
+ "react/jsx-runtime",
127
+ "react/jsx-dev-runtime",
128
+ ],
129
+ preserveEntrySignatures: "allow-extension",
130
+ output: { format: "esm" },
131
+ },
132
+ },
133
+ logLevel: "info",
134
+ plugins: [
135
+ tsconfigPaths(),
136
+ injectIndexVitePlugin({ assetsCdnUrl, logger }) as Plugin,
137
+ customComponentsPlugin(),
138
+ injectSuperblocksIdsPlugin(root),
139
+ superblocksCdnPlugin({
140
+ imports: {
141
+ "@superblocksteam/library": `${libraryUrl}/index.js`,
142
+ "react/jsx-runtime": "https://esm.sh/react@18.2.0/jsx-runtime.mjs",
143
+ "react/jsx-dev-runtime":
144
+ "https://esm.sh/react@18.2.0/jsx-dev-runtime.mjs",
145
+ },
146
+ cssImports: {
147
+ "@superblocksteam/library/index.css": `${libraryUrl}/index.css`,
148
+ },
149
+ }),
150
+ react(),
151
+
152
+ ddRumPlugin({
153
+ clientToken: ddClientToken ?? "",
154
+ applicationId: ddApplicationId ?? "",
155
+ env: ddEnv ?? "prod",
156
+ version: ddVersion ?? "1.0.0",
157
+ }),
158
+ ],
159
+ });
160
+ }
@@ -277,14 +277,28 @@ export async function checkVersionsAndUpgrade(
277
277
  const targetVersions = await getRemoteVersions(config);
278
278
  if (!targetVersions) return;
279
279
 
280
- // Check if CLI needs upgrade
281
- const cliNeedsUpgrade =
282
- targetVersions.cli && gt(targetVersions.cli, currentCliVersion);
283
-
284
- // Check if library needs upgrade
285
- const libraryNeedsUpgrade =
286
- targetVersions.library &&
287
- gt(targetVersions.library, currentLibraryInfo.version);
280
+ let cliNeedsUpgrade: boolean | string;
281
+ let libraryNeedsUpgrade: boolean | string;
282
+ try {
283
+ // If version is latest, then semver can throw an error
284
+ // Check if CLI needs upgrade
285
+ cliNeedsUpgrade =
286
+ targetVersions.cli && gt(targetVersions.cli, currentCliVersion);
287
+
288
+ // Check if library needs upgrade
289
+ libraryNeedsUpgrade =
290
+ targetVersions.library &&
291
+ gt(targetVersions.library, currentLibraryInfo.version);
292
+ } catch (error) {
293
+ console.warn(
294
+ "Error checking versions to upgrade, releasing lock and exiting",
295
+ error,
296
+ );
297
+ await lockService.shutdown({
298
+ serverInitiated: false,
299
+ });
300
+ process.exit(1);
301
+ }
288
302
 
289
303
  if (!cliNeedsUpgrade && !libraryNeedsUpgrade) {
290
304
  return; // Everything is up to date
@@ -2,6 +2,7 @@ import "../dev-utils/dev-tracer.js";
2
2
 
3
3
  import * as child_process from "node:child_process";
4
4
  import * as fsp from "node:fs/promises";
5
+ import path from "node:path";
5
6
  import { promisify } from "node:util";
6
7
  import { maskUnixSignals } from "@superblocksteam/util";
7
8
  import { AiService } from "@superblocksteam/vite-plugin-file-sync/ai-service";
@@ -13,6 +14,7 @@ import { OperationQueue } from "@superblocksteam/vite-plugin-file-sync/operation
13
14
  import { SyncService } from "@superblocksteam/vite-plugin-file-sync/sync-service";
14
15
  import { green } from "colorette";
15
16
  import { diffJson } from "diff";
17
+ import fs from "fs-extra";
16
18
  import { resolveCommand } from "package-manager-detector";
17
19
  import { detect } from "package-manager-detector/detect";
18
20
 
@@ -115,6 +117,13 @@ export async function dev(options: {
115
117
  applicationConfig,
116
118
  } = options;
117
119
 
120
+ // Add check for node_modules
121
+ if (!fs.existsSync(path.join(cwd, "node_modules"))) {
122
+ throw new Error(
123
+ 'node_modules folder is missing. Please run "npm install" first.',
124
+ );
125
+ }
126
+
118
127
  if (pidfilePath) {
119
128
  await fsp.writeFile(pidfilePath, `${process.pid}\n`);
120
129
  }
@@ -198,6 +207,7 @@ export async function dev(options: {
198
207
  anthropicApiKey: process.env.ANTHROPIC_API_KEY || "",
199
208
  fsOperationQueue,
200
209
  draftInterface: syncService! as DraftInterface,
210
+ tracer,
201
211
  });
202
212
 
203
213
  const isSynced = localContents.hash === serverHash;
package/src/client.ts CHANGED
@@ -1,4 +1,5 @@
1
- import * as fs from "fs";
1
+ import * as fs from "node:fs";
2
+ import path from "node:path";
2
3
  import { Bucketeer, FileDescriptor } from "@superblocksteam/bucketeer-sdk";
3
4
  import { ExportViewMode } from "@superblocksteam/shared";
4
5
  import {
@@ -1269,13 +1270,15 @@ export async function uploadApplication({
1269
1270
  scopedJwt,
1270
1271
  url,
1271
1272
  cliVersion,
1273
+ appRoot,
1272
1274
  }: {
1273
1275
  files: string[];
1274
1276
  scopedJwt: string;
1275
1277
  url: string;
1276
1278
  cliVersion: string;
1279
+ appRoot?: string;
1277
1280
  }) {
1278
- const fds = filesToFileDescriptors(files);
1281
+ const fds = filesToFileDescriptors(files, appRoot);
1279
1282
  const bucketeer = new Bucketeer({
1280
1283
  token: scopedJwt,
1281
1284
  baseUrl: url,
@@ -1285,9 +1288,15 @@ export async function uploadApplication({
1285
1288
  await bucketeer.uploadApplication(fds);
1286
1289
  }
1287
1290
 
1288
- function filesToFileDescriptors(files: string[]) {
1291
+ function filesToFileDescriptors(files: string[], appRoot?: string) {
1289
1292
  const fds = files.map((file) => {
1290
- return new FileDescriptor(file, fs.createReadStream(file));
1293
+ const relativePath = appRoot ? path.relative(appRoot, file) : undefined;
1294
+ return new FileDescriptor(
1295
+ file,
1296
+ fs.createReadStream(file),
1297
+ undefined,
1298
+ relativePath,
1299
+ );
1291
1300
  });
1292
1301
  return fds;
1293
1302
  }
@@ -84,11 +84,23 @@ export async function createDevServer({
84
84
  viteReject = reject;
85
85
  });
86
86
 
87
- async function gracefulShutdown(logger: ReturnType<typeof getLogger>) {
87
+ async function gracefulShutdown({
88
+ logger,
89
+ serverInitiated,
90
+ switchingTo,
91
+ initiatedByEmail,
92
+ }: {
93
+ logger: ReturnType<typeof getLogger>;
94
+ serverInitiated: boolean;
95
+ switchingTo?: "local" | "cloud" | "none";
96
+ initiatedByEmail?: string;
97
+ }) {
88
98
  try {
89
- if (lockService?.isLocked) {
90
- await lockService.shutdown();
91
- }
99
+ await lockService?.shutdown({
100
+ serverInitiated,
101
+ switchingTo,
102
+ initiatedByEmail,
103
+ });
92
104
  // Cleanup the vite server
93
105
  if (viteServer) {
94
106
  await viteServer?.close();
@@ -118,6 +130,7 @@ export async function createDevServer({
118
130
  credentials: true,
119
131
  }),
120
132
  );
133
+ app.use(express.json());
121
134
 
122
135
  app.use((req, res, next) => {
123
136
  res.setHeader("Cache-Control", "no-store, max-age=0");
@@ -174,11 +187,29 @@ export async function createDevServer({
174
187
  }, viteReject);
175
188
  });
176
189
 
190
+ // TODO(code-mode): remove this soon
177
191
  app.get("/_sb_disconnect", async (_req, res) => {
192
+ console.log("GET /_sb_disconnect");
178
193
  // TODO(code-mode): should this include any validation checks, such as getting a token?
179
- await gracefulShutdown(logger);
194
+ await gracefulShutdown({ logger, serverInitiated: false });
180
195
  res.send("ok");
181
196
  });
197
+ app.post("/_sb_disconnect", async (req, res) => {
198
+ const { initiatedByEmail, switchingTo } = req.body;
199
+ // TODO(code-mode): should this include any validation checks, such as getting a token?
200
+ try {
201
+ await gracefulShutdown({
202
+ logger,
203
+ serverInitiated: true,
204
+ switchingTo,
205
+ initiatedByEmail: initiatedByEmail as string | undefined,
206
+ });
207
+ res.send("ok");
208
+ } catch (e) {
209
+ console.error("Error disconnecting from dev server", e);
210
+ res.status(500).send("Error disconnecting from dev server");
211
+ }
212
+ });
182
213
 
183
214
  app.get("/_sb_status", async (_req, res) => {
184
215
  res.setHeader("Content-Type", "application/json");
@@ -195,17 +226,17 @@ export async function createDevServer({
195
226
 
196
227
  process.on("SIGINT", async () => {
197
228
  logger.info("SIGINT received");
198
- await gracefulShutdown(logger);
229
+ await gracefulShutdown({ logger, serverInitiated: false });
199
230
  });
200
231
 
201
232
  process.on("SIGTERM", async () => {
202
233
  logger.info("SIGTERM received");
203
- await gracefulShutdown(logger);
234
+ await gracefulShutdown({ logger, serverInitiated: false });
204
235
  });
205
236
 
206
237
  process.on("SIGABRT", async () => {
207
238
  logger.info("SIGABRT received");
208
- await gracefulShutdown(logger);
239
+ await gracefulShutdown({ logger, serverInitiated: false });
209
240
  });
210
241
 
211
242
  httpServer = await app.listen(port);
@@ -1,15 +1,29 @@
1
1
  import { trace } from "@opentelemetry/api";
2
2
  import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
3
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
3
4
  import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
4
5
  import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
5
6
  import { Resource } from "@opentelemetry/resources";
6
7
  import { NodeSDK } from "@opentelemetry/sdk-node";
7
8
  import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
9
+ import { getLocalTokenWithUrl } from "@superblocksteam/util";
8
10
  import packageJson from "../../package.json" with { type: "json" };
9
11
  import type { Span } from "@opentelemetry/api";
10
12
 
11
13
  // NOTE: @joeyagreco - this is how the "env" facet is determined in datadog: https://docs.datadoghq.com/opentelemetry/setup/collector_exporter/#3---configure-your-application
12
14
  const ATTR_DEPLOYMENT_ENVIRONMENT = "deployment.environment";
15
+ // NOTE: @joeyagreco - this can be used to determine if we are using mock-csb, staging-csb, prod-csb, etc
16
+ const ATTR_SUPERBLOCKS_BASE_URL = "superblocks.base_url";
17
+ let superblocksTracesUrl = undefined;
18
+ let superblocksHostname = "unknown";
19
+ try {
20
+ const tokenWithUrl = await getLocalTokenWithUrl();
21
+ const superblocksBaseUrl = new URL(tokenWithUrl.superblocksBaseUrl);
22
+ superblocksTracesUrl = superblocksBaseUrl.origin + "/api/v1/traces";
23
+ superblocksHostname = superblocksBaseUrl.hostname;
24
+ } catch (e) {
25
+ console.error("[tracing init] could not determine superblocks base url", e);
26
+ }
13
27
 
14
28
  // Initialize the OpenTelemetry SDK
15
29
  const sdk = new NodeSDK({
@@ -17,8 +31,12 @@ const sdk = new NodeSDK({
17
31
  new Resource({
18
32
  [ATTR_SERVICE_NAME]: "sdk-dev-server",
19
33
  [ATTR_DEPLOYMENT_ENVIRONMENT]: process.env.SUPERBLOCKS_CLI_ENV,
34
+ [ATTR_SUPERBLOCKS_BASE_URL]: superblocksHostname,
20
35
  }),
21
36
  ),
37
+ traceExporter: new OTLPTraceExporter({
38
+ url: superblocksTracesUrl, // OTLPTraceExporter defaults to sending traffic to http://localhost:4318/v1/traces
39
+ }),
22
40
  contextManager: new AsyncLocalStorageContextManager(),
23
41
  instrumentations: [
24
42
  // Configure HTTP instrumentation with custom attributes
@@ -11,6 +11,7 @@ export function reactTransformPlugin(): Plugin {
11
11
  return {
12
12
  name: "vite-plugin-react-transform",
13
13
  enforce: "pre", // Run before other plugins
14
+ apply: "serve",
14
15
  async transform(code, id) {
15
16
  // Check for React modules
16
17
  if (id.includes("node_modules/.vite/deps/react.js")) {
@@ -469,6 +469,16 @@ async function extractNeededExports(
469
469
  }
470
470
  }
471
471
 
472
+ const wellKnownPackages = new Map<string, string>([
473
+ ["react", "https://esm.sh/react@18.2.0"],
474
+ ["react-dom", "https://esm.sh/react-dom@18.2.0"],
475
+ ["react/jsx-runtime", "https://esm.sh/react@18.2.0/jsx-runtime"],
476
+ ["react/jsx-dev-runtime", "https://esm.sh/react@18.2.0/jsx-dev-runtime"],
477
+ ]);
478
+
479
+ const react18CdnUrl = "https://esm.sh/react@18.2.0";
480
+ const reactDom18CdnUrl = "https://esm.sh/react-dom@18.2.0";
481
+
472
482
  /**
473
483
  * Creates a Vite plugin that injects an import map into the HTML.
474
484
  * It analyzes remote modules to find their imports and maps them to local Vite modules.
@@ -558,7 +568,14 @@ export async function superblocksCdnPlugin(
558
568
  const modulePreloadData = modulesToPreload.get(importUrl);
559
569
  if (modulePreloadData) {
560
570
  modulePreloadData.content = content;
561
- modulePreloadData.integrity = await calculateIntegrity(binary);
571
+
572
+ // Don't calculate integrity for react 18 CDN modules
573
+ if (
574
+ !importUrl.startsWith(react18CdnUrl) &&
575
+ !importUrl.startsWith(reactDom18CdnUrl)
576
+ ) {
577
+ modulePreloadData.integrity = await calculateIntegrity(binary);
578
+ }
562
579
  }
563
580
 
564
581
  // Process all discovered modules and add them to the preload list
@@ -570,8 +587,15 @@ export async function superblocksCdnPlugin(
570
587
  if (moduleUrl.startsWith(baseUrl)) {
571
588
  // Add the module to preload if not already added
572
589
  if (!modulesToPreload.has(moduleUrl)) {
573
- // Calculate the integrity hash
574
- const integrity = await calculateIntegrity(moduleData.binary);
590
+ // Calculate the integrity hash for non-react 18 CDN modules
591
+ let integrity: string | undefined;
592
+ if (
593
+ !moduleUrl.startsWith(react18CdnUrl) &&
594
+ !moduleUrl.startsWith(reactDom18CdnUrl)
595
+ ) {
596
+ integrity = await calculateIntegrity(moduleData.binary);
597
+ }
598
+
575
599
  modulesToPreload.set(moduleUrl, {
576
600
  url: moduleUrl,
577
601
  content: moduleData.content,
@@ -802,10 +826,12 @@ export async function superblocksCdnPlugin(
802
826
  const importMap = {
803
827
  imports: {
804
828
  ...Object.fromEntries(
805
- Object.entries(initialImportMap).map(([module, url]) => [
806
- `${isDevMode ? "/@id/" : ""}cdn:${module}`,
807
- url,
808
- ]),
829
+ Object.entries(initialImportMap).map(([module, url]) => {
830
+ if (wellKnownPackages.has(module)) {
831
+ return [module, wellKnownPackages.get(module)!];
832
+ }
833
+ return [`${isDevMode ? "/@id/" : ""}cdn:${module}`, url];
834
+ }),
809
835
  ),
810
836
  },
811
837
  // Scopes apply to specific URL prefixes for more granular control
@@ -871,6 +897,8 @@ export async function superblocksCdnPlugin(
871
897
  const chunkPath = importToChunkMap.get(moduleName);
872
898
  if (chunkPath) {
873
899
  dependencyChunkUrl = `${base}${chunkPath}`;
900
+ } else if (wellKnownPackages.has(moduleName)) {
901
+ dependencyChunkUrl = wellKnownPackages.get(moduleName)!;
874
902
  }
875
903
  }
876
904
 
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { buildApplication } from "./application-build.mjs";
2
+
1
3
  export {
2
4
  createSocketConnectionIfNeeded,
3
5
  fetchApi,