@superblocksteam/sdk 2.0.6-next.49 → 2.0.6-next.5

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 (41) hide show
  1. package/dist/application-build.mjs +2 -6
  2. package/dist/application-build.mjs.map +1 -1
  3. package/dist/cli-replacement/automatic-upgrades.d.ts +2 -5
  4. package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
  5. package/dist/cli-replacement/automatic-upgrades.js +93 -199
  6. package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
  7. package/dist/cli-replacement/dev.d.mts +2 -1
  8. package/dist/cli-replacement/dev.d.mts.map +1 -1
  9. package/dist/cli-replacement/dev.mjs +28 -53
  10. package/dist/cli-replacement/dev.mjs.map +1 -1
  11. package/dist/dev-utils/dev-logger.d.mts +7 -17
  12. package/dist/dev-utils/dev-logger.d.mts.map +1 -1
  13. package/dist/dev-utils/dev-logger.mjs +9 -50
  14. package/dist/dev-utils/dev-logger.mjs.map +1 -1
  15. package/dist/dev-utils/dev-server.d.mts.map +1 -1
  16. package/dist/dev-utils/dev-server.mjs +12 -8
  17. package/dist/dev-utils/dev-server.mjs.map +1 -1
  18. package/dist/dev-utils/vite-plugin-sb-cdn.d.mts.map +1 -1
  19. package/dist/dev-utils/vite-plugin-sb-cdn.mjs +3 -13
  20. package/dist/dev-utils/vite-plugin-sb-cdn.mjs.map +1 -1
  21. package/dist/vite-plugin-inject-sb-ids-transform.mjs +1 -1
  22. package/dist/vite-plugin-inject-sb-ids-transform.mjs.map +1 -1
  23. package/package.json +4 -6
  24. package/src/application-build.mts +3 -6
  25. package/src/cli-replacement/automatic-upgrades.ts +113 -253
  26. package/src/cli-replacement/dev.mts +41 -67
  27. package/src/dev-utils/dev-logger.mts +20 -94
  28. package/src/dev-utils/dev-server.mts +12 -10
  29. package/src/dev-utils/vite-plugin-sb-cdn.mts +3 -14
  30. package/src/vite-plugin-inject-sb-ids-transform.mts +1 -1
  31. package/tsconfig.tsbuildinfo +1 -1
  32. package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts +0 -10
  33. package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts.map +0 -1
  34. package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs +0 -27
  35. package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs.map +0 -1
  36. package/dist/vite-plugin-generate-build-manifest.d.mts +0 -21
  37. package/dist/vite-plugin-generate-build-manifest.d.mts.map +0 -1
  38. package/dist/vite-plugin-generate-build-manifest.mjs +0 -131
  39. package/dist/vite-plugin-generate-build-manifest.mjs.map +0 -1
  40. package/src/dev-utils/vite-plugin-build-manifest-stub.mts +0 -30
  41. package/src/vite-plugin-generate-build-manifest.mts +0 -193
@@ -1,6 +1,7 @@
1
1
  import "../dev-utils/dev-tracer.js";
2
2
 
3
3
  import * as child_process from "node:child_process";
4
+ import * as fsp from "node:fs/promises";
4
5
  import path from "node:path";
5
6
  import { promisify } from "node:util";
6
7
  import { maskUnixSignals } from "@superblocksteam/util";
@@ -17,7 +18,7 @@ import fs from "fs-extra";
17
18
  import { resolveCommand } from "package-manager-detector";
18
19
  import { detect } from "package-manager-detector/detect";
19
20
 
20
- import { getErrorMeta, getLogger } from "../dev-utils/dev-logger.mjs";
21
+ import { getLogger } from "../dev-utils/dev-logger.mjs";
21
22
  import { createDevServer } from "../dev-utils/dev-server.mjs";
22
23
  import tracer from "../dev-utils/dev-tracer.js";
23
24
  import { SuperblocksSdk } from "../sdk.js";
@@ -26,7 +27,6 @@ import {
26
27
  getCurrentCliVersion,
27
28
  getCurrentLibraryVersionWithoutPM,
28
29
  } from "./automatic-upgrades.js";
29
- import { AUTO_UPGRADE_EXIT_CODE } from "./automatic-upgrades.js";
30
30
  import type { DevLogger } from "../dev-utils/dev-logger.mjs";
31
31
  import type { ApplicationConfig } from "../types/common.js";
32
32
  import type { DraftInterface } from "@superblocksteam/vite-plugin-file-sync/draft-interface";
@@ -93,6 +93,7 @@ async function installPackages(cwd: string, logger: DevLogger) {
93
93
  export async function dev(options: {
94
94
  /* cwd is required */
95
95
  cwd: string;
96
+ pidfilePath?: string;
96
97
  devServerPort?: number;
97
98
 
98
99
  /* user control of sync operations */
@@ -106,7 +107,7 @@ export async function dev(options: {
106
107
  /* For debugging purposes to get location of the cli */
107
108
  superblocksPath?: string;
108
109
  /* For redirecting output, like when running outside of the CLI */
109
- logger?: (...messages: (string | Error)[]) => void;
110
+ logger?: (message: string) => void;
110
111
 
111
112
  /* For a child process when restarting the dev server for automatic upgrades */
112
113
  skipAutoUpgrade?: boolean;
@@ -118,6 +119,7 @@ export async function dev(options: {
118
119
 
119
120
  const {
120
121
  cwd,
122
+ pidfilePath,
121
123
  devServerPort,
122
124
  downloadFirst,
123
125
  uploadFirst,
@@ -126,6 +128,12 @@ export async function dev(options: {
126
128
  skipAutoUpgrade,
127
129
  } = options;
128
130
 
131
+ const cliVersion = await getCurrentCliVersion();
132
+ const libraryVersion = await getCurrentLibraryVersionWithoutPM();
133
+ logger.info(
134
+ `Running command: ${options.superblocksPath} dev${options.uploadFirst ? " --upload-first" : ""}${options.downloadFirst ? " --download-first" : ""} with baseUrl: ${applicationConfig?.superblocksBaseUrl}, cliVersion: ${cliVersion}, libraryVersion: ${libraryVersion?.alias} ${libraryVersion?.version}`,
135
+ );
136
+
129
137
  // Add check for node_modules
130
138
  if (!fs.existsSync(path.join(cwd, "node_modules"))) {
131
139
  throw new Error(
@@ -133,13 +141,9 @@ export async function dev(options: {
133
141
  );
134
142
  }
135
143
 
136
- logger.info("Starting dev server");
137
-
138
- const cliVersion = await getCurrentCliVersion();
139
- const libraryVersion = await getCurrentLibraryVersionWithoutPM();
140
- logger.info(
141
- `Running command: ${options.superblocksPath} dev${options.uploadFirst ? " --upload-first" : ""}${options.downloadFirst ? " --download-first" : ""} with baseUrl: ${applicationConfig?.superblocksBaseUrl}, cliVersion: ${cliVersion}, libraryVersion: ${libraryVersion?.alias} ${libraryVersion?.version}`,
142
- );
144
+ if (pidfilePath) {
145
+ await fsp.writeFile(pidfilePath, `${process.pid}\n`);
146
+ }
143
147
 
144
148
  const port = devServerPort ?? 5173;
145
149
 
@@ -184,11 +188,17 @@ export async function dev(options: {
184
188
  if (lockService) {
185
189
  try {
186
190
  await lockService!.acquireLock();
191
+
192
+ // TODO(code-mode): package naming is preventing upgrade in ephemeral environments
193
+ if (
194
+ !process.env.PACKAGE_SUFFIX ||
195
+ process.env.PACKAGE_SUFFIX === "" ||
196
+ !skipAutoUpgrade
197
+ ) {
198
+ await checkVersionsAndUpgrade(lockService, applicationConfig);
199
+ }
187
200
  } catch (error) {
188
- logger.error(
189
- "Failed to acquire lock on application",
190
- getErrorMeta(error),
191
- );
201
+ logger.error("Failed to acquire lock on application", error);
192
202
  passErrorToVSCode(
193
203
  (error as { context?: { message: string } }).context?.message,
194
204
  logger,
@@ -222,10 +232,11 @@ export async function dev(options: {
222
232
 
223
233
  if (isSynced) {
224
234
  logger.info("Local files are in sync with the server");
225
- } else {
226
- logger.info("Local files are out of sync with the server");
235
+ return;
227
236
  }
228
237
 
238
+ logger.info("Local files are out of sync with the server");
239
+
229
240
  if (!(downloadFirst || uploadFirst)) {
230
241
  throw new Error(
231
242
  "You must choose --download-first or --upload-first to use the dev command",
@@ -235,70 +246,37 @@ export async function dev(options: {
235
246
  throw new Error("Choose either --download-first or --upload-first");
236
247
  }
237
248
 
238
- let hasPackageChanged = false;
239
-
240
249
  if (downloadFirst) {
241
- logger.info("Starting download");
250
+ logger.info(
251
+ "Starting directory sync from server before starting the local server",
252
+ );
242
253
 
254
+ // Read package.json before download
243
255
  const packageJsonBefore = await readPkgJson(cwd);
256
+
244
257
  await syncService!.downloadDirectory();
258
+
259
+ // Read package.json after download and compare
245
260
  const packageJsonAfter = await readPkgJson(cwd);
246
261
 
262
+ // Check if package.json changed
247
263
  if (packageJsonBefore && packageJsonAfter) {
248
264
  const diff = diffJson(packageJsonBefore, packageJsonAfter);
249
- hasPackageChanged = diff.some((part) => part.added || part.removed);
250
- } else if (packageJsonAfter) {
251
- hasPackageChanged = true;
252
- logger.info("package.json was created, installing packages…");
253
- }
254
- }
265
+ const hasChanges = diff.some((part) => part.added || part.removed);
255
266
 
256
- let hasCliUpdated = false;
257
- if (
258
- !process.env.PACKAGE_SUFFIX ||
259
- process.env.PACKAGE_SUFFIX === "" ||
260
- !skipAutoUpgrade
261
- ) {
262
- if (lockService) {
263
- const result = await checkVersionsAndUpgrade(
264
- lockService,
265
- applicationConfig,
266
- );
267
- if (result?.libraryUpdated) {
268
- hasPackageChanged = true;
267
+ if (hasChanges) {
268
+ logger.info("package.json has changed, installing packages…");
269
+ await installPackages(cwd, logger);
269
270
  }
270
- hasCliUpdated = result?.cliUpdated ?? false;
271
- } else {
272
- logger.warn(
273
- "Lock service is not available, skipping version check and upgrade",
274
- );
275
271
  }
276
- }
277
-
278
- if (hasPackageChanged) {
279
- logger.info("Installing packages…");
280
- await installPackages(cwd, logger);
281
- }
282
-
283
- if (hasPackageChanged || uploadFirst) {
272
+ } else if (uploadFirst) {
284
273
  logger.info("Uploading local files to server before starting");
285
274
  await syncService!.uploadDirectory();
286
- await syncService!.uploadDirectoryNowIfNeeded();
287
- }
288
-
289
- if (hasCliUpdated) {
290
- logger.info("CLI was updated, restarting the dev server…");
291
- process.exit(AUTO_UPGRADE_EXIT_CODE);
292
275
  }
293
276
  });
294
277
  } catch (error: any) {
295
278
  logger.error(error.message);
296
- try {
297
- await lockService?.shutdownAndExit();
298
- } finally {
299
- // this is redundant, but it's here to make sure the lock service is shutdown and the process exits
300
- process.exit(1);
301
- }
279
+ process.exit(1);
302
280
  }
303
281
  } else {
304
282
  logger.info("Skipping directory sync");
@@ -318,10 +296,6 @@ export async function dev(options: {
318
296
  options.signal?.addEventListener("abort", () => {
319
297
  logger.info("Server closed");
320
298
  httpServer.close();
321
- lockService?.shutdownAndExit().catch(() => {
322
- // this is redundant, but it's here to make sure the lock service is shutdown and the process exits
323
- process.exit(1);
324
- });
325
299
  });
326
300
 
327
301
  logger.debug(green(`Local server started at port ${port}`));
@@ -1,113 +1,39 @@
1
1
  import { createLogger, format, transports } from "winston";
2
- import type winston from "winston";
3
2
 
4
- const activeTransports: winston.transport[] = [];
5
-
6
- if (process.env.SUPERBLOCKS_IS_CSB === "true") {
7
- activeTransports.push(
8
- new transports.File({
9
- format: format.json(),
10
- filename: `/tmp/dev-server.log`,
11
- level: "info",
12
- }),
13
- );
14
- }
15
-
16
- activeTransports.push(
17
- new transports.Console({
18
- format: format.combine(
19
- format.colorize(),
20
- format.timestamp({
21
- format: "HH:mm:ss.SSS",
22
- }),
23
- format.printf((props) => {
24
- const { message, timestamp, error, level } = props;
25
- const base =
26
- process.env.SUPERBLOCKS_IS_CSB === "true"
27
- ? `${timestamp} ${message}`
28
- : `${message}`;
29
- if (level === "error") {
30
- return `${base} ${(error as ErrorMeta["error"]).message} ${(error as ErrorMeta["error"]).stack}`;
31
- }
32
- return base;
33
- }),
34
- ),
35
- }),
36
- );
3
+ export type DevLogger = {
4
+ debug: (message: string, ...meta: any[]) => void;
5
+ info: (message: string, ...meta: any[]) => void;
6
+ warn: (message: string, ...meta: any[]) => void;
7
+ error: (message: string, ...meta: any[]) => void;
8
+ };
37
9
 
38
10
  const winstonLogger = createLogger({
39
- level: "debug",
11
+ level: "info",
40
12
  exitOnError: false,
41
13
  format: format.json(),
42
- transports: activeTransports,
43
- });
44
-
45
- interface ErrorMeta {
46
- error: {
47
- kind: string;
48
- message: string;
49
- stack?: string;
50
- };
51
- }
52
-
53
- export interface DevLogger {
54
- log: (...messages: string[]) => void;
55
- debug: (...messages: string[]) => void;
56
- info: (...messages: string[]) => void;
57
- warn: (...messages: string[]) => void;
58
- error: (message: string, meta?: ErrorMeta) => void;
59
- }
60
- const logger: DevLogger = Object.freeze({
61
- debug: (...messages: string[]) =>
62
- winstonLogger.debug(
63
- messages.length > 0 ? messages.join(" ") : (messages[0] as string),
64
- ),
65
- log: (...messages: string[]) =>
66
- winstonLogger.info(
67
- messages.length > 0 ? messages.join(" ") : (messages[0] as string),
68
- ),
69
- info: (...messages: string[]) =>
70
- winstonLogger.info(
71
- messages.length > 0 ? messages.join(" ") : (messages[0] as string),
72
- ),
73
- warn: (...messages: string[]) =>
74
- winstonLogger.warn(
75
- messages.length > 0 ? messages.join(" ") : (messages[0] as string),
76
- ),
77
- error: (message: string, meta?: ErrorMeta) =>
78
- winstonLogger.error(message, meta),
14
+ transports: [
15
+ new transports.File({ filename: `/tmp/dev-server.log`, level: "info" }),
16
+ new transports.Console({
17
+ format: format.combine(
18
+ format.printf(({ message }) => `${message}`),
19
+ format.colorize({ message: true }),
20
+ ),
21
+ level: "debug",
22
+ }),
23
+ ],
79
24
  });
80
25
 
81
26
  export function getLogger(
82
- loggerOverride?: (...messages: string[]) => void,
27
+ loggerOverride?: (message: string) => void,
83
28
  ): DevLogger {
84
29
  if (!loggerOverride) {
85
- return logger;
30
+ return winstonLogger;
86
31
  }
87
32
 
88
33
  return {
89
34
  debug: loggerOverride,
90
35
  info: loggerOverride,
91
36
  warn: loggerOverride,
92
- log: loggerOverride,
93
- error: loggerOverride as any,
94
- };
95
- }
96
-
97
- export function getErrorMeta(error: unknown): ErrorMeta {
98
- if (error instanceof Error) {
99
- return {
100
- error: {
101
- kind: error.name,
102
- message: error.message,
103
- stack: error.stack,
104
- },
105
- };
106
- }
107
- return {
108
- error: {
109
- kind: "Unknown Error",
110
- message: JSON.stringify(error),
111
- },
37
+ error: loggerOverride,
112
38
  };
113
39
  }
@@ -18,8 +18,7 @@ import {
18
18
  customComponentsPlugin,
19
19
  isCustomComponentsEnabled,
20
20
  } from "./custom-build.mjs";
21
- import { getErrorMeta, getLogger } from "./dev-logger.mjs";
22
- import { buildManifestStubPlugin } from "./vite-plugin-build-manifest-stub.mjs";
21
+ import { getLogger } from "./dev-logger.mjs";
23
22
  import { ddRumPlugin } from "./vite-plugin-dd-rum.mjs";
24
23
  import { superblocksCdnPlugin } from "./vite-plugin-sb-cdn.mjs";
25
24
  import type { AiService } from "@superblocksteam/vite-plugin-file-sync/ai-service";
@@ -188,6 +187,13 @@ export async function createDevServer({
188
187
  }, viteReject);
189
188
  });
190
189
 
190
+ // TODO(code-mode): remove this soon
191
+ app.get("/_sb_disconnect", async (_req, res) => {
192
+ console.log("GET /_sb_disconnect");
193
+ // TODO(code-mode): should this include any validation checks, such as getting a token?
194
+ await gracefulShutdown({ logger, serverInitiated: false });
195
+ res.send("ok");
196
+ });
191
197
  app.post("/_sb_disconnect", async (req, res) => {
192
198
  const { initiatedByEmail, switchingTo } = req.body;
193
199
  // TODO(code-mode): should this include any validation checks, such as getting a token?
@@ -200,7 +206,7 @@ export async function createDevServer({
200
206
  });
201
207
  res.send("ok");
202
208
  } catch (e) {
203
- logger.error("Error disconnecting from dev server", getErrorMeta(e));
209
+ console.error("Error disconnecting from dev server", e);
204
210
  res.status(500).send("Error disconnecting from dev server");
205
211
  }
206
212
  });
@@ -254,7 +260,7 @@ async function startVite({
254
260
  }) {
255
261
  const viteLogger = createLogger();
256
262
  const logger = getLogger(loggerOverride);
257
- viteLogger.info = (msg: string) => logger.info(msg);
263
+ viteLogger.info = logger.info;
258
264
  viteLogger.warn = (msg: string) => {
259
265
  logger.warn(yellow(msg));
260
266
  };
@@ -270,8 +276,6 @@ async function startVite({
270
276
  const isCustomBuildEnabled = await isCustomComponentsEnabled();
271
277
  const customFolder = path.join(root, "custom");
272
278
 
273
- const draftsFolder = path.join(root, ".superblocks");
274
-
275
279
  const cdnUrl = process.env.SUPERBLOCKS_CDN_URL ?? "http://localhost:4040/cdn";
276
280
 
277
281
  const env = loadEnv(mode, root, "");
@@ -309,7 +313,7 @@ async function startVite({
309
313
  server: {
310
314
  middlewareMode: true,
311
315
  watch: {
312
- ignored: [`${customFolder}/**/*`, `${draftsFolder}/**/*`],
316
+ ignored: [`${customFolder}/**/*`],
313
317
  },
314
318
  hmr: hmrOptions,
315
319
  cors: {
@@ -338,13 +342,11 @@ async function startVite({
338
342
  aiService,
339
343
  httpServer,
340
344
  tracer,
345
+ logger,
341
346
  },
342
347
  { isCustomBuildEnabled },
343
348
  ) as Plugin,
344
349
 
345
- // Add a virtual "stub" module for the build manifest
346
- buildManifestStubPlugin(),
347
-
348
350
  // for now, only use the CDN locally
349
351
  superblocksCdnPlugin({
350
352
  imports: {
@@ -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 and skip the shared library's build manifest reference
228
- if (visited.has(url) || url.endsWith("/user-facing/build-manifest.js")) {
227
+ // Avoid circular dependencies
228
+ if (visited.has(url)) {
229
229
  return {
230
230
  dependencies: new Set(),
231
231
  content: "",
@@ -474,13 +474,6 @@ 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",
484
477
  ]);
485
478
 
486
479
  const react18CdnUrl = "https://esm.sh/react@18.2.0";
@@ -780,12 +773,8 @@ export async function superblocksCdnPlugin(
780
773
  // Externalize modules specified in the import map
781
774
  // The cdn: prefix ensures they're properly resolved to the CDN URL
782
775
  if (imports.includes(id)) {
783
- const shouldRedirectToCdn = !packagesToExcludeFromCdnRedirect.has(id);
784
776
  debug(`Externalizing module for CDN resolution: ${id}`);
785
- return {
786
- id: `${shouldRedirectToCdn ? "cdn:" : ""}${id}`,
787
- external: true,
788
- };
777
+ return { id: `cdn:${id}`, external: true };
789
778
  }
790
779
 
791
780
  return null;
@@ -29,7 +29,7 @@ const routesFileBaseName = "routes.json";
29
29
  export async function injectSuperblocksIdsPlugin(root: string) {
30
30
  const viteLogger = createLogger();
31
31
  const logger = getLogger();
32
- viteLogger.info = (msg: string) => logger.info(msg);
32
+ viteLogger.info = logger.info;
33
33
  viteLogger.warn = (msg: string) => {
34
34
  logger.warn(yellow(msg));
35
35
  };