<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Majd Al Mnayer</title>
    <description>The latest articles on DEV Community by Majd Al Mnayer (@majd_almnayer_2101).</description>
    <link>https://dev.to/majd_almnayer_2101</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2017204%2F75e6a72c-3226-4238-8189-04386a155a94.jpeg</url>
      <title>DEV Community: Majd Al Mnayer</title>
      <link>https://dev.to/majd_almnayer_2101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/majd_almnayer_2101"/>
    <language>en</language>
    <item>
      <title>The Final Stretch of My Open Source Journey: Part 3</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Thu, 05 Dec 2024 18:15:31 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/the-final-stretch-of-my-open-source-journey-part-3-1a2j</link>
      <guid>https://dev.to/majd_almnayer_2101/the-final-stretch-of-my-open-source-journey-part-3-1a2j</guid>
      <description>&lt;p&gt;For the third week of my final open source course assignment, several events have transpired.&lt;/p&gt;

&lt;p&gt;First, I'm glad to announce that I've successfully made all user messages sent using the &lt;code&gt;WYSIWYG&lt;/code&gt; editor compatible with the existing &lt;code&gt;MarkdownRenderer&lt;/code&gt; component! This means that once I transitioned all user messages from &lt;code&gt;textarea&lt;/code&gt; to use the &lt;code&gt;MarkdownRenderer&lt;/code&gt; component, everything worked exactly as expected, and it looks amazing!&lt;/p&gt;

&lt;p&gt;Now users can easily write markdown in the input, send it, and view it in their chat history with the LLM. The goal was to make &lt;code&gt;chat-ui&lt;/code&gt; behave exactly like &lt;code&gt;claude&lt;/code&gt;, and the mission was successful!&lt;/p&gt;

&lt;p&gt;However, there are downsides. My communication with the repo maintainer has ceased, despite my several attempts to contact them. My issues (&lt;a href="https://github.com/huggingface/chat-ui/issues/1545" rel="noopener noreferrer"&gt;one&lt;/a&gt;, &lt;a href="https://github.com/huggingface/chat-ui/issues/1592" rel="noopener noreferrer"&gt;two&lt;/a&gt;) and &lt;a href="https://github.com/huggingface/chat-ui/pull/1562" rel="noopener noreferrer"&gt;pull request&lt;/a&gt; remain open but have received no updates whatsoever.&lt;/p&gt;

&lt;p&gt;I've attempted several times to communicate with the maintainer on the issues, but no reply has been given. The maintainer continues to reply to some other issues and pull requests, but not mine.&lt;/p&gt;

&lt;p&gt;This has been extremely disappointing, as I put a lot of time and effort into making the requirements work exactly as expected. Seeing my work neglected like this is truly heartbreaking. What's even worse is that I discovered and resolved an issue in my pull request where LLM-sent messages weren't being converted into &lt;code&gt;Markdown&lt;/code&gt; properly when using the &lt;code&gt;MarkdownRenderer&lt;/code&gt; component — which was then used by the maintainer in a commit they made to the repo (and this happened after my pull request was up).&lt;/p&gt;

&lt;p&gt;I've truly enjoyed working on this issue and this project, but it's extremely disappointing to see such poor communication take place in the open source community. Certainly nothing can be all "flowers and roses," however, this is something that shouldn't happen.&lt;/p&gt;

&lt;p&gt;Aside from my disappointment, I would say this has been extremely rewarding. I ended up learning what a &lt;code&gt;What You See Is What You Get&lt;/code&gt; editor is and how to create one, learned a new framework (&lt;code&gt;svelte&lt;/code&gt;), and many other things. I would certainly recommend working on open source projects to everyone out there — you meet lovely people, learn many new things, and work on amazing projects! Just perhaps, maybe not &lt;code&gt;chat-ui&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>ai</category>
    </item>
    <item>
      <title>The Final Stretch of My Open Source Journey: Part 2</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Fri, 29 Nov 2024 15:03:47 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/the-final-stretch-of-my-open-source-journey-part-2-d0d</link>
      <guid>https://dev.to/majd_almnayer_2101/the-final-stretch-of-my-open-source-journey-part-2-d0d</guid>
      <description>&lt;p&gt;For the second week of my final open source course assignment, I decided to contribute once again to Hugging Face's chat-ui!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/huggingface/chat-ui/issues/1592" rel="noopener noreferrer"&gt;issue&lt;/a&gt; I created was to add Markdown rendering to user messages that are sent and stored. At the time, user messages were being displayed as unrendered markdown text.&lt;/p&gt;

&lt;p&gt;To tackle this, I created an issue detailing my planned approach. I intended to use &lt;a href="https://www.npmjs.com/package/marked" rel="noopener noreferrer"&gt;Marked&lt;/a&gt; to conditionally render certain markdown elements into HTML. After diving deep into Marked's documentation, I discovered this was indeed possible - you can simply disable the elements you don't want to render into HTML!&lt;/p&gt;

&lt;p&gt;As I started working on the implementation, I noticed something interesting: there was already a MarkdownRenderer component in place. This component was being used to render the LLM's replies from Markdown into HTML. However, it wasn't working properly for my use case.&lt;/p&gt;

&lt;p&gt;Strangely, while the Markdown was being converted to HTML, the elements weren't displaying on-screen - they were showing up as strings instead. This behavior was puzzling, as the code appeared correct after multiple reviews. I even started doubting my understanding and created a new empty project with TailwindCSS, copying chunks of HTML and CSS from the chat-ui project to test pieces individually. Everything worked fine in isolation.&lt;/p&gt;

&lt;p&gt;After several hours of code review, I finally spotted something unfamiliar in the Markdown Renderer component: a function called &lt;code&gt;escapeHTML&lt;/code&gt; was being used to escape HTML, even though &lt;a href="https://github.com/cure53/DOMPurify" rel="noopener noreferrer"&gt;DOMPurify&lt;/a&gt; was already being used for sanitization right after!&lt;/p&gt;

&lt;p&gt;The solution? I deleted this function, and suddenly everything worked perfectly! The markdown was now rendering properly on screen, and I could even edit the response.&lt;/p&gt;

&lt;p&gt;The entire process took over 30 hours collectively, and the result was deleting a single line of code! Sometimes the simplest solutions are the hardest to find.&lt;/p&gt;

&lt;p&gt;What remains is for me to implement Markdown Rendering to the user messages, and allow the user to modify their previously sent messages as well!&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>The Final Stretch of My Open Source Journey: Part 1</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Mon, 25 Nov 2024 00:47:28 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/the-final-stretch-of-my-open-source-journey-part-1-4039</link>
      <guid>https://dev.to/majd_almnayer_2101/the-final-stretch-of-my-open-source-journey-part-1-4039</guid>
      <description>&lt;p&gt;I can't believe this semester is almost over! To be fair, contributing to open source projects doesn't even feel like coursework - it feels real, and it's been amazing.&lt;/p&gt;

&lt;p&gt;For our last deliverable in this course, we are asked to work on an issue, or several, similar to the previous deliverable. It should feel real, be a genuinely good contribution, and mean something both for us and the project!&lt;/p&gt;

&lt;p&gt;Now, I don't really have anything specific in mind. I might contribute to projects I've already contributed to, or I might choose something new and exciting, but either way, whatever I end up doing is going to be worth it! I'm mainly looking for something fun and engaging. I'm not so fussy about what language or technology is used per se; I just want the idea or the domain to be fun!&lt;/p&gt;

&lt;p&gt;In previous deliverables, I've contributed tests, bug fixes, features, simple documentation updates, and refactoring. I can't think of anything that I haven't done, therefore, it wouldn't really matter to me what type my contribution is, as long as I feel like it meant something, that I learned something from it, and that it benefited the project!&lt;/p&gt;

&lt;p&gt;As of my writing of this post, I have still not decided on what project to work on. I might contribute to Hugging Face's &lt;code&gt;Chat-ui&lt;/code&gt;, I might find a new project, or work on one that I contributed to in the past. I am hunting for an issue that is not too easy, is fulfilling to work on, and teaches new things!&lt;/p&gt;

&lt;p&gt;And if time permits, with the finals of my other courses drawing close as well, I will take on more issues! Part two of this journey should be out by the end of this week, where I finally decide on what I will be working on and what progress I've made so far!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>github</category>
      <category>programming</category>
    </item>
    <item>
      <title>OptimizeIt Is Unleashed!</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Sun, 17 Nov 2024 22:34:48 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/optimizeit-is-unleashed-3agm</link>
      <guid>https://dev.to/majd_almnayer_2101/optimizeit-is-unleashed-3agm</guid>
      <description>&lt;h1&gt;
  
  
  Finally, &lt;a href="https://www.npmjs.com/package/optimizeit" rel="noopener noreferrer"&gt;OptimizeIt is released on npm&lt;/a&gt;!
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; was definitely the go-to, since I use it as a package manager for OptimizeIt. Let's discuss how this process went from A to Z.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Releases
&lt;/h2&gt;

&lt;p&gt;First things first, I had to create &lt;a href="https://www.npmjs.com/~mounayer" rel="noopener noreferrer"&gt;an account&lt;/a&gt; on npm. Afterwards, I had to update the &lt;code&gt;package.json&lt;/code&gt; file to include &lt;code&gt;repository&lt;/code&gt;, &lt;code&gt;bugs&lt;/code&gt;, and &lt;code&gt;homepage&lt;/code&gt; URLs. I also had to create an &lt;a href="https://docs.npmjs.com/cli/v10/using-npm/developers#keeping-files-out-of-your-package" rel="noopener noreferrer"&gt;.npmignore&lt;/a&gt; file to ignore everything that is not included in the &lt;code&gt;build&lt;/code&gt; directory. Then, I did a fresh install and build, and using the &lt;code&gt;cli&lt;/code&gt;, I logged into my newly created &lt;code&gt;npm&lt;/code&gt; account.&lt;/p&gt;

&lt;p&gt;Once that was done, I created a tag for version &lt;code&gt;1.0.0&lt;/code&gt;, and I published &lt;code&gt;OptimizeIt&lt;/code&gt; for the very first time using &lt;code&gt;npm publish&lt;/code&gt;. I didn't have to update any code, files, or anything—it just worked!&lt;/p&gt;

&lt;p&gt;It was much easier than expected, as those were the exact steps I took, and boom! &lt;code&gt;OptimizeIt&lt;/code&gt; was now on npm!&lt;/p&gt;

&lt;p&gt;This is great and all; however, I wanted to automate this. I didn't want to do this manually every single time. Additionally, after doing this, the &lt;a href="https://github.com/Mounayer/OptimizeIt/releases/tag/v1.0.4" rel="noopener noreferrer"&gt;releases section&lt;/a&gt; on the &lt;code&gt;GitHub Repo&lt;/code&gt; was not updated with the most recently added release! I wanted a way to automate all of this—ideally: tag, publish to npm, publish on GitHub, finish.&lt;/p&gt;

&lt;p&gt;To do this, I had to add a new job to my current &lt;a href="https://github.com/Mounayer/OptimizeIt/blob/main/.github/workflows/ci.yml" rel="noopener noreferrer"&gt;workflow&lt;/a&gt; that runs only when a new &lt;code&gt;tag&lt;/code&gt; is detected. I had to retrieve an &lt;a href="https://docs.npmjs.com/creating-and-viewing-access-tokens" rel="noopener noreferrer"&gt;NPM_TOKEN&lt;/a&gt; from my &lt;code&gt;npm account&lt;/code&gt; and add it to &lt;a href="https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions" rel="noopener noreferrer"&gt;GitHub Secrets&lt;/a&gt; so that my newly added job could access it to publish to &lt;code&gt;npm&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;GitHub releases&lt;/code&gt; part, however, I didn't have to create any secret manually, as the workflow already listens in on the repository's permissions and fetches the &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;, which is required to create a &lt;code&gt;release&lt;/code&gt; on &lt;code&gt;GitHub&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After adding the new workflow, creating a new release is simpler than ever. These are the exact steps that I must do every single time I need to create a new release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm version 1.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin v1.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will automatically trigger the &lt;code&gt;workflow&lt;/code&gt; and execute &lt;code&gt;linting&lt;/code&gt;, &lt;code&gt;building&lt;/code&gt;, &lt;code&gt;testing&lt;/code&gt;, and if all pass, &lt;code&gt;publishing&lt;/code&gt;. Now, everything is automated—both &lt;code&gt;npm&lt;/code&gt; and &lt;code&gt;GitHub&lt;/code&gt;'s releases are updated automatically!&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing The Release
&lt;/h2&gt;

&lt;p&gt;Testing the release went much better than I thought. The very first time &lt;code&gt;OptimizeIt&lt;/code&gt; was run, it complained that no &lt;code&gt;API Key&lt;/code&gt; was provided. However, a quick glance at the &lt;code&gt;README.md&lt;/code&gt; immediately tells the user how to provide that using the &lt;a href="https://github.com/Mounayer/OptimizeIt/tree/main?tab=readme-ov-file#toml-config" rel="noopener noreferrer"&gt;toml config&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Afterwards, very thorough testing was done on all of its features, until... It was time for &lt;code&gt;OptimizeIt&lt;/code&gt; to output some files. This is when the issue happened. Not that it wasn't working as intended, but whenever &lt;code&gt;OptimizeIt&lt;/code&gt; creates a file in the &lt;code&gt;output&lt;/code&gt; directory, it does so in the &lt;code&gt;output&lt;/code&gt; directory in its &lt;code&gt;directory&lt;/code&gt;. As in, if the user uses either its &lt;code&gt;html&lt;/code&gt;, &lt;code&gt;markdown&lt;/code&gt;, or &lt;code&gt;output&lt;/code&gt; features, the file created is somewhere in &lt;code&gt;node_modules&lt;/code&gt; in the system. While this does work, and it did work as intended... I personally thought this was very unintuitive and cumbersome. Therefore, small &lt;a href="https://github.com/Mounayer/OptimizeIt/commit/3ad1104430c8164251c89ab894f173a92b8e04b4" rel="noopener noreferrer"&gt;updates&lt;/a&gt; were done to &lt;code&gt;OptimizeIt&lt;/code&gt; to now automatically create an &lt;code&gt;output&lt;/code&gt; file at the current directory where the &lt;code&gt;OptimizeIt&lt;/code&gt; call was invoked. As in, no matter where users are in their system, if they use any of &lt;code&gt;OptimizeIt&lt;/code&gt;'s output features, it will now automatically create an &lt;code&gt;output&lt;/code&gt; folder and place the updated file within! This was much more intuitive than before, hassle-free, and very helpful!&lt;/p&gt;

&lt;p&gt;Aside from that, no issues arose when testing &lt;code&gt;OptimizeIt&lt;/code&gt;, and it works beautifully!&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should You Use OptimizeIt
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;OptimizeIt&lt;/code&gt; is intended to be installed globally, as in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; optimizeit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its purpose is to offer help for the user, no matter where they are in their system. Using &lt;code&gt;OptimizeIt&lt;/code&gt; has not changed! It works just like it always did; a very thorough explanation can be found &lt;a href="https://github.com/Mounayer/OptimizeIt?tab=readme-ov-file#how-to-use" rel="noopener noreferrer"&gt;here&lt;/a&gt;. However, a small example of my favorite feature is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;optimizeit examples/main.cpp examples/main.py &lt;span class="nt"&gt;--html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would generate an &lt;code&gt;html&lt;/code&gt; file in your &lt;code&gt;output&lt;/code&gt; directory, showcasing the differences in the &lt;code&gt;before&lt;/code&gt; and &lt;code&gt;after&lt;/code&gt; usage of &lt;code&gt;OptimizeIt&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu0xgfxke3nrn9gpzu5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu0xgfxke3nrn9gpzu5k.png" alt="OptimizeIt HTML 1" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jzbeaa81qmzzlsdtwd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jzbeaa81qmzzlsdtwd8.png" alt="OptimizeIt HTML 2" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Users can also customize its configurations however they want using the &lt;a href="https://github.com/Mounayer/OptimizeIt?tab=readme-ov-file#toml-config" rel="noopener noreferrer"&gt;toml config&lt;/a&gt; option that &lt;code&gt;OptimizeIt&lt;/code&gt; uses!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Now that &lt;code&gt;OptimizeIt&lt;/code&gt; is released, anyone can use it for a little help in optimizing the performance of their source code! I know, I know—do not use &lt;code&gt;AI&lt;/code&gt; to alter your code because it will break it, never use AI to write your code, it's unreadable, it's not good enough... I've heard it all. However, you, the reader, would be lying if you said you've never used &lt;code&gt;AI&lt;/code&gt; before to help give you ideas on how to improve your code! I understand that no one should &lt;code&gt;solely&lt;/code&gt; rely on &lt;code&gt;AI&lt;/code&gt; to write their code; however, optimizing it, on the other hand, is something that every developer does! Whether it's to optimize an entire file, give you ideas on how to approach a problem differently, or simply make code readability improvements, &lt;code&gt;OptimizeIt&lt;/code&gt; is here to help you &lt;code&gt;Optimize&lt;/code&gt; &lt;code&gt;it&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Well, what are you waiting for? &lt;a href="https://www.npmjs.com/package/optimizeit" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>performance</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Open Source Contribution: Round 2</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Tue, 12 Nov 2024 19:07:38 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/open-source-contribution-round-2-1nhg</link>
      <guid>https://dev.to/majd_almnayer_2101/open-source-contribution-round-2-1nhg</guid>
      <description>&lt;p&gt;For Hacktoberfest, I started my open source contribution journey slowly, working my way up from fixing a small issue in a README.md file to contributing to a large open source project.&lt;/p&gt;

&lt;p&gt;For this release, I wanted to take things up a notch. For the first project, I wanted to choose a new big project to work with: &lt;a href="https://github.com/tjtanjin/react-chatbotify" rel="noopener noreferrer"&gt;react-chatbotify&lt;/a&gt;. This project had many issues related to testing, which seemed right because, at the time, our weekly assignment was to write test cases, use mocks, etc., in our own &lt;a href="https://github.com/Mounayer/OptimizeIt" rel="noopener noreferrer"&gt;project&lt;/a&gt;. For the second project I chose to contribute to, I went back to &lt;a href="https://github.com/huggingface/chat-ui" rel="noopener noreferrer"&gt;HuggingFace's chat-ui&lt;/a&gt;. This time, I wanted to contribute something much larger than I was used to, ideally something that I hadn't done before.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Issue
&lt;/h2&gt;

&lt;p&gt;For my &lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/165" rel="noopener noreferrer"&gt;first issue&lt;/a&gt;, I was tasked with creating several unit test cases for the &lt;code&gt;ChatHistoryService&lt;/code&gt; component in the &lt;a href="https://github.com/tjtanjin/react-chatbotify" rel="noopener noreferrer"&gt;react-chatbotify&lt;/a&gt; repo. The issue itself was very well described; it even came with examples of how to do it, where the service was located, and the location of the test folder.&lt;/p&gt;

&lt;p&gt;However, I had never mocked nor tested React components using &lt;code&gt;Jest&lt;/code&gt; before, so this was an entirely new experience for me. After reading some of the existing tests, I had an idea of how to start and how mocking really worked (because I had to do a lot of it). Halfway through testing, I started to become a little irritated because of the amount of time it took to run all the test cases just to see if my test cases passed or not. But then I remembered that in that same week, Professor &lt;a href="https://github.com/humphd" rel="noopener noreferrer"&gt;Humphrey&lt;/a&gt; had suggested, as an optional step for our weekly assignment, that we find out how to run a single test case using &lt;code&gt;Jest&lt;/code&gt;, and I did! So I immediately went to the same project's repo and opened a &lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/259" rel="noopener noreferrer"&gt;new issue&lt;/a&gt; suggesting that a new script be added to allow running a single test file. The repo maintainer then replied and asked me if I could handle that too, which I included in my &lt;a href="https://github.com/tjtanjin/react-chatbotify/pull/260" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I have to say though, I did not enjoy mocking with Jest. I personally think &lt;a href="https://japa.dev/docs/introduction" rel="noopener noreferrer"&gt;Jappa&lt;/a&gt; is superior in every way when it comes to mocking services and components! However, I did learn something new and tried it out! I also learned that if I am working on an open source project and I see something that can be improved that isn't mentioned as an issue already, I should open it up myself!&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Issue
&lt;/h2&gt;

&lt;p&gt;For my &lt;a href="https://github.com/huggingface/chat-ui/issues/1545" rel="noopener noreferrer"&gt;second issue&lt;/a&gt; in &lt;a href="https://github.com/huggingface/chat-ui" rel="noopener noreferrer"&gt;Hugging Face's chat-ui&lt;/a&gt;, I was tasked with completely revamping the main &lt;code&gt;ChatInput&lt;/code&gt; component to make it support some &lt;code&gt;Markdown&lt;/code&gt; features such as &lt;code&gt;bolding&lt;/code&gt; and &lt;code&gt;italicizing&lt;/code&gt;, additionally supporting &lt;code&gt;code blocks&lt;/code&gt;, similar to the &lt;a href="https://claude.ai/" rel="noopener noreferrer"&gt;Claude AI&lt;/a&gt; chat input.&lt;/p&gt;

&lt;p&gt;When I first accepted this feature, I did not realize that I would have to work with something completely new to me: &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt;, an open-source component-based front-end framework! This came as a shock to me as I opened the &lt;code&gt;ChatInput&lt;/code&gt; component and realized that this was a file where there was TypeScript code, HTML elements, and styles all in the same file!&lt;/p&gt;

&lt;p&gt;While it did look readable and fairly intuitive to understand, it was still a little terrifying, particularly in such a large project! Nevertheless, I immediately headed to the documentation to understand what was going on and what all of these things meant!&lt;/p&gt;

&lt;p&gt;After practicing a little bit, I felt like I was ready to tackle the issue, and I was! I understood that Svelte offers lots of functions to help with mounting and unmounting components, manipulating the DOM, etc.&lt;/p&gt;

&lt;p&gt;Now that I knew what I knew, it was time to start. Before I even began to consider how to solve this, I knew how these large projects feel about dependencies, so I went to the &lt;code&gt;package.json&lt;/code&gt; file to check and see if there were things that I could work with. And what do you know? &lt;code&gt;highlight.js&lt;/code&gt; was already included! What I immediately thought of was perhaps using the &lt;a href="https://www.npmjs.com/package/marked" rel="noopener noreferrer"&gt;marked&lt;/a&gt; parser in addition to &lt;code&gt;highlight.js&lt;/code&gt; to create and use my code blocks. But after quite a lot of time attempting this, I realized that hand-rolling this solution would not only take a lot of time but would also require a lot of code.&lt;/p&gt;

&lt;p&gt;I then tried something different: &lt;a href="https://www.npmjs.com/package/markdown-it" rel="noopener noreferrer"&gt;markdown-it&lt;/a&gt;, which is another Markdown parser that offers some other features that I could find useful. I almost succeeded in creating this; however, I still needed a lot of code to listen in on key presses and conditions of when and when not to convert into markdown, etc.&lt;/p&gt;

&lt;p&gt;Finally, I wanted to look for a tool that could offer much more help, and so I started looking into WYSIWYG (What you see is what you get) editors. And lo and behold, there were many editors that I could use which could help me accomplish my task.&lt;/p&gt;

&lt;p&gt;However, after doing some extensive research, I realized that almost none of them were compatible with &lt;code&gt;Svelte&lt;/code&gt;, and those that were did not offer what I was looking for. That is, until I found &lt;a href="https://www.npmjs.com/package/@tiptap/core" rel="noopener noreferrer"&gt;tiptap&lt;/a&gt;, which is a headless wrapper around another WYSIWYG editor called &lt;a href="https://prosemirror.net/" rel="noopener noreferrer"&gt;ProseMirror&lt;/a&gt;. However, ProseMirror is very low level, and &lt;code&gt;tiptap&lt;/code&gt; is super &lt;code&gt;Svelte&lt;/code&gt; friendly!&lt;/p&gt;

&lt;p&gt;After reading the docs and replacing the existing &lt;code&gt;textarea&lt;/code&gt; component with the &lt;code&gt;tiptap editor&lt;/code&gt;, I realized, hey, this could actually work!&lt;/p&gt;

&lt;p&gt;Now, you know, I know, and everybody knows, nothing in software development is going to work straight out of the box! I started to note some weird patterns, certain pieces of text disappearing, and other issues. That is, until I realized that I had to actually manually configure &lt;code&gt;tiptap&lt;/code&gt; to work with my specifications. That meant disabling everything &lt;code&gt;markdown&lt;/code&gt; with the exception of the &lt;code&gt;codeblock&lt;/code&gt;, &lt;code&gt;bolding&lt;/code&gt;, and &lt;code&gt;italicizing&lt;/code&gt;. Afterwards, most of the issues started disappearing; however... my code was not colored! &lt;code&gt;highlight.js&lt;/code&gt; was not working very well with &lt;code&gt;tiptap&lt;/code&gt;, and so my joy faded momentarily... Until I found the incredible tool -- &lt;a href="https://www.npmjs.com/package/lowlight" rel="noopener noreferrer"&gt;lowlight&lt;/a&gt;, which offers &lt;code&gt;virtual syntax highlighting&lt;/code&gt; for virtual DOMs and non-HTML things based on &lt;code&gt;highlight.js&lt;/code&gt;! And what do you know, &lt;code&gt;lowlight&lt;/code&gt; already has an actual extension in &lt;code&gt;tiptap&lt;/code&gt; -- &lt;a href="https://www.npmjs.com/package/@tiptap/extension-code-block-lowlight" rel="noopener noreferrer"&gt;@tiptap/extension-code-block-lowlight&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;This was great and so easy to work with. I installed the extension, simply plugged it into the &lt;code&gt;tiptap&lt;/code&gt; editor settings, and et voila! Everything worked spectacularly!&lt;/p&gt;

&lt;p&gt;That is, until... I tried to work out the edge cases... Back and forth navigation, resizing, creating several code blocks in a row...&lt;/p&gt;

&lt;p&gt;And so, I started tackling these issues one by one. The issue that arose with back and forth navigation was that the &lt;code&gt;editor&lt;/code&gt; was being created every time the same &lt;code&gt;ChatInput&lt;/code&gt; component was called, such as when an error happens, resulting in the creation of more than one. Luckily, &lt;code&gt;Svelte&lt;/code&gt; offers certain functions that help with unmounting a component appropriately. I also made sure the newly added codeblock would resize and work in all resolutions (if you REALLY want to create a codeblock and code on your phone, that is). Finally, for the most problematic issue of them all... I was, for some reason, unable to create a new code block except at the beginning of the input. As in, if I went to a newline and tried to open a new code block, nothing happened. Apparently, that is the default behavior of &lt;code&gt;tiptap&lt;/code&gt;; however, after some extensive research, GitHub post and issue reading, and StackOverflow posts, I figured out that there was a way to customize the codeblock's behaviors! And so I did.&lt;/p&gt;

&lt;p&gt;Once I got several codeblocks to work at the same time, the final issue arose! If I wrote some text before a code block and opened a codeblock right after, magically, the text before got inserted into the codeblock. After quite a lot of time and investigation, I realized that &lt;code&gt;tiptap&lt;/code&gt; was removing the previously created paragraph element, taking its contents, and feeding it into the codeblock! And so I had to modify the behavior manually one more time by creating an empty element before the creation of the code block. This helped separate the codeblock from anything that came before it!&lt;/p&gt;

&lt;p&gt;Finally, my job was done. I'd tested every edge case I could think of, polished my code, and created my &lt;a href="https://github.com/huggingface/chat-ui/pull/1562" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Update
&lt;/h3&gt;

&lt;p&gt;But this was not done yet! I received some suggestions and ideas from the maintainer, and tiny bug that I did not encounter myself!&lt;/p&gt;

&lt;p&gt;I was asked to separate the &lt;code&gt;Markdown Editor&lt;/code&gt; I created from the original &lt;code&gt;ChatInput&lt;/code&gt; component I was working on, since it might get used by other components in the future. Additionally, &lt;a href="https://github.com/nsarrazin" rel="noopener noreferrer"&gt;the maintainer&lt;/a&gt; had some other suggestions, such as adding a feature to allow inline code blocks &lt;code&gt;like this&lt;/code&gt; which I did! As well as trying to apply the &lt;code&gt;highlight.js&lt;/code&gt; theme the LLM code block responses already use to the Markdown Editor, which I also did.&lt;/p&gt;

&lt;p&gt;Lastly, for the bug, I simply added some very well needed validation for the conditions of when the code block should be created, and that solved it like a charm!&lt;/p&gt;

&lt;p&gt;It's so much fun getting into things you haven't done before, working with tools and technologies you are a stranger to, it keeps things exciting!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At the end of this release, I definitely feel like I put much more into my open source contributions in these two issues than the four last issues combined! I've learned many things, such as opening an issue myself if I could see a potential improvement that was not addressed, doing extensive research before deciding on a specific implementation, and docs, docs, docs!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>svelte</category>
      <category>typescript</category>
      <category>testing</category>
    </item>
    <item>
      <title>GitHub Workflows: The First Line of Defense</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Sun, 10 Nov 2024 22:16:57 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/github-workflows-the-first-line-of-defense-4lck</link>
      <guid>https://dev.to/majd_almnayer_2101/github-workflows-the-first-line-of-defense-4lck</guid>
      <description>&lt;p&gt;For this week, our task was to automate everything: GitHub workflows for testing, linting, building, and error checking. Additionally, I set up a &lt;a href="https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers" rel="noopener noreferrer"&gt;dev container&lt;/a&gt; that contributors can use in &lt;a href="https://github.com/features/codespaces" rel="noopener noreferrer"&gt;GitHub Codespaces&lt;/a&gt; for a fast, hassle-free setup. Finally, we were assigned to write tests for a classmate's project!&lt;/p&gt;

&lt;p&gt;Setting up the GitHub Actions CI workflow was straightforward, as I had already done it several weeks ago in release 0.1. The workflow includes several jobs. The first job builds the project and ensures there are no build errors. The second job runs eslint to ensure the code meets our linting standards. The third job runs the tests and verifies they all pass! I also configured the GitHub workflows to run only on pull requests when they are opened, reopened, marked as ready for review, or when new commits are pushed.&lt;/p&gt;

&lt;p&gt;Setting up workflows is not new for me, as I’ve done it previously in the Cloud Computing course and in my job. As for adding tests to a pclassmate's project](&lt;a href="https://github.com/cleobnvntra/genereadme/pull/19" rel="noopener noreferrer"&gt;https://github.com/cleobnvntra/genereadme/pull/19&lt;/a&gt;), The main difference between my partner’s testing setup and mine was in code granularity. I made sure my code is modular, with small, testable pieces working together, making it easier to test. My partner’s code, however, was constructed in a way that combined many elements in the same file, which made testing slightly harder. Still, I found that it’s possible to test effectively without needing extensive project context—I covered edge cases, handled errors, and more.&lt;/p&gt;

&lt;p&gt;CI is amazing and should always be one of the first setups in a project, especially for testing and linting. It ensures that the project follows standards, all tests pass, and builds don’t fail before a change is pushed to the main branch!&lt;/p&gt;

&lt;p&gt;For the optional challenges, I had already set up linting in my workflow, so this was already done. However, setting up the &lt;code&gt;devcontainer&lt;/code&gt; was certainly challenging. I encountered an issue with the Docker visual studio code extension that caused the devcontainer's build to fail on Windows but pass on WSL. After some troubleshooting, I found a workaround: cleaning any locally cached files (using &lt;code&gt;apt-get clean&lt;/code&gt;) before the build process started.&lt;/p&gt;

&lt;p&gt;Finally, the devcontainer was set up with all the recommended extensions, rules, and settings required to provide a premium, hassle-free contribution experience for &lt;code&gt;OptimizeIt&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;And the coolest part? Anyone can use GitHub Codespaces to run the devcontainer instantly, allowing for the smoothest possible development experience when contributing. No more Operating System issues, no more “but it worked on my machine,” and no more time wasted on annoying setup steps—everything is ready for any contributor!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayqr6vcxfru1p1xxegq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayqr6vcxfru1p1xxegq1.png" alt="Codespaces" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Overall, I’d say this week was essential for open-source development. Ensuring your repository is guarded against issues that might otherwise cause problems is the &lt;code&gt;first line of defense&lt;/code&gt;. It’s crucial for maintaining cleanliness and adhering to standard guidelines. Additionally, having a ready-to-use development environment for contributors not only smooths the development experience but also encourages more people to contribute with ease!&lt;/p&gt;

</description>
      <category>ci</category>
      <category>opensource</category>
      <category>containers</category>
      <category>github</category>
    </item>
    <item>
      <title>Testing &amp; Mocking With Jest!</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Sun, 03 Nov 2024 22:41:05 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/testing-mocking-with-jest-5ok</link>
      <guid>https://dev.to/majd_almnayer_2101/testing-mocking-with-jest-5ok</guid>
      <description>&lt;p&gt;The time has finally come to test our work! This week, we were asked to introduce a testing framework into our &lt;a href="https://github.com/Mounayer/OptimizeIt" rel="noopener noreferrer"&gt;project&lt;/a&gt; and to write tests!&lt;/p&gt;

&lt;p&gt;My go-to was &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt;, particularly because I hadn't used Jest to mock services before and was curious how it would work. Of course, I had to install the TypeScript version of Jest and an ESLint plugin, but soon after, Jest was installed and running.&lt;/p&gt;

&lt;p&gt;Jest is arguably one of the most popular, if not the most widely used, testing frameworks for JavaScript and TypeScript. It seemed only right to deepen my knowledge of its mocking capabilities for this project.&lt;/p&gt;

&lt;p&gt;Setting up Jest was straightforward and hassle-free. Simply install the package, its TypeScript types, and voilà, it works. However, as I mentioned, since I use ESLint, I also had to install the Jest ESLint plugin so that ESLint recognizes the types without requiring explicit imports everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Thankfully, when I started developing &lt;code&gt;OptimizeIt&lt;/code&gt;, one of my primary concerns was how to make it modular, scalable, and testable. The answer, of course, is separation of concerns and smaller functions. Unlike the code I used to write several years ago, I now consider several factors when coding. One of these for this project was ensuring that complex logic remained simple enough to be both performant and easily tested.&lt;/p&gt;

&lt;p&gt;This made the testing process much easier; I ended up with standalone test files for each small piece of functionality in my entire project, including the Groq chat completion API!&lt;/p&gt;

&lt;p&gt;I was pleasantly surprised to see that I hadn’t missed any edge cases. I tried to be as thorough as possible when testing each function: How could it break? What would happen if I did this? What would happen if I used incorrect data? Thankfully, everything worked as expected.&lt;/p&gt;

&lt;p&gt;As for testing the chat completion API provided by &lt;a href="https://groq.com/" rel="noopener noreferrer"&gt;Groq&lt;/a&gt;, my approach was pretty simple: Get the actual response JSON format, mock it, mock the chat completion API, and test!&lt;/p&gt;

&lt;p&gt;I ended up with a thorough test suite for the heart of my project—the chat completion functionality—and it worked just as expected.&lt;/p&gt;

&lt;p&gt;After several hours of writing tests, I achieved a pretty solid 96% code coverage!&lt;/p&gt;

&lt;p&gt;Now, I have a lot of experience with testing from previous courses, personal projects, and my job. In my job, I've thoroughly tested and mocked several tricky cloud provider services. Testing OptimizeIt was straightforward, though I was initially a bit stuck figuring out how to start the mocking process with &lt;code&gt;Jest&lt;/code&gt; since &lt;code&gt;Jappa/Runner&lt;/code&gt;, the tool I use at work, simplifies this process.&lt;/p&gt;

&lt;p&gt;Finally, I added a couple of extremely helpful scripts to OptimizeIt: one that runs tests whenever source code changes, one that calculates code coverage and generates a report in the &lt;code&gt;coverage&lt;/code&gt; folder, and one particularly useful script that allows you to run a single test file! Then, I added a new job to my CI workflow that runs all the tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This week’s task was substantial; it’s not easy or quick to write tests that maintain high coverage (80%+) for a project with this much functionality. However, it was a great learning experience. Writing tests always helps improve the way you write code. It helps you catch edge cases you hadn’t thought of or small logical issues, like an &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; instead of an &lt;code&gt;||&lt;/code&gt;, that could cause a problem if not caught.&lt;/p&gt;

&lt;p&gt;While it's impossible to catch every edge case, I believe there's always that one edge case you don't think of that could break your code. This is one reason why versions exist in projects—no one can make something perfect right off the bat, though perhaps over time!&lt;/p&gt;

&lt;p&gt;Personally, what I valued most from this was keeping the source code simple. Not only does this make it more readable, but also much, much easier to test!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>opensource</category>
      <category>typescript</category>
      <category>openai</category>
    </item>
    <item>
      <title>Clean Code: Open Source Linting &amp; Formatting</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Sun, 27 Oct 2024 18:58:53 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/clean-code-open-source-linting-formatting-1g8l</link>
      <guid>https://dev.to/majd_almnayer_2101/clean-code-open-source-linting-formatting-1g8l</guid>
      <description>&lt;p&gt;For this week, we were tasked to choose a linter, a formatter, and to add a &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; file for our project!&lt;/p&gt;

&lt;p&gt;Personally, I always consider adding a formatter and a linter to be one of the most essential first steps before even starting to work on a project. I set them up weeks ago because I simply cannot work without following the standards. However, I will discuss them in detail, why I chose what I chose, and how I set them up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting
&lt;/h2&gt;

&lt;p&gt;For formatting, my go-to is always the beloved &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; package/extension! This was introduced to me first in the Cloud Computing for Developers course I took with &lt;a href="https://github.com/humphd" rel="noopener noreferrer"&gt;Professor Humphrey&lt;/a&gt; last year.&lt;/p&gt;

&lt;p&gt;Prettier is a wonderful tool that automatically formats your code based on some guidelines set in its config file. For example, here is the &lt;code&gt;.prettierrc&lt;/code&gt; config file I use for &lt;code&gt;OptimizeIt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"semi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"singleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trailingComma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"printWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"endOfLine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auto"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While Prettier does have its default rules, you can add your own rules in this file. Personally, I asked it to always include a semicolon at line endings, use single quotes ('') instead of double quotes ("") where applicable, and apply some other settings!&lt;/p&gt;

&lt;p&gt;This tool helps a dev team, a company, or a department establish its own standards and guidelines for writing clean and maintainable code.&lt;/p&gt;

&lt;p&gt;Prettier can also be configured to automatically format on file save! This can easily be done in Visual Studio Code by simply going into the settings and enabling the option. It can also be done in many other IDEs!&lt;/p&gt;

&lt;p&gt;I also provided a script to run Prettier manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Linting
&lt;/h2&gt;

&lt;p&gt;For linting, my go-to is usually &lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt;. Unlike formatting, which is meant to keep your code clean and readable, linting helps detect issues in your code, such as unused variables, attempts to change an immutable variable, and many more. ESLint is my go-to because I always use &lt;a href="https://www.npmjs.com/package/eslint-config-airbnb" rel="noopener noreferrer"&gt;Airbnb's ESLint Configurations&lt;/a&gt; in my projects. ESLint allows you to set many rules for your source code, such as using a specific naming convention, forbidding &lt;code&gt;vanilla&lt;/code&gt; for-loops, or prefix and postfix operators, restricting single exports in a file to &lt;code&gt;export default&lt;/code&gt;, and many more.&lt;/p&gt;

&lt;p&gt;The reason I always use the Airbnb ESLint Config is that it's widely regarded as one of the cleaner and more efficient ways to write code. Many smart people spent countless hours carefully choosing the best rules to follow, and which to avoid, and placed them all together in that config file, which is used by millions of projects every week!&lt;/p&gt;

&lt;p&gt;However, ESLint is slow. It takes time to run and fix issues, particularly in large projects. I wanted to try out something I hadn't used before for this lab, since I had already implemented the formatter and the linter weeks ago. I tried &lt;a href="https://oxc.rs/" rel="noopener noreferrer"&gt;Oxc&lt;/a&gt;, which is a JavaScript linter that is Prettier-compatible and ESLint-friendly, written in &lt;code&gt;Rust&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Installing this tool was pretty straightforward, and I was really excited to see its performance given that it's written in Rust, and on their &lt;a href="https://oxc.rs/docs/guide/introduction.html" rel="noopener noreferrer"&gt;official website&lt;/a&gt;, they boast about how much faster their tool is than alternatives.&lt;/p&gt;

&lt;p&gt;Not only was this tool fast, easy to use, and efficient, but it also displays errors in an incredibly intuitive way! It clearly shows what is wrong, what rule was broken, and how to fix it clearly! Unlike ESLint, which doesn't show as much detail about what went wrong.&lt;/p&gt;

&lt;p&gt;The documentation also mentioned an &lt;a href="https://github.com/oxc-project/eslint-plugin-oxlint" rel="noopener noreferrer"&gt;ESLint plugin&lt;/a&gt; so that &lt;code&gt;Oxc&lt;/code&gt; works with &lt;code&gt;ESLint&lt;/code&gt;, that I simply injected into the &lt;code&gt;ESLint&lt;/code&gt; config file &lt;code&gt;eslint.config.mjs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of an error caught by &lt;code&gt;Oxc&lt;/code&gt;, just look at how elegant and clean it is, it has colors too!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsxi67r3repb9q93na1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsxi67r3repb9q93na1h.png" alt="Oxc Error Example" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also provided a script to run linting manually, which runs both &lt;code&gt;Oxc&lt;/code&gt; and &lt;code&gt;ESLint&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run lint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pre-Commit Checks
&lt;/h2&gt;

&lt;p&gt;Once both linting and formatting were set up, I wanted to dig in and see how to run both linting and formatting before a commit is made! This is something I hadn't done before, and I didn't know where to start or what to look for. My first approach was to go to Google and search "pre-commit command run packages npm". However, I didn't get very far doing that.&lt;/p&gt;

&lt;p&gt;My second approach is to always ask &lt;code&gt;ChatGPT&lt;/code&gt; to do a Bing (I wish it was google too, believe me) search for me and find tools that fit my criteria. And it did! I was recommended two packages, &lt;a href="https://typicode.github.io/husky/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; and &lt;a href="https://github.com/lint-staged/lint-staged" rel="noopener noreferrer"&gt;lint-staged&lt;/a&gt;, which work together! &lt;code&gt;Husky&lt;/code&gt; is a package that provides ultra-fast modern native Git hooks, and &lt;code&gt;lint-staged&lt;/code&gt; is a tool that allows running linters against staged Git files!&lt;/p&gt;

&lt;p&gt;Once I knew what tools to use, I delved into the documentation, which was surprisingly very easy to follow. I simply had to install &lt;code&gt;Husky&lt;/code&gt;, &lt;code&gt;lint-staged&lt;/code&gt;, and update the Husky pre-commit script to run the &lt;code&gt;lint-staged&lt;/code&gt; configuration I made before a commit is made!&lt;/p&gt;

&lt;p&gt;For context, this is my &lt;code&gt;lint-staged&lt;/code&gt; configuration for &lt;code&gt;OptimizeIt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"*.{js,ts,json}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"eslint --fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"npx oxlint --fix"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For my config, I require formatting and linting for all JavaScript, TypeScript, and JSON files!&lt;/p&gt;

&lt;p&gt;And it worked like magic. I tested it in different scenarios. Whenever a commit is made and a violation occurs, I get an error in my IDE with a button to check the logs. In the logs, there is detailed information about what issue happened, why the error occurred, and everything we need to solve the problem!&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Now, the reason I did not encounter any linting or formatting issues when I ran the scripts is that I had them installed several weeks ago. However, even when I am developing, I rarely encounter ESLint issues, mainly because I have been working with it for a while and I know how it works and what it violates. Although, encountering ESLint issues is very normal when working on new projects with different rules, and we as programmers have to simply follow these rules to provide the cleanest, most error-free code possible.&lt;/p&gt;

&lt;p&gt;What I loved the most this week was learning about pre-commit linting and formatting. This was something new for me, and I honestly thought implementing it would take quite a while, that I'd have to work with shell scripts and other Git configurations. However, it turned out to be much easier than I thought!&lt;/p&gt;

&lt;p&gt;Overall, these steps are extremely essential, and I believe that formatting and linting should be the very first things introduced in a project, to avoid issues if implemented later on.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>opensource</category>
      <category>typescript</category>
      <category>formatting</category>
    </item>
    <item>
      <title>Hacktoberfest Conclusion: Hugging Face Finale!</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Fri, 25 Oct 2024 18:52:11 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/hacktoberfest-conclusion-hugging-face-finale-4hj4</link>
      <guid>https://dev.to/majd_almnayer_2101/hacktoberfest-conclusion-hugging-face-finale-4hj4</guid>
      <description>&lt;p&gt;For the last week of Hacktoberfest, I wanted to do something special. I wanted to contribute to a much larger repository than I had contributed to so far!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue
&lt;/h2&gt;

&lt;p&gt;What project would fit better than one where the theme is similar to our labs? On to Hugging Face repositories!&lt;/p&gt;

&lt;p&gt;After browsing their repositories, I set my mind on the &lt;a href="https://github.com/huggingface/chat-ui" rel="noopener noreferrer"&gt;chat-ui&lt;/a&gt; project. Chat-ui is the open-source codebase powering the &lt;code&gt;HuggingChat&lt;/code&gt; app! The &lt;code&gt;HuggingChat&lt;/code&gt; app is a chat-based web app that allows interaction with a variety of different language models, such as &lt;code&gt;llama&lt;/code&gt;, &lt;code&gt;cohere&lt;/code&gt;, and &lt;code&gt;mistralai&lt;/code&gt; models, and more!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/huggingface/chat-ui/issues/1432" rel="noopener noreferrer"&gt;issue&lt;/a&gt; I chose discussed implementing a new feature for the existing model configuration in the app. While this is something I personally did not know before, apparently some models do &lt;em&gt;not&lt;/em&gt; support &lt;code&gt;system&lt;/code&gt; role prompts, but rather only &lt;code&gt;user&lt;/code&gt; role prompts. Therefore, models that do not support &lt;code&gt;system&lt;/code&gt; role prompts failed to work on the app.&lt;/p&gt;

&lt;p&gt;My task was to implement a new model configuration option that allows the user to specify whether the model in use supports or does not support &lt;code&gt;system&lt;/code&gt; role prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process
&lt;/h2&gt;

&lt;p&gt;The setup process took quite a long time (another downside of being a Windows user), even though I was using &lt;code&gt;WSL&lt;/code&gt;, which powers an &lt;code&gt;Ubuntu&lt;/code&gt; subsystem on my PC. Not only that, but building and running the &lt;code&gt;llama.cpp server&lt;/code&gt; was not only time-consuming but also extremely resource-intensive. I could feel the hit my PC's performance took when I got it up and running. Nevertheless, once it was all set up, and I made sure everything worked, it was time to start development!&lt;/p&gt;

&lt;p&gt;The very first thing I did was search for &lt;code&gt;modelConfig&lt;/code&gt; in all the files, because it was pointed out in the issue that the new option should be added there. I immediately found the file in question.&lt;/p&gt;

&lt;p&gt;The next step was to familiarize myself with the code. I noticed they are using &lt;a href="https://www.npmjs.com/package/zod" rel="noopener noreferrer"&gt;Zod&lt;/a&gt; for validation and type inference, and I could see where all the user prompts are being passed, and system prompts are being set.&lt;/p&gt;

&lt;p&gt;After identifying where I needed to insert the new feature, I made sure to make the least amount of changes possible to support this new feature. I added a new variable to the Zod validator, &lt;code&gt;systemRoleSupported&lt;/code&gt; which is true by default, and simply filtered out all system prompts before they were passed to the models.&lt;/p&gt;

&lt;p&gt;I also ensured that hard-coded system prompts preferred user prompts if the user specified that the model does not support the system prompt.&lt;/p&gt;

&lt;p&gt;After a lot of code reading and testing, my &lt;a href="https://github.com/huggingface/chat-ui/pull/1539" rel="noopener noreferrer"&gt;pull request&lt;/a&gt; was up. I got one tiny requested change from the repo maintainer asking for a better name for the new model config option, but once that was addressed, all checks passed, and the pull request is now ready to be merged!&lt;/p&gt;

&lt;h2&gt;
  
  
  Hacktoberfest Conclusion
&lt;/h2&gt;

&lt;p&gt;Overall, I would say this was one of the most fun and engaging experiences I've had in my program yet. The idea of contributing to random projects supported by strangers with similar goals is exhilarating. Seeing every open-source contributor and maintainer following the best practices that we were taught, and communicating effectively, was inspiring, and yet another proof that I was born to do this, because it's just so much fun!&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>ai</category>
      <category>typescript</category>
    </item>
    <item>
      <title>P2P, WebSockets &amp; WebTorrent</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Thu, 17 Oct 2024 23:51:23 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/p2p-websockets-webtorrent-3om1</link>
      <guid>https://dev.to/majd_almnayer_2101/p2p-websockets-webtorrent-3om1</guid>
      <description>&lt;p&gt;For this week, I decided to contribute using a different language. My goal was either JavaScript or TypeScript, and I ended up finding an extremely interesting project called &lt;a href="https://github.com/blenderskool/blaze" rel="noopener noreferrer"&gt;Blaze&lt;/a&gt;. Blaze is a peer-to-peer file-sharing progressive web app built using WebTorrent and WebSockets. Although there weren't many open issues in this project, I found one that seemed interesting to me. For my &lt;a href="https://github.com/blenderskool/blaze/issues/172" rel="noopener noreferrer"&gt;issue&lt;/a&gt; this week, I was tasked with displaying error modal popups to users for certain uncovered edge cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue
&lt;/h2&gt;

&lt;p&gt;The issue was not very descriptive, and the only information provided was, "When the connection to the Blaze server fails, no feedback is given to the user."&lt;/p&gt;

&lt;p&gt;Therefore, my goal for this week was to investigate and analyze all uncovered edge cases where the backend might fail, resulting in no error messages being displayed to the user.&lt;/p&gt;

&lt;p&gt;To begin, I isolated the front-end files where my modifications might take place. At first, I thought the front-end was written in React, but it turned out to use a different library called &lt;a href="https://preactjs.com/" rel="noopener noreferrer"&gt;Preact&lt;/a&gt;, which is an alternative to React with the same API but much faster.&lt;/p&gt;

&lt;p&gt;Afterwards, my task was straightforward: trace, investigate, isolate, and update. My first instinct was to close the connection to the backend and analyze the front-end to determine where error messages should pop up. I found several uncovered edge cases and updated the app to use an error modal, leveraging a component that already existed in the source code.&lt;/p&gt;

&lt;p&gt;After creating my &lt;a href="https://github.com/blenderskool/blaze/pull/176" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;, the project maintainer replied, thanking me for my well-written pull request and providing detailed descriptions. However, they also suggested some changes and asked for my opinion regarding one of them. After discussing it with the repo owner directly on the pull request, I set out to apply the requested changes. However, I noticed one of the changes seemed redundant, so I replied to their comment, asking for their opinion this time. Unfortunately, that was several days ago, and I haven't received a response yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going Forward
&lt;/h2&gt;

&lt;p&gt;I have to admit, it feels like a letdown not to receive a timely response after dedicating personal time to the project. While I enjoyed working on the project, learning Preact, WebTorrent, and analyzing the code, I felt disappointed that I couldn't complete my pull request this week.&lt;/p&gt;

&lt;p&gt;Perhaps that was my own fault. The repo was active, but its last update was about a year ago. I think that from now on, I will only contribute to repositories that have been recently updated.&lt;/p&gt;

&lt;p&gt;Despite that, I thoroughly enjoyed working on my issue this week and am looking forward to the next one!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Contributing To Open Source - C++ Edition</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Tue, 08 Oct 2024 23:00:31 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/contributing-to-open-source-c-edition-255a</link>
      <guid>https://dev.to/majd_almnayer_2101/contributing-to-open-source-c-edition-255a</guid>
      <description>&lt;p&gt;Following last week, where I did my first straightforward open source contribution, this week I wanted to tackle bigger contributions.&lt;/p&gt;

&lt;p&gt;For starters, I came across a &lt;a href="https://github.com/codewithnick/ascii-art" rel="noopener noreferrer"&gt;C/C++ Library that prints the alphabet as ASCII art&lt;/a&gt; in different fonts.&lt;/p&gt;

&lt;p&gt;However, afterward, I still wanted to do more, so I started looking for a larger project to contribute to. To my surprise, the very popular &lt;a href="https://fakerjs.dev/" rel="noopener noreferrer"&gt;faker.js&lt;/a&gt; library has a C++ version in the works, &lt;a href="https://github.com/cieslarmichal/faker-cxx" rel="noopener noreferrer"&gt;faker-cxx&lt;/a&gt;, which I was very excited to work on!&lt;/p&gt;

&lt;h2&gt;
  
  
  First Contribution
&lt;/h2&gt;

&lt;p&gt;For my first &lt;a href="https://github.com/codewithnick/ascii-art/issues/1058" rel="noopener noreferrer"&gt;issue&lt;/a&gt; of this week, I was tasked with adding a new letter to the &lt;code&gt;drpepper&lt;/code&gt; font in the &lt;a href="https://github.com/codewithnick/ascii-art" rel="noopener noreferrer"&gt;ascii-art&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;This was a straightforward task because the file structure was very easy to navigate. There was a folder called &lt;code&gt;fonts&lt;/code&gt; containing the supported fonts. Before I began the process of adding my new character, I examined how others had added characters to the font.&lt;/p&gt;

&lt;p&gt;I simply followed the existing style, added my character, and then submitted my &lt;a href="https://github.com/codewithnick/ascii-art/pull/1118" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, I found the method of adding new fonts somewhat peculiar. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;vs&lt;/span&gt; &lt;span class="nf"&gt;D&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;vs&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getCharGrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'_'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'|'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;'\'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm not entirely sure why it was done this way, but it seems to allow for clear modifications if needed in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Contribution
&lt;/h2&gt;

&lt;p&gt;For my second &lt;a href="https://github.com/cieslarmichal/faker-cxx/issues/937" rel="noopener noreferrer"&gt;issue&lt;/a&gt; in the &lt;a href="https://github.com/cieslarmichal/faker-cxx" rel="noopener noreferrer"&gt;faker-cxx&lt;/a&gt; library, I had to add a new &lt;code&gt;faker&lt;/code&gt; function to the &lt;code&gt;Date&lt;/code&gt; module. This function should mimic its &lt;a href="https://github.com/cieslarmichal/faker-cxx/issues/937" rel="noopener noreferrer"&gt;JavaScript counterpart&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At first, I thought, "It's just one function... how hard can it be?" But I was wrong.&lt;/p&gt;

&lt;p&gt;I had to read through a lot of code to understand how everything was structured, where things were declared, where they were exported, how tests were conducted, and how to add new ones.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/cieslarmichal/faker-cxx/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;contributing guidelines&lt;/a&gt; emphasize that all additions must be thoroughly tested.&lt;/p&gt;

&lt;p&gt;There were many custom types and reusable functions, so I had to familiarize myself with each one before I could start coding.&lt;/p&gt;

&lt;p&gt;Once I identified the necessary files and became accustomed to some initially unfamiliar C++20 syntax, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I realized this is syntactic sugar for templates! This use of &lt;code&gt;auto&lt;/code&gt; allows the function's parameter type to be deduced without explicitly specifying it.&lt;/p&gt;

&lt;p&gt;After understanding the internal functions (used internally for development but not exposed in the API), I added two functions. One accepts two ISO dates, and the other two timestamps. Luckily, there was already an internal function to generate a random date between two given dates, so I mainly needed to manage parameter conversions and preparations.&lt;/p&gt;

&lt;p&gt;Once the functions were ready, I documented them for the API and created and ran the necessary tests. Adding tests was initially confusing, but after examining existing ones, it became straightforward.&lt;/p&gt;

&lt;p&gt;However, running the tests proved challenging. I needed to build the entire library using &lt;code&gt;cmake&lt;/code&gt;, which usually wouldn't be an issue, but I encountered a persistent error with the &lt;code&gt;fmt dependency not found&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Despite following all the steps (on both Windows and Unix), I couldn't get the &lt;code&gt;cmake&lt;/code&gt; build to succeed. After several hours of debugging, I decided to try another build method provided by the project, using &lt;a href="https://bazel.build/" rel="noopener noreferrer"&gt;bazel&lt;/a&gt;, which was much simpler.&lt;/p&gt;

&lt;p&gt;After successfully building the project and running the tests, I was delighted to see all tests pass. I then tested my newly added function in a fresh C++ project, and it worked perfectly!&lt;/p&gt;

&lt;p&gt;Finally, my &lt;a href="https://github.com/cieslarmichal/faker-cxx/pull/951" rel="noopener noreferrer"&gt;pull request&lt;/a&gt; was accepted without any requested changes!&lt;/p&gt;

&lt;p&gt;It felt really great contributing to a well known library like &lt;code&gt;faker&lt;/code&gt;, that I have personally used at my job!&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This week's contributions were incredibly rewarding and exciting. I feel more confident than ever in my ability to contribute to open source projects. Next week, I plan to explore contributions to a project in a different language!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>opensource</category>
      <category>faker</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Optimizing OptimizeIt</title>
      <dc:creator>Majd Al Mnayer</dc:creator>
      <pubDate>Sun, 06 Oct 2024 18:37:39 +0000</pubDate>
      <link>https://dev.to/majd_almnayer_2101/optimizing-optimizeit-2k73</link>
      <guid>https://dev.to/majd_almnayer_2101/optimizing-optimizeit-2k73</guid>
      <description>&lt;p&gt;This week is a nice change of pace. We are tasked with refactoring our projects!&lt;/p&gt;

&lt;p&gt;This means renaming badly named variables, abstracting away logic, creating functions out of duplicate code in several files, looking out for any performance-impacting logic, renaming files, rearranging directories, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring
&lt;/h2&gt;

&lt;p&gt;This required a deep dive into the code, reading every line, and tracing execution because I did not want to make any modification that would impact the current functionality of the program. I just wanted to make it better in any way possible.&lt;/p&gt;

&lt;p&gt;At first glance, I could see some duplicate code in my flag handlers. This was an easy fix. I factored out the duplicate code, made a helper function, and called it where applicable.&lt;/p&gt;

&lt;p&gt;Afterwards, I noticed that the file structure in my project was a bit chaotic. I then decided to move all helper functions to their own &lt;code&gt;helpers&lt;/code&gt; folder. There are two such folders: one is a global &lt;code&gt;helpers&lt;/code&gt; folder, and the other is specific to argument handling.&lt;/p&gt;

&lt;p&gt;Then, during further inspection, I noticed some code was out of place. For example, I had a function that handles file names in the argument handler file. I moved it into its own file, attempting to separate all code that did not share the same context into their own files.&lt;/p&gt;

&lt;p&gt;After completing these three refactors, I decided to use my own tool on itself! That's right, OptimizeIt is going to optimize it! I used OptimizeIt to optimize &lt;code&gt;main.ts&lt;/code&gt;, because it was starting to get unmaintainable with lots of different logic existing there—some for handling output, some for processing files, and some for executing it all together.&lt;/p&gt;

&lt;p&gt;OptimizeIt then optimized it by separating each chunk of logic into its own function! This greatly enhanced not only readability but modularity as well. I then proceeded to create different files in the &lt;code&gt;helpers&lt;/code&gt; folder for each of those functions, and now my &lt;code&gt;main.ts&lt;/code&gt; looks super clean, elegant, and the complex logic that I once had is now in its own files.&lt;/p&gt;

&lt;p&gt;For my final touches, I addressed certain nitpicks I had in the past, such as changing the token usage short flag to &lt;code&gt;-u&lt;/code&gt; instead of &lt;code&gt;-tu&lt;/code&gt;, separating all interfaces into their own files, and some renaming, such as renaming &lt;code&gt;Config&lt;/code&gt; to &lt;code&gt;TomlConfig&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, I bumped the version up from 0.1.1 to 0.1.3, because at some point I forgot to bump the version up to 0.1.2, even though I had a 0.1.2 release on my repo.&lt;/p&gt;

&lt;p&gt;Once the refactoring was complete, I then squashed all of the commits into one, amended it, and merged into main!&lt;/p&gt;

&lt;p&gt;Overall, more work was done than I anticipated. You can see all of the changes in this &lt;a href="https://github.com/Mounayer/OptimizeIt/commit/5ebcc6ff3f1bcc7e3f5a27b8abd79c74de611868" rel="noopener noreferrer"&gt;commit&lt;/a&gt;. However, I now feel much more confident about the state of OptimizeIt, as it's looking very modular, easily maintainable, and super readable!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
