@superblocksteam/sdk 2.0.6-next.59 → 2.0.6-next.6

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 +29 -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 +42 -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,
@@ -212,6 +222,7 @@ export async function dev(options: {
212
222
  appRootDirPath: options.cwd,
213
223
  applicationId: applicationConfig.id,
214
224
  organizationId: currentUser.organizations[0].id,
225
+ anthropicApiKey: process.env.ANTHROPIC_API_KEY || "",
215
226
  fsOperationQueue,
216
227
  draftInterface: syncService! as DraftInterface,
217
228
  tracer,
@@ -221,10 +232,11 @@ export async function dev(options: {
221
232
 
222
233
  if (isSynced) {
223
234
  logger.info("Local files are in sync with the server");
224
- } else {
225
- logger.info("Local files are out of sync with the server");
235
+ return;
226
236
  }
227
237
 
238
+ logger.info("Local files are out of sync with the server");
239
+
228
240
  if (!(downloadFirst || uploadFirst)) {
229
241
  throw new Error(
230
242
  "You must choose --download-first or --upload-first to use the dev command",
@@ -234,70 +246,37 @@ export async function dev(options: {
234
246
  throw new Error("Choose either --download-first or --upload-first");
235
247
  }
236
248
 
237
- let hasPackageChanged = false;
238
-
239
249
  if (downloadFirst) {
240
- logger.info("Starting download");
250
+ logger.info(
251
+ "Starting directory sync from server before starting the local server",
252
+ );
241
253
 
254
+ // Read package.json before download
242
255
  const packageJsonBefore = await readPkgJson(cwd);
256
+
243
257
  await syncService!.downloadDirectory();
258
+
259
+ // Read package.json after download and compare
244
260
  const packageJsonAfter = await readPkgJson(cwd);
245
261
 
262
+ // Check if package.json changed
246
263
  if (packageJsonBefore && packageJsonAfter) {
247
264
  const diff = diffJson(packageJsonBefore, packageJsonAfter);
248
- hasPackageChanged = diff.some((part) => part.added || part.removed);
249
- } else if (packageJsonAfter) {
250
- hasPackageChanged = true;
251
- logger.info("package.json was created, installing packages…");
252
- }
253
- }
265
+ const hasChanges = diff.some((part) => part.added || part.removed);
254
266
 
255
- let hasCliUpdated = false;
256
- if (
257
- !process.env.PACKAGE_SUFFIX ||
258
- process.env.PACKAGE_SUFFIX === "" ||
259
- !skipAutoUpgrade
260
- ) {
261
- if (lockService) {
262
- const result = await checkVersionsAndUpgrade(
263
- lockService,
264
- applicationConfig,
265
- );
266
- if (result?.libraryUpdated) {
267
- hasPackageChanged = true;
267
+ if (hasChanges) {
268
+ logger.info("package.json has changed, installing packages…");
269
+ await installPackages(cwd, logger);
268
270
  }
269
- hasCliUpdated = result?.cliUpdated ?? false;
270
- } else {
271
- logger.warn(
272
- "Lock service is not available, skipping version check and upgrade",
273
- );
274
271
  }
275
- }
276
-
277
- if (hasPackageChanged) {
278
- logger.info("Installing packages…");
279
- await installPackages(cwd, logger);
280
- }
281
-
282
- if (hasPackageChanged || uploadFirst) {
272
+ } else if (uploadFirst) {
283
273
  logger.info("Uploading local files to server before starting");
284
274
  await syncService!.uploadDirectory();
285
- await syncService!.uploadDirectoryNowIfNeeded();
286
- }
287
-
288
- if (hasCliUpdated) {
289
- logger.info("CLI was updated, restarting the dev server…");
290
- process.exit(AUTO_UPGRADE_EXIT_CODE);
291
275
  }
292
276
  });
293
277
  } catch (error: any) {
294
278
  logger.error(error.message);
295
- try {
296
- await lockService?.shutdownAndExit();
297
- } finally {
298
- // this is redundant, but it's here to make sure the lock service is shutdown and the process exits
299
- process.exit(1);
300
- }
279
+ process.exit(1);
301
280
  }
302
281
  } else {
303
282
  logger.info("Skipping directory sync");
@@ -317,10 +296,6 @@ export async function dev(options: {
317
296
  options.signal?.addEventListener("abort", () => {
318
297
  logger.info("Server closed");
319
298
  httpServer.close();
320
- lockService?.shutdownAndExit().catch(() => {
321
- // this is redundant, but it's here to make sure the lock service is shutdown and the process exits
322
- process.exit(1);
323
- });
324
299
  });
325
300
 
326
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
  };