@superblocksteam/sdk 2.0.3-next.174 → 2.0.3-next.176
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.
- package/dist/application-build.d.mts +12 -0
- package/dist/application-build.d.mts.map +1 -0
- package/dist/application-build.mjs +113 -0
- package/dist/application-build.mjs.map +1 -0
- package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.js +22 -6
- package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
- package/dist/cli-replacement/dev.d.mts.map +1 -1
- package/dist/cli-replacement/dev.mjs +7 -0
- package/dist/cli-replacement/dev.mjs.map +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -5
- package/dist/client.js.map +1 -1
- package/dist/dev-utils/dev-server.d.mts.map +1 -1
- package/dist/dev-utils/dev-server.mjs +30 -8
- package/dist/dev-utils/dev-server.mjs.map +1 -1
- package/dist/dev-utils/dev-tracer.d.ts.map +1 -1
- package/dist/dev-utils/dev-tracer.js +33 -1
- package/dist/dev-utils/dev-tracer.js.map +1 -1
- package/dist/dev-utils/vite-plugin-react-transform.d.mts.map +1 -1
- package/dist/dev-utils/vite-plugin-react-transform.mjs +1 -0
- package/dist/dev-utils/vite-plugin-react-transform.mjs.map +1 -1
- package/dist/dev-utils/vite-plugin-sb-cdn.d.mts.map +1 -1
- package/dist/dev-utils/vite-plugin-sb-cdn.mjs +34 -9
- package/dist/dev-utils/vite-plugin-sb-cdn.mjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/socket/handlers.d.ts +2 -2
- package/dist/socket/handlers.d.ts.map +1 -1
- package/dist/socket/handlers.js.map +1 -1
- package/dist/socket/index.d.ts +1 -11
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +11 -43
- package/dist/socket/index.js.map +1 -1
- package/dist/vite-plugin-inject-sb-ids-transform.d.mts +15 -0
- package/dist/vite-plugin-inject-sb-ids-transform.d.mts.map +1 -0
- package/dist/vite-plugin-inject-sb-ids-transform.mjs +86 -0
- package/dist/vite-plugin-inject-sb-ids-transform.mjs.map +1 -0
- package/package.json +16 -5
- package/src/application-build.mts +160 -0
- package/src/cli-replacement/automatic-upgrades.ts +30 -9
- package/src/cli-replacement/dev.mts +10 -0
- package/src/client.ts +13 -4
- package/src/dev-utils/dev-server.mts +39 -8
- package/src/dev-utils/dev-tracer.ts +35 -1
- package/src/dev-utils/vite-plugin-react-transform.mts +1 -0
- package/src/dev-utils/vite-plugin-sb-cdn.mts +45 -11
- package/src/index.ts +2 -0
- package/src/socket/handlers.ts +109 -105
- package/src/socket/index.ts +21 -101
- package/src/vite-plugin-inject-sb-ids-transform.mts +104 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import babelGenerate from "@babel/generator";
|
|
3
|
+
import { parse } from "@babel/parser";
|
|
4
|
+
import { supplementElementIds, generateRootSource, } from "@superblocksteam/vite-plugin-file-sync";
|
|
5
|
+
import { yellow, red } from "colorette";
|
|
6
|
+
import fs from "fs-extra";
|
|
7
|
+
import { createLogger } from "vite";
|
|
8
|
+
import { getLogger } from "./dev-utils/dev-logger.mjs";
|
|
9
|
+
const routesFileBaseName = "routes.json";
|
|
10
|
+
/**
|
|
11
|
+
* Creates a Vite plugin that injects Superblocks IDs into the application.
|
|
12
|
+
* This will primarily be used during builds, as the dev server leverages the
|
|
13
|
+
* file sync manager to inject and keep the IDs up to date.
|
|
14
|
+
*
|
|
15
|
+
* Features:
|
|
16
|
+
* - Injects the root component with the routes data
|
|
17
|
+
* - Injects Superblocks IDs into all components
|
|
18
|
+
*
|
|
19
|
+
* @param root - The root directory of the application
|
|
20
|
+
* @returns A Vite plugin that injects Superblocks IDs into the application's components
|
|
21
|
+
*/
|
|
22
|
+
export async function injectSuperblocksIdsPlugin(root) {
|
|
23
|
+
const viteLogger = createLogger();
|
|
24
|
+
const logger = getLogger();
|
|
25
|
+
viteLogger.info = logger.info;
|
|
26
|
+
viteLogger.warn = (msg) => {
|
|
27
|
+
logger.warn(yellow(msg));
|
|
28
|
+
};
|
|
29
|
+
viteLogger.warnOnce = (msg) => {
|
|
30
|
+
logger.warn(yellow(msg));
|
|
31
|
+
};
|
|
32
|
+
viteLogger.error = (msg) => {
|
|
33
|
+
logger.error(red(msg));
|
|
34
|
+
};
|
|
35
|
+
viteLogger.clearScreen = () => { };
|
|
36
|
+
const routes = await getRoutes(root, viteLogger);
|
|
37
|
+
return {
|
|
38
|
+
name: "sb-inject-superblocks-ids",
|
|
39
|
+
enforce: "pre",
|
|
40
|
+
transform(code, id) {
|
|
41
|
+
const relativePath = path.relative(root, id);
|
|
42
|
+
if (relativePath === "root.tsx") {
|
|
43
|
+
const source = generateRootSource(code, routes);
|
|
44
|
+
return {
|
|
45
|
+
code: source,
|
|
46
|
+
map: null,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
else if (id.endsWith(".tsx")) {
|
|
50
|
+
const ast = parse(code, {
|
|
51
|
+
sourceType: "module",
|
|
52
|
+
sourceFilename: id,
|
|
53
|
+
plugins: ["jsx"],
|
|
54
|
+
});
|
|
55
|
+
supplementElementIds({
|
|
56
|
+
fileName: id,
|
|
57
|
+
ast,
|
|
58
|
+
shouldModifyAst: true,
|
|
59
|
+
});
|
|
60
|
+
const result = babelGenerate.default(ast);
|
|
61
|
+
return result.code;
|
|
62
|
+
}
|
|
63
|
+
return code;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function getRoutes(root, logger) {
|
|
68
|
+
const routesFile = path.join(root, routesFileBaseName);
|
|
69
|
+
if (!(await fs.pathExists(routesFile))) {
|
|
70
|
+
logger.warn(`routes file not found at expected location: ${routesFile}`);
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const routesData = await fs.readFile(routesFile, "utf-8");
|
|
75
|
+
const routes = JSON.parse(routesData);
|
|
76
|
+
return Object.entries(routes).map(([path, { file }]) => ({
|
|
77
|
+
path,
|
|
78
|
+
component: file,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
logger.error(`error reading routes file: ${routesFile}. error=[${JSON.stringify(err)}]`);
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=vite-plugin-inject-sb-ids-transform.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin-inject-sb-ids-transform.mjs","sourceRoot":"","sources":["../src/vite-plugin-inject-sb-ids-transform.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.3-next.
|
|
3
|
+
"version": "2.0.3-next.176",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Superblocks JS SDK",
|
|
6
6
|
"homepage": "https://www.superblocks.com",
|
|
@@ -16,16 +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",
|
|
25
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.55.0",
|
|
21
26
|
"@opentelemetry/instrumentation-express": "^0.45.0",
|
|
22
27
|
"@opentelemetry/instrumentation-http": "^0.55.0",
|
|
28
|
+
"@opentelemetry/resources": "^1.28.0",
|
|
23
29
|
"@opentelemetry/sdk-node": "^0.55.0",
|
|
30
|
+
"@opentelemetry/semantic-conventions": "^1.28.0",
|
|
24
31
|
"@rollup/wasm-node": "^4.35.0",
|
|
25
|
-
"@superblocksteam/bucketeer-sdk": "0.
|
|
26
|
-
"@superblocksteam/shared": "0.
|
|
27
|
-
"@superblocksteam/util": "2.0.3-next.
|
|
28
|
-
"@superblocksteam/vite-plugin-file-sync": "2.0.3-next.
|
|
32
|
+
"@superblocksteam/bucketeer-sdk": "0.5.0",
|
|
33
|
+
"@superblocksteam/shared": "0.9160.0",
|
|
34
|
+
"@superblocksteam/util": "2.0.3-next.176",
|
|
35
|
+
"@superblocksteam/vite-plugin-file-sync": "2.0.3-next.176",
|
|
29
36
|
"@vitejs/plugin-react": "^4.3.4",
|
|
30
37
|
"axios": "^1.4.0",
|
|
31
38
|
"chokidar": "^4.0.3",
|
|
@@ -53,7 +60,11 @@
|
|
|
53
60
|
"yaml": "^2.4.2"
|
|
54
61
|
},
|
|
55
62
|
"devDependencies": {
|
|
63
|
+
"@babel/types": "^7.25.8",
|
|
56
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",
|
|
57
68
|
"@types/chai": "^4",
|
|
58
69
|
"@types/chai-as-promised": "^8.0.2",
|
|
59
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
|
+
}
|
|
@@ -79,7 +79,11 @@ async function getCurrentCliVersion(): Promise<string | undefined> {
|
|
|
79
79
|
);
|
|
80
80
|
const json = JSON.parse(versionOutput) as Record<string, string>;
|
|
81
81
|
// Extract version from string like "@superblocksteam/cli/2.0.0-next.1" or "@superblocksteam/cli-ephemeral/2.0.0-SNAPSHOT.1749077365"
|
|
82
|
-
|
|
82
|
+
const version = json.cliVersion?.replace(
|
|
83
|
+
/@superblocksteam\/cli(-ephemeral)?\//,
|
|
84
|
+
"",
|
|
85
|
+
);
|
|
86
|
+
return version;
|
|
83
87
|
} catch (error) {
|
|
84
88
|
if (isNativeError(error)) {
|
|
85
89
|
logger.error(`Error getting CLI version: ${error.message}`);
|
|
@@ -258,6 +262,9 @@ export async function checkVersionsAndUpgrade(
|
|
|
258
262
|
// Get current versions
|
|
259
263
|
const currentCliVersion = await getCurrentCliVersion();
|
|
260
264
|
const currentLibraryInfo = await getCurrentLibraryVersion(pm);
|
|
265
|
+
logger.info(
|
|
266
|
+
`@superblocksteam/cli/${currentCliVersion} ${currentLibraryInfo?.alias} ${currentLibraryInfo?.version}`,
|
|
267
|
+
);
|
|
261
268
|
|
|
262
269
|
// Skip if we're in local development
|
|
263
270
|
if (
|
|
@@ -277,14 +284,28 @@ export async function checkVersionsAndUpgrade(
|
|
|
277
284
|
const targetVersions = await getRemoteVersions(config);
|
|
278
285
|
if (!targetVersions) return;
|
|
279
286
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
287
|
+
let cliNeedsUpgrade: boolean | string;
|
|
288
|
+
let libraryNeedsUpgrade: boolean | string;
|
|
289
|
+
try {
|
|
290
|
+
// If version is latest, then semver can throw an error
|
|
291
|
+
// Check if CLI needs upgrade
|
|
292
|
+
cliNeedsUpgrade =
|
|
293
|
+
targetVersions.cli && gt(targetVersions.cli, currentCliVersion);
|
|
294
|
+
|
|
295
|
+
// Check if library needs upgrade
|
|
296
|
+
libraryNeedsUpgrade =
|
|
297
|
+
targetVersions.library &&
|
|
298
|
+
gt(targetVersions.library, currentLibraryInfo.version);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
console.warn(
|
|
301
|
+
"Error checking versions to upgrade, releasing lock and exiting",
|
|
302
|
+
error,
|
|
303
|
+
);
|
|
304
|
+
await lockService.shutdown({
|
|
305
|
+
serverInitiated: false,
|
|
306
|
+
});
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
288
309
|
|
|
289
310
|
if (!cliNeedsUpgrade && !libraryNeedsUpgrade) {
|
|
290
311
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
90
|
-
|
|
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,14 +1,48 @@
|
|
|
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";
|
|
6
|
+
import { Resource } from "@opentelemetry/resources";
|
|
5
7
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
8
|
+
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
9
|
+
import { getLocalTokenWithUrl } from "@superblocksteam/util";
|
|
6
10
|
import packageJson from "../../package.json" with { type: "json" };
|
|
7
11
|
import type { Span } from "@opentelemetry/api";
|
|
8
12
|
|
|
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
|
|
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
|
+
const ATTR_SUPERBLOCKS_CLI_TOKEN = "superblocks.cli_token";
|
|
18
|
+
let superblocksTracesUrl = undefined;
|
|
19
|
+
let superblocksHostname = "unknown";
|
|
20
|
+
let token = "unknown";
|
|
21
|
+
try {
|
|
22
|
+
const tokenWithUrl = await getLocalTokenWithUrl();
|
|
23
|
+
const superblocksBaseUrl = new URL(tokenWithUrl.superblocksBaseUrl);
|
|
24
|
+
superblocksTracesUrl = superblocksBaseUrl.origin + "/api/v1/traces";
|
|
25
|
+
superblocksHostname = superblocksBaseUrl.hostname;
|
|
26
|
+
if ("token" in tokenWithUrl) {
|
|
27
|
+
token = tokenWithUrl.token.substring(0, 8);
|
|
28
|
+
}
|
|
29
|
+
} catch (e) {
|
|
30
|
+
console.error("[tracing init] could not determine superblocks base url", e);
|
|
31
|
+
}
|
|
32
|
+
|
|
9
33
|
// Initialize the OpenTelemetry SDK
|
|
10
34
|
const sdk = new NodeSDK({
|
|
11
|
-
|
|
35
|
+
resource: Resource.default().merge(
|
|
36
|
+
new Resource({
|
|
37
|
+
[ATTR_SERVICE_NAME]: "sdk-dev-server",
|
|
38
|
+
[ATTR_DEPLOYMENT_ENVIRONMENT]: process.env.SUPERBLOCKS_CLI_ENV,
|
|
39
|
+
[ATTR_SUPERBLOCKS_BASE_URL]: superblocksHostname,
|
|
40
|
+
[ATTR_SUPERBLOCKS_CLI_TOKEN]: token,
|
|
41
|
+
}),
|
|
42
|
+
),
|
|
43
|
+
traceExporter: new OTLPTraceExporter({
|
|
44
|
+
url: superblocksTracesUrl, // OTLPTraceExporter defaults to sending traffic to http://localhost:4318/v1/traces
|
|
45
|
+
}),
|
|
12
46
|
contextManager: new AsyncLocalStorageContextManager(),
|
|
13
47
|
instrumentations: [
|
|
14
48
|
// 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")) {
|