create-interview-cockpit 0.7.0 → 0.9.0
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/package.json +1 -1
- package/template/client/src/api.ts +96 -1
- package/template/client/src/components/CodeRunnerModal.tsx +637 -73
- package/template/client/src/reactLab.ts +38 -8
- package/template/client/tsconfig.tsbuildinfo +30 -1
- package/template/cockpit.json +1 -1
- package/template/server/src/index.ts +376 -0
package/package.json
CHANGED
|
@@ -800,6 +800,11 @@ export interface ModuleFederationSandboxStatus {
|
|
|
800
800
|
logs?: string[];
|
|
801
801
|
}
|
|
802
802
|
|
|
803
|
+
export type ModuleFederationCommandStreamMessage =
|
|
804
|
+
| { type: "output"; kind: "stdout" | "stderr" | "info"; text: string }
|
|
805
|
+
| { type: "complete" }
|
|
806
|
+
| { type: "error"; error: string };
|
|
807
|
+
|
|
803
808
|
export async function startNextjsSandbox(
|
|
804
809
|
files: Record<string, string>,
|
|
805
810
|
): Promise<NextjsSandboxInfo> {
|
|
@@ -865,11 +870,101 @@ export async function updateModuleFederationFiles(
|
|
|
865
870
|
export async function fetchModuleFederationStatus(
|
|
866
871
|
id: string,
|
|
867
872
|
): Promise<ModuleFederationSandboxStatus> {
|
|
868
|
-
const res = await fetch(`${BASE}/module-federation/${id}/status
|
|
873
|
+
const res = await fetch(`${BASE}/module-federation/${id}/status`, {
|
|
874
|
+
cache: "no-store",
|
|
875
|
+
});
|
|
869
876
|
if (!res.ok) throw new Error(await res.text());
|
|
870
877
|
return res.json();
|
|
871
878
|
}
|
|
872
879
|
|
|
880
|
+
export async function streamModuleFederationCommand(
|
|
881
|
+
input: { id: string; command: string; cwd?: string },
|
|
882
|
+
onMessage: (message: ModuleFederationCommandStreamMessage) => void,
|
|
883
|
+
): Promise<void> {
|
|
884
|
+
const res = await fetch(
|
|
885
|
+
`${BASE}/module-federation/${input.id}/command-stream`,
|
|
886
|
+
{
|
|
887
|
+
method: "POST",
|
|
888
|
+
headers: { "Content-Type": "application/json" },
|
|
889
|
+
body: JSON.stringify({ command: input.command, cwd: input.cwd }),
|
|
890
|
+
},
|
|
891
|
+
);
|
|
892
|
+
|
|
893
|
+
if (!res.ok || !res.body) {
|
|
894
|
+
const error = await res.text().catch(() => "Webpack command failed");
|
|
895
|
+
throw new Error(error || "Webpack command failed");
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
const reader = res.body.getReader();
|
|
899
|
+
const decoder = new TextDecoder();
|
|
900
|
+
let buffer = "";
|
|
901
|
+
|
|
902
|
+
const flushBuffer = () => {
|
|
903
|
+
const events = buffer.replace(/\r/g, "").split("\n\n");
|
|
904
|
+
buffer = events.pop() ?? "";
|
|
905
|
+
|
|
906
|
+
for (const event of events) {
|
|
907
|
+
if (!event.trim()) continue;
|
|
908
|
+
const payload = event
|
|
909
|
+
.split("\n")
|
|
910
|
+
.filter((line) => line.startsWith("data:"))
|
|
911
|
+
.map((line) => line.slice(5).trimStart())
|
|
912
|
+
.join("\n");
|
|
913
|
+
|
|
914
|
+
if (!payload) continue;
|
|
915
|
+
onMessage(JSON.parse(payload) as ModuleFederationCommandStreamMessage);
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
|
|
919
|
+
while (true) {
|
|
920
|
+
const { value, done } = await reader.read();
|
|
921
|
+
buffer += decoder.decode(value ?? new Uint8Array(), { stream: !done });
|
|
922
|
+
flushBuffer();
|
|
923
|
+
if (done) break;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (buffer.trim()) {
|
|
927
|
+
flushBuffer();
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
export async function fetchModuleFederationGeneratedFiles(
|
|
932
|
+
id: string,
|
|
933
|
+
): Promise<string[]> {
|
|
934
|
+
const res = await fetch(`${BASE}/module-federation/${id}/generated-files`, {
|
|
935
|
+
cache: "no-store",
|
|
936
|
+
});
|
|
937
|
+
if (!res.ok) {
|
|
938
|
+
const body = await res.json().catch(() => ({}));
|
|
939
|
+
throw new Error(
|
|
940
|
+
(body as any).error ||
|
|
941
|
+
`Failed to load generated files for webpack lab (${res.status})`,
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
const body = (await res.json()) as { files?: string[] };
|
|
945
|
+
return Array.isArray(body.files) ? body.files : [];
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
export async function fetchModuleFederationGeneratedFile(
|
|
949
|
+
id: string,
|
|
950
|
+
filePath: string,
|
|
951
|
+
): Promise<{ path: string; content: string }> {
|
|
952
|
+
const res = await fetch(
|
|
953
|
+
`${BASE}/module-federation/${id}/generated-file?path=${encodeURIComponent(filePath)}`,
|
|
954
|
+
{
|
|
955
|
+
cache: "no-store",
|
|
956
|
+
},
|
|
957
|
+
);
|
|
958
|
+
if (!res.ok) {
|
|
959
|
+
const body = await res.json().catch(() => ({}));
|
|
960
|
+
throw new Error(
|
|
961
|
+
(body as any).error ||
|
|
962
|
+
`Failed to load generated webpack file (${res.status})`,
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
return res.json();
|
|
966
|
+
}
|
|
967
|
+
|
|
873
968
|
export async function stopModuleFederationSandbox(id: string): Promise<void> {
|
|
874
969
|
await fetch(`${BASE}/module-federation/${id}`, { method: "DELETE" });
|
|
875
970
|
}
|