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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-interview-cockpit",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Scaffold a personal AI-powered interview prep cockpit",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
  }