יש לי תחביב. כל פעם שאני רואה פרסום על איזה פרויקט קוד פתוח מעניין אני אוהב להיכנס לקוד שלו ולהסתכל בגדול במה זה בנוי ואיך. בדרך כלל אחרי כמה דקות אני הולך לאיבוד כי להבין קודבייס גדול זה קשה, מסמן לי לחזור לזה ואף פעם לא מגיע חזרה, אבל מדי פעם יש פרויקטים שהמבנה שלהם פשוט הגיוני ואז אני נשאר לחטט. כך קרה לי עם Cap, פרויקט קוד פתוח לשיתוף המסך.
קאפ כתוב בטייפסקריפט ומשתמש בכל הספריות המודרניות שהייתם מצפים למצוא בפרויקט היום כמו Tailwind, React וכמובן Drizzle. יש גירסת דסקטופ עם טאורי וגם קוד האתר זמין בגיטהאב. הקוד עצמו פשוט קל לקריאה לדוגמה הקובץ הזה הוא דף ה FAQ שלהם:
"use client";
const faqContent = [
{
title: "What is Cap?",
answer:
"Cap is an open source alternative to Loom. It's a video messaging tool that allows you to record, edit and share videos in seconds.",
},
{
title: "How do I use it?",
answer:
"Simply download the Cap macOS app (or the Cap web app), and start recording. You can record your screen, your camera, or both at once. After your recording finishes, you will receive your shareable Cap link to share with anyone.",
},
{
title: "Who is it for?",
answer:
"Cap is for anyone who wants to record and share videos. It's a great tool for creators, educators, marketers, and anyone who wants to communicate more effectively.",
},
{
title: "How much does it cost?",
answer:
"Cap is free to use. However, you can upgrade to Cap Pro for just $9/month and unlock unlimited recordings, unlimited recording length, and much more.",
},
{
title: "What makes you different to Loom?",
answer:
"Apart from being open source and privacy focused, Cap is also a lot more lightweight and faster to use. We also focus strongly on design and user experience, and our community is at the heart of everything we do.",
},
];
export const FaqPage = () => {
return (
<div className="wrapper wrapper-sm py-20">
<div className="text-center page-intro mb-14">
<h1>FAQ</h1>
</div>
<div className="mb-10">
{faqContent.map((section, index) => {
return (
<div key={index} className="max-w-2xl mx-auto my-8">
<h2 className="text-xl mb-2">{section.title}</h2>
<p className="text-lg">{section.answer}</p>
</div>
);
})}
</div>
</div>
);
};
ובסך הכל חוץ מלתהות למה זה צריך להתרנדר ב client אני מבין מה קורה פה (למרות שאישית לא הייתי שומר כך את השאלות והתשובות כי יהיה להם קשה לתרגם את זה לעוד שפות כשיבוא היום).
מפה לשם המשכתי לחטט בקוד והגעתי לחבילת בסיסי הנתונים ושם אני מוצא שתי פונקציות:
async createUser(userData) {
await db.insert(users).values({
id: nanoId(),
email: userData.email,
emailVerified: userData.emailVerified,
name: userData.name,
image: userData.image,
activeSpaceId: "",
});
const rows = await db
.select()
.from(users)
.where(eq(users.email, userData.email))
.limit(1);
const row = rows[0];
if (!row) throw new Error("User not found");
return row;
},
async getUser(id) {
const rows = await db
.select()
.from(users)
.where(eq(users.id, id))
.limit(1);
const row = rows[0];
return row ?? null;
},
הפונקציה createUser
תזרוק שגיאה אם היתה בעיה ביצירה. הפונקציה getUser
תחזיר null.
אני רואה איך זה קורה. אני רואה איך התוכנית השתנתה ואיך אולי פעם אחת חשבת שזה רעיון טוב לטפל בבעיה בחוץ ובמקום אחר הקוד החיצוני נראה טוב יותר כשהוא לא צריך את ה catch. ובכל זאת כותב כאן כדי שנלמד להסתכל על הדברים האלה, במיוחד כשהם כל כך קרובים.
אחידות בממשק זה אחד הדברים הכי חשובים כדי שיהיה לאנשים (ולנו) קל להשתמש בקוד. טייפסקריפט עוזר אם בוחרים להשתמש בו, אבל בסוף זה אנחנו - איפה אנחנו מטפלים בשגיאות, איזה סוגי מידע פונקציות מקבלות, מה בדרך כלל הן מחזירות. כשאני יודע "לנחש" את הממשק בלי להסתכל על התיעוד או הקוד דברים עובדים הרבה יותר מהר.