Roadmap to becoming a developer in 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

169 lines
3.7 KiB

export const IS_KEY_ONLY_ROADMAP_GENERATION = false;
type Lesson = string;
type Module = {
title: string;
lessons: Lesson[];
};
export type AiCourse = {
title: string;
modules: Module[];
difficulty: string;
};
export function generateAiCourseStructure(
data: string,
): Omit<AiCourse, 'difficulty'> {
const lines = data.split('\n');
let title = '';
const modules: Module[] = [];
let currentModule: Module | null = null;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (i === 0 && line.startsWith('#')) {
// First line is the title
title = line.replace('#', '').trim();
} else if (line.startsWith('## ')) {
// New module
if (currentModule) {
modules.push(currentModule);
}
currentModule = {
title: line.replace('## ', ''),
lessons: [],
};
// Removed auto-expand code to keep modules collapsed by default
} else if (line.startsWith('- ') && currentModule) {
// Lesson within current module
currentModule.lessons.push(line.replace('- ', ''));
}
}
// Add the last module if it exists
if (currentModule) {
modules.push(currentModule);
}
return {
title,
modules,
};
}
const NEW_LINE = '\n'.charCodeAt(0);
export async function readAIRoadmapStream(
reader: ReadableStreamDefaultReader<Uint8Array>,
{
onStream,
onStreamEnd,
}: {
onStream?: (roadmap: string) => void;
onStreamEnd?: (roadmap: string) => void;
},
) {
const decoder = new TextDecoder('utf-8');
let result = '';
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
// We will call the renderRoadmap callback whenever we encounter
// a new line with the result until the new line
// otherwise, we will keep appending the result to the previous result
if (value) {
let start = 0;
for (let i = 0; i < value.length; i++) {
if (value[i] === NEW_LINE) {
result += decoder.decode(value.slice(start, i + 1));
onStream?.(result);
start = i + 1;
}
}
if (start < value.length) {
result += decoder.decode(value.slice(start));
}
}
}
onStream?.(result);
onStreamEnd?.(result);
reader.releaseLock();
}
export async function readAIRoadmapContentStream(
reader: ReadableStreamDefaultReader<Uint8Array>,
{
onStream,
onStreamEnd,
}: {
onStream?: (roadmap: string) => void;
onStreamEnd?: (roadmap: string) => void;
},
) {
const decoder = new TextDecoder('utf-8');
let result = '';
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
if (value) {
result += decoder.decode(value);
onStream?.(result);
}
}
onStream?.(result);
onStreamEnd?.(result);
reader.releaseLock();
}
export async function readStream(
reader: ReadableStreamDefaultReader<Uint8Array>,
{
onStream,
onStreamEnd,
}: {
onStream?: (course: string) => void;
onStreamEnd?: (course: string) => void;
},
) {
const decoder = new TextDecoder('utf-8');
let result = '';
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
// Process the stream data as it comes in
if (value) {
let start = 0;
for (let i = 0; i < value.length; i++) {
if (value[i] === NEW_LINE) {
result += decoder.decode(value.slice(start, i + 1));
onStream?.(result);
start = i + 1;
}
}
if (start < value.length) {
result += decoder.decode(value.slice(start));
}
}
}
onStream?.(result);
onStreamEnd?.(result);
reader.releaseLock();
}