<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Pratik Sharma || react developer || new Delhi]]></title><description><![CDATA[react developer in india, react native developer in new delhi, react js , js developer. Web developer]]></description><link>https://blog.coolhead.in</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1677182263229/XITo1RvuU.png</url><title>Pratik Sharma || react developer || new Delhi</title><link>https://blog.coolhead.in</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 09:50:11 GMT</lastBuildDate><atom:link href="https://blog.coolhead.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Draw Japan Flag Using TSL - Threejs Shading language]]></title><description><![CDATA[Learn More about the japanese Flag → https://en.wikipedia.org/wiki/Flag_of_Japan
import "./style.css"
import * as THREE from 'three/webgpu';
import { abs, color, convertColorSpace, float, Fn, If, positionLocal, texture, rotateUV, time, vec2, fract, v...]]></description><link>https://blog.coolhead.in/draw-japan-flag-using-tsl-threejs-shading-language</link><guid isPermaLink="true">https://blog.coolhead.in/draw-japan-flag-using-tsl-threejs-shading-language</guid><category><![CDATA[ThreejsShadingLanguage]]></category><category><![CDATA[ThreeJS]]></category><category><![CDATA[webgpu]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Fri, 19 Dec 2025 07:43:29 GMT</pubDate><content:encoded><![CDATA[<p>Learn More about the japanese Flag → <a target="_blank" href="https://en.wikipedia.org/wiki/Flag_of_Japan">https://en.wikipedia.org/wiki/Flag_of_Japan</a></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> <span class="hljs-string">"./style.css"</span>
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> THREE <span class="hljs-keyword">from</span> <span class="hljs-string">'three/webgpu'</span>;
<span class="hljs-keyword">import</span> { abs, color, convertColorSpace, float, Fn, If, positionLocal, texture, rotateUV, time, vec2, fract, vec3, mix } <span class="hljs-keyword">from</span> <span class="hljs-string">"three/tsl"</span>;
<span class="hljs-keyword">import</span> { OrbitControls } <span class="hljs-keyword">from</span> <span class="hljs-string">'three/addons/controls/OrbitControls.js'</span>


<span class="hljs-keyword">const</span> scene = <span class="hljs-keyword">new</span> THREE.Scene();

<span class="hljs-keyword">const</span> camera = <span class="hljs-keyword">new</span> THREE.PerspectiveCamera(
  <span class="hljs-number">75</span>,
  <span class="hljs-built_in">window</span>.innerWidth / <span class="hljs-built_in">window</span>.innerHeight,
  <span class="hljs-number">0.1</span>,
  <span class="hljs-number">10</span>
)
camera.position.z = <span class="hljs-number">1</span>

<span class="hljs-keyword">const</span> renderer = <span class="hljs-keyword">new</span> THREE.WebGPURenderer();
renderer.setSize(<span class="hljs-built_in">window</span>.innerWidth, <span class="hljs-built_in">window</span>.innerHeight);
<span class="hljs-built_in">document</span>.body.appendChild(renderer.domElement);
renderer.setAnimationLoop(animate);


<span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'resize'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  camera.aspect = <span class="hljs-built_in">window</span>.innerWidth / <span class="hljs-built_in">window</span>.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(<span class="hljs-built_in">window</span>.innerWidth, <span class="hljs-built_in">window</span>.innerHeight)
})

<span class="hljs-keyword">const</span> controls = <span class="hljs-keyword">new</span> OrbitControls(camera, renderer.domElement);
controls.enableDamping = <span class="hljs-literal">true</span>

<span class="hljs-keyword">const</span> material = <span class="hljs-keyword">new</span> THREE.NodeMaterial();


<span class="hljs-keyword">const</span> shaderMain = Fn(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> p = positionLocal.toVar(); <span class="hljs-comment">// we do this to create a variable of positionLocal which is immutable</span>
  <span class="hljs-keyword">const</span> mask = p.length().step(<span class="hljs-number">0.5</span>);

  <span class="hljs-keyword">const</span> red = vec3(<span class="hljs-number">0.737</span>, <span class="hljs-number">0.0</span>, <span class="hljs-number">0.176</span>)

  <span class="hljs-keyword">const</span> white = vec3(<span class="hljs-number">1</span>);

  <span class="hljs-keyword">return</span> mix(red, white, mask);
})

material.fragmentNode = convertColorSpace(
  shaderMain(),
  THREE.SRGBColorSpace,
  THREE.LinearSRGBColorSpace,
)

material.side = THREE.DoubleSide;



<span class="hljs-keyword">const</span> mesh = <span class="hljs-keyword">new</span> THREE.Mesh(<span class="hljs-keyword">new</span> THREE.PlaneGeometry(<span class="hljs-number">3</span>, <span class="hljs-number">2</span>), material);



scene.add(mesh);

renderer.debug.getShaderAsync(scene, camera, mesh).then(<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(e.vertexShader)
  <span class="hljs-built_in">console</span>.log(e.fragmentShader)
})


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">animate</span>(<span class="hljs-params"></span>) </span>{
  controls.update()
  renderer.render(scene, camera);
}
</code></pre>
<h3 id="heading-result">Result →</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766130120134/a84a330c-bc66-4659-9006-7f368c7804e8.png" alt class="image--center mx-auto" /></p>
<p>###</p>
]]></content:encoded></item><item><title><![CDATA[Improve Your Website Web Vitals]]></title><description><![CDATA[Core Web Vitals metrics →

Largest Contentful Paint → Frist
 Improving the Largest Contentful Paint (LCP) metric. Using a CDN reduces server response times, minimizing third-party scripts lowers JavaScript execution delays, optimizing images and vide...]]></description><link>https://blog.coolhead.in/improve-your-website-web-vitals</link><guid isPermaLink="true">https://blog.coolhead.in/improve-your-website-web-vitals</guid><category><![CDATA[General Programming]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[SEO]]></category><category><![CDATA[webdev]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Tue, 16 Dec 2025 13:37:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765892211103/54f9f51d-0e61-4a0f-b326-ee222b771fcc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Core Web Vitals metrics →</p>
<ol>
<li><p>Largest Contentful Paint → Frist</p>
<p> Improving the Largest Contentful Paint (LCP) metric. Using a CDN reduces server response times, minimizing third-party scripts lowers JavaScript execution delays, optimizing images and videos enhances their load speed, and reducing HTTP requests overall boosts performance, making them all essential for better web loading efficiency.</p>
</li>
<li><p>INP → interaction to next paint</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765891939542/c376681b-2648-466d-8bdf-12351e83316b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Cumulative Layout Shift → Visual Stabillity on a website, Font Change</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765891655382/397531ff-82b4-48c9-b8d2-61a78dc75914.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-good-blogs-on-web-performance">Good Blogs on web performance →</h3>
<p><a target="_blank" href="https://www.dckap.com/blog/">https://www.dckap.com/blog/</a></p>
<p><a target="_blank" href="https://bloggingwizard.com/page-load-time-statistics/#:~:text=%E2%80%9CAt">https://bloggingwizard.com/page-load-time-statistics/#:~:text=“At</a> the BBC we've,20.7 million users lost%2Fmonth</p>
<p><a target="_blank" href="https://www.fastcompany.com/1825005/how-one-second-could-cost-amazon-16-billion-sales">https://www.fastcompany.com/1825005/how-one-second-could-cost-amazon-16-billion-sales</a></p>
<h3 id="heading-google-web-vitals">Google Web Vitals</h3>
<p><a target="_blank" href="https://web.dev/articles/vitals">Web Vitals  |  Articles  |  web.dev</a></p>
<p><img src="https://web.dev/static/articles/vitals/image/largest-contentful-paint-ea2e6ec5569b6.svg" alt="Largest Contentful Paint threshold recommendations" /></p>
<p><img src="https://web.dev/static/articles/vitals/image/inp-thresholds.svg" alt="Interaction to Next Paint threshold recommendations" /></p>
<p><img src="https://web.dev/static/articles/vitals/image/cumulative-layout-shift-t-5d49b9b883de4.svg" alt="Cumulative Layout Shift threshold recommendations" /></p>
<ul>
<li><p><a target="_blank" href="https://web.dev/articles/lcp"><strong>Largest Contentful Paint (LCP)</strong></a>: measures <em>loading</em> performance. To provide a good user experience, LCP should occur within <strong>2.5 seconds</strong> of when the page first starts loading.</p>
</li>
<li><p><a target="_blank" href="https://web.dev/articles/inp"><strong>Interaction to Next Paint (INP)</strong></a>: measures <em>interactivity</em>. To provide a good user experience, pages should have a INP of <strong>200 milliseconds</strong> or less.</p>
</li>
<li><p><a target="_blank" href="https://web.dev/articles/cls"><strong>Cumulative Layout Shift (CLS)</strong></a>: measures <em>visual stability</em>. To provide a good user experience, pages should maintain a CLS of <strong>0.1.</strong> or less.</p>
</li>
</ul>
<h1 id="heading-what-is-tbt">What is TBT?</h1>
<p>The Total Blocking Time (TBT) metric measures the total amount of time after <a target="_blank" href="https://web.dev/articles/fcp">First Contentful Paint (FCP)</a> where the main thread was blocked for long enough to prevent input responsiveness.</p>
<p>By default, Lighthouse stops monitoring TBT after <a target="_blank" href="https://web.dev/articles/tti">Time to Interactive (TTI)</a>, as do some other lab tools that measure page load. See <a target="_blank" href="https://web.dev/articles/tbt#how_does_tbt_relate_to_tti">How does TBT relate to TTI?</a>.</p>
<p>The main thread is considered "blocked" any time there's a <a target="_blank" href="https://web.dev/articles/custom-metrics#long-tasks-api">Long Task</a> a task that runs on the main thread for more than 50 milliseconds. We say the main thread is "blocked" because the browser cannot interrupt a task that's in progress. So in the event that a user <em>does</em> interact with the page in the middle of a long task, the browser must wait for the task to finish before it can respond.</p>
<h3 id="heading-optimising-javascript">Optimising Javascript</h3>
<ol>
<li><p>Minification and Compression - Webpack/ Vite, Gzip</p>
</li>
<li><p>Javascript File Loading → Script tag, defer, async</p>
</li>
<li><p>Loops and iterations Optimisation → use forEach, map or reduce</p>
</li>
<li><p>Dom manipulation optimizations → minimise dom operations, use document fragments</p>
<ul>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment">https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment</a></p>
</li>
<li><p>User Request Animation Frame → We can batch multiple dom update into one update</p>
</li>
</ul>
</li>
<li><p>Event Delegation → Event Bubbling to the parent element to reduce the no. of event listeners</p>
</li>
<li><p>Use JS libraries and Frameworks → react, vue, and angular</p>
</li>
</ol>
<h3 id="heading-optimizing-css">Optimizing CSS</h3>
<ol>
<li><p>Minification and Compression → Webpack/Vite,</p>
<ol>
<li><p><a target="_blank" href="https://www.projectwallace.com/">https://www.projectwallace.com/</a></p>
</li>
<li><p><a target="_blank" href="https://cssstats.com/">https://cssstats.com/</a></p>
</li>
<li><p><a target="_blank" href="https://makersaid.com/tools/css-performance-testing/">https://makersaid.com/tools/css-performance-testing/</a></p>
</li>
</ol>
</li>
</ol>
<h3 id="heading-opimizing-images">Opimizing Images →</h3>
<ul>
<li><p>Image Type → Vector graphics</p>
</li>
<li><p>Tools →</p>
<ul>
<li><p><a target="_blank" href="https://imagemagick.org/index.php">https://imagemagick.org/index.php</a></p>
</li>
<li><p><a target="_blank" href="https://www.npmjs.com/package/sharp">https://www.npmjs.com/package/sharp</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/ApoorvSaxena/lozad.js">https://github.com/ApoorvSaxena/lozad.js</a></p>
</li>
<li><p>ffmpeg</p>
</li>
<li><p>svgomg</p>
</li>
</ul>
</li>
<li><p>CDNS → 40 to 80 % image size delivery optimization</p>
</li>
</ul>
<p>&lt;aside&gt; 💡</p>
<p>Lazy Loading →</p>
<p>&lt;/aside&gt;</p>
<h3 id="heading-tips">Tips →</h3>
<ol>
<li><p>Reduce IFrames</p>
</li>
<li><p>Use Preload attribute</p>
</li>
<li><p>Avoid Inline styles</p>
</li>
<li><p>reduce cookies size → maximum 20</p>
</li>
<li><p>page size → 1500KB</p>
</li>
<li><p>minimise http requests → Like graphql</p>
</li>
<li><p>Use PWA</p>
</li>
</ol>
<h3 id="heading-tips-to-improve-your-chrome-core-vitals">Tips to improve your Chrome Core Vitals →</h3>
<h3 id="heading-chrome-dev-tools-performance-tab">Chrome Dev Tools Performance Tab →</h3>
<h3 id="heading-server-side-bottlenecks">Server Side Bottlenecks →</h3>
<p>Common issues →</p>
<p>inefficient database queries</p>
<p>slow third-party services → payment gateways,</p>
<p>insufficient hardware</p>
<p>server-side code</p>
<p>not-caching, not proper caching</p>
<h3 id="heading-db-optimization">Db optimization →</h3>
<ol>
<li><p>Database Index → for data retrieval</p>
</li>
<li><p>Denormalisation</p>
</li>
<li><p>Materialised Views →</p>
</li>
<li><p>Partitioning</p>
</li>
<li><p>Connection Pooling</p>
</li>
<li><p>Minimise Join operations</p>
</li>
<li><p>Optimise where clauses</p>
</li>
<li><p>Use Pagination</p>
</li>
<li><p>Regular Database Updates</p>
</li>
</ol>
<p>Query Execution Plan →</p>
<p>Detailed a blueprint the step and operations take plan to execute the query .</p>
<p><a target="_blank" href="https://pganalyze.com/docs/explain/basics-of-postgres-query-planning">https://pganalyze.com/docs/explain/basics-of-postgres-query-planning</a></p>
<p>NOSQL database optimization →</p>
<p>Indexes allow the database to quickly locate and retrieve data.</p>
<h3 id="heading-third-party-services">Third Party services →</h3>
<ol>
<li><p>Message Queue → Kafka, RabbitMQ</p>
</li>
<li><p>Connection Polling</p>
</li>
<li><p>Caching</p>
</li>
<li><p>Backup integrations</p>
</li>
</ol>
<h3 id="heading-caching">Caching →</h3>
<ol>
<li><p>Memcached</p>
<p> Memcached is an open source in-memory caching system designed for high performance and distributed environments.</p>
</li>
<li><p>Redis</p>
<p> Redis is an in-memory data structure store that can function as both a database and a cache.</p>
<p> It offers a rich set of data structures and supports advanced caching features such as data exploration,publishing and messaging, subscription and persistence options.</p>
<p> Both Memcached and Redis offer mechanisms for cache invalidation, such as setting time based expiration</p>
</li>
<li><p>Cache Invalidation</p>
</li>
</ol>
<ul>
<li>Resources → <a target="_blank" href="https://redis.io/solutions/caching/">https://redis.io/solutions/caching/</a></li>
</ul>
<h3 id="heading-microservices">Microservices →</h3>
<ul>
<li><p>Modular, Deployment, Scalability,</p>
</li>
<li><p>Service Mesh → Istio, Linkered, and Consul</p>
</li>
</ul>
<h3 id="heading-algo-complexity">Algo Complexity →</h3>
<ul>
<li>Check the Algo Complexity in your code</li>
</ul>
<h3 id="heading-profiling">Profiling →</h3>
<ul>
<li><p>CPU Usage</p>
</li>
<li><p>Memory Usage</p>
</li>
<li><p>Event Loop Delay ms</p>
<p>  <strong>Resources</strong></p>
</li>
<li><p><a target="_blank" href="https://www.npmjs.com/package/clinic">https://www.npmjs.com/package/clinic</a></p>
<pre><code class="lang-bash">  clinic doctor -- node main.js
</code></pre>
<p>  This Generates an HTML file report</p>
</li>
<li><p><a target="_blank" href="https://www.jetbrains.com/profiler/">https://www.jetbrains.com/profiler/</a></p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=visualstudio">https://learn.microsoft.com/en-us/visualstudio/profiling/profiling-feature-tour?view=visualstudio</a></p>
</li>
</ul>
<h3 id="heading-server-side-implementation">Server Side Implementation</h3>
<ul>
<li><p>Data Types</p>
</li>
<li><p>Simple code</p>
</li>
<li><p>Use better Data structures</p>
</li>
<li><p>Performance Testing</p>
</li>
</ul>
<p><strong>Resources</strong></p>
<p><a target="_blank" href="https://gettaurus.org/">https://gettaurus.org/</a></p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/RAID">https://en.wikipedia.org/wiki/RAID</a></p>
<h3 id="heading-network-stack">Network Stack →</h3>
<p><img alt="image.png" /></p>
<pre><code class="lang-bash">    traceroute yourwebsite.com
</code></pre>
<ul>
<li><a target="_blank" href="http://f5.com/products/nginx">f5.com/products/nginx</a> → nginx Loadbalancing</li>
</ul>
<h3 id="heading-performance-monitoring-and-planning-improvements">Performance Monitoring and Planning Improvements →</h3>
<p><a target="_blank" href="https://www.npmjs.com/package/web-vitals">https://www.npmjs.com/package/web-vitals</a></p>
<p><a target="_blank" href="https://www.npmjs.com/package/node-os-utils">https://www.npmjs.com/package/node-os-utils</a></p>
<p>Database Monitoring → Queries/sec, Throughput, Compute Time, connection counts, storage usage, query time execution ,</p>
<p>Monitoring tools →</p>
<ul>
<li><p>Prometheus</p>
</li>
<li><p>Grafana → dashboards</p>
</li>
<li><p>Datadog → Cloud based analytics</p>
</li>
<li><p>New Relic</p>
</li>
<li><p>Elastic → Search</p>
</li>
<li><p>Kibana</p>
</li>
</ul>
<h3 id="heading-notifications">Notifications →</h3>
<p>Set Alerts for monitoring performance issues, decrease downtimes, SLA Compliance,</p>
<p>Set Grafana with Promethesus with alert rules</p>
]]></content:encoded></item><item><title><![CDATA[Understanding npm link and Its Better Alternative in pnpm]]></title><description><![CDATA[If you’ve ever built multiple JavaScript packages that depend on each other, you’ve probably used — or at least heard of — npm link. It’s a handy tool that lets you work on a library and an app at the same time without constantly reinstalling or publ...]]></description><link>https://blog.coolhead.in/understanding-npm-link-and-its-better-alternative-in-pnpm</link><guid isPermaLink="true">https://blog.coolhead.in/understanding-npm-link-and-its-better-alternative-in-pnpm</guid><category><![CDATA[npm]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sun, 26 Oct 2025 14:17:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/oZMUrWFHOB4/upload/27b54651e28bb7650a1a6b644cf7a408.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’ve ever built multiple JavaScript packages that depend on each other, you’ve probably used — or at least heard of — <code>npm link</code>. It’s a handy tool that lets you work on a library and an app at the same time without constantly reinstalling or publishing updates.</p>
<p>But if you’ve switched to <strong>pnpm</strong>, you might wonder — <em>where did my</em> <code>npm link</code> go?<br />Good news: pnpm has better, faster, and more reliable ways to handle local linking.</p>
<p>Let’s dive in 👇</p>
<hr />
<h2 id="heading-what-npm-link-actually-does">🧩 What <code>npm link</code> Actually Does</h2>
<p>When you run <code>npm link</code>, npm creates a symbolic link (symlink) between a local package and another project.</p>
<p>Example structure:</p>
<pre><code class="lang-typescript">/packages/ui
/app
</code></pre>
<h3 id="heading-with-npm">With npm:</h3>
<ol>
<li><p>Go into your local library:</p>
<pre><code class="lang-typescript"> cd packages/ui
 npm link
</code></pre>
<p> This registers the package globally.</p>
</li>
<li><p>Then, inside your app:</p>
<pre><code class="lang-typescript"> cd ../app
 npm link ui
</code></pre>
<p> This tells npm to use your local version of <code>ui</code> instead of the one from the npm registry.</p>
</li>
</ol>
<p>Result → Any changes you make inside <code>/packages/ui</code> reflect instantly in <code>/app</code> without reinstalling.</p>
<hr />
<h2 id="heading-why-pnpm-is-different">⚡ Why pnpm Is Different</h2>
<p><code>pnpm</code> was designed for <strong>speed</strong>, <strong>disk efficiency</strong>, and <strong>workspace management</strong>.<br />Instead of scattering node_modules everywhere, pnpm uses a content-addressable store and symlinks under the hood.</p>
<p>So naturally, <code>pnpm</code> gives us a few better ways to handle linking — depending on your setup.</p>
<hr />
<h2 id="heading-option-1-use-workspaces-recommended">🚀 Option 1 — Use Workspaces (Recommended)</h2>
<p>If you have a monorepo, pnpm workspaces make linking automatic.</p>
<h3 id="heading-example-structure">Example structure:</h3>
<pre><code class="lang-typescript">pnpm-workspace.yaml
packages/
  ui/
  app/
</code></pre>
<h3 id="heading-pnpm-workspaceyaml"><code>pnpm-workspace.yaml</code></h3>
<pre><code class="lang-typescript">packages:
  - <span class="hljs-string">"packages/*"</span>
</code></pre>
<p>Then, in your app’s <code>package.json</code>, declare:</p>
<pre><code class="lang-typescript">{
  <span class="hljs-string">"dependencies"</span>: {
    <span class="hljs-string">"ui"</span>: <span class="hljs-string">"workspace:*"</span>
  }
}
</code></pre>
<p>Run:</p>
<pre><code class="lang-typescript">pnpm install
</code></pre>
<p>✅ Done — pnpm automatically symlinks your local <code>ui</code> package into <code>app/node_modules</code>.</p>
<p>➡️ No need to manually <code>link</code> anything.<br />➡️ Every edit in <code>/packages/ui</code> is reflected instantly in <code>/app</code>.</p>
<p>This is <strong>the cleanest and most reliable</strong> way to work with local packages in pnpm.</p>
<hr />
<h2 id="heading-option-2-manual-linking-like-npm-link">🧩 Option 2 — Manual Linking (Like npm link)</h2>
<p>If you’re working outside a monorepo, you can still manually link.</p>
<h3 id="heading-step-1-create-a-global-link">Step 1: Create a global link</h3>
<pre><code class="lang-typescript">cd ~<span class="hljs-regexp">/projects/ui</span>
pnpm link --<span class="hljs-built_in">global</span>
</code></pre>
<h3 id="heading-step-2-link-in-your-app">Step 2: Link in your app</h3>
<pre><code class="lang-typescript">cd ~<span class="hljs-regexp">/projects/</span>app
pnpm link ui
</code></pre>
<p>This behaves just like <code>npm link</code>, but uses pnpm’s internal linking system.</p>
<hr />
<h2 id="heading-option-3-direct-local-linking">🔗 Option 3 — Direct Local Linking</h2>
<p>You can also directly link a local path without touching the global store:</p>
<pre><code class="lang-typescript">pnpm link ../ui
</code></pre>
<p>This instantly symlinks your local folder into <code>node_modules</code>.</p>
<p>Useful for quick experiments or smaller projects.</p>
<hr />
<h2 id="heading-quick-comparison">🧠 Quick Comparison</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Task</td><td>npm command</td><td>pnpm equivalent</td><td>Notes</td></tr>
</thead>
<tbody>
<tr>
<td>Create global link</td><td><code>npm link</code></td><td><code>pnpm link --global</code></td><td>Registers globally</td></tr>
<tr>
<td>Link to global package</td><td><code>npm link pkg-name</code></td><td><code>pnpm link pkg-name</code></td><td>Same behavior</td></tr>
<tr>
<td>Local direct link</td><td>—</td><td><code>pnpm link ../path/to/pkg</code></td><td>Fast and local</td></tr>
<tr>
<td>Monorepo linking (automatic)</td><td>manual setup required</td><td><code>workspace:*</code></td><td><strong>Best practice</strong></td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-handy-extras">🧰 Handy Extras</h2>
<p>List all global links:</p>
<pre><code class="lang-typescript">pnpm link --<span class="hljs-built_in">global</span> list
</code></pre>
<p>Remove a link:</p>
<pre><code class="lang-typescript">pnpm unlink ui
</code></pre>
<hr />
<h2 id="heading-final-thoughts">🧭 Final Thoughts</h2>
<p>While <code>npm link</code> served developers well for years, <strong>pnpm workspaces</strong> make local development between multiple packages smoother and more predictable.</p>
<p>If you’re maintaining multiple interdependent packages — say a design system and a frontend app — setting up a monorepo with pnpm workspaces will save you endless linking headaches.</p>
<p>Once you try it, you’ll never go back to manual linking again.</p>
]]></content:encoded></item><item><title><![CDATA[Friends as Mentors - Making Mistakes in adulthood]]></title><description><![CDATA[Irrespective of your age. You will make mistakes. As a serious person, who really regrets when something goes wrong. Like I would have nightmares of my mistakes. This has become an obstacle in my path of learning.Sometimes it is the embarrassment of ...]]></description><link>https://blog.coolhead.in/friends-as-mentors-making-mistakes-in-adulthood</link><guid isPermaLink="true">https://blog.coolhead.in/friends-as-mentors-making-mistakes-in-adulthood</guid><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Tue, 07 Oct 2025 16:43:24 GMT</pubDate><content:encoded><![CDATA[<p>Irrespective of your age. You will make mistakes. As a serious person, who really regrets when something goes wrong. Like I would have nightmares of my mistakes. This has become an obstacle in my path of learning.<br />Sometimes it is the embarrassment of making this mistakes. As an adult you always have eyes on you.<br />Making the same mistake again and again, is stupidity. But When You are doing something new, you are sure to make mistakes. The Smarter thing is always to have someone guide you.  </p>
<p>So, i guess i should tell you, What to do when you make a mistake ?</p>
<ul>
<li><p>Say sorry,</p>
</li>
<li><p>Own your mistakes,</p>
</li>
<li><p>Please tell someone about it, Don’t tell everyone</p>
</li>
<li><p>Be Humble</p>
</li>
<li><p>Don’t get angry</p>
</li>
<li><p>Find Healthy Environment</p>
</li>
<li><p>Accept your mistake</p>
</li>
<li><p>There is not guarantee that you will not make that mistake again ;)</p>
</li>
</ul>
<p>This are the things that tend to work for me. Owning your mistakes shows your character.  </p>
<p>Now, the fear part. With time people will forget, even you will forget that you made such a rookie mistake. Fear is only as good as salt in your food. Don’t let the fear overcome you and stop you from achieving your goals.  </p>
<p>Now, let’s face reality mistakes can change your life path. My friend broke his leg, stop playing cricket afterwards. He works/owns his father business now. Is he happy ? Yes. Is he rich? Yes. Can he walk? Yes.<br />Does he keeps talking about cricket all the time ? Yes.  </p>
<p>There would be other successful examples as well.</p>
<p>In my opinion, it would be great to spend your 20s with people of your own age group. They can become your support groups. This would become your networks for the next coming years.  </p>
<p>Specially, Friends can be great mentors. With Quality Friends you can learn a lot.</p>
]]></content:encoded></item><item><title><![CDATA[Creating Vector Search with TiDB Serverless and Drizzle]]></title><description><![CDATA[Vector Search has become highly popular with RAG Systems. In this blog we will learn how we can use the TiDB serverless library to connect with our Database, create schema in drizzle, and use the vector search ability of the build in vector search in...]]></description><link>https://blog.coolhead.in/creating-vector-search-with-tidb-serverless-and-drizzle</link><guid isPermaLink="true">https://blog.coolhead.in/creating-vector-search-with-tidb-serverless-and-drizzle</guid><category><![CDATA[TiDB Cloud]]></category><category><![CDATA[VectorSearch]]></category><category><![CDATA[DrizzleORM]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[agentic AI]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Mon, 29 Sep 2025 22:14:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759184043443/f8ccc3b1-af87-4ab9-9d2b-16b90f5dafbe.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Vector Search has become highly popular with RAG Systems. In this blog we will learn how we can use the TiDB serverless library to connect with our Database, create schema in drizzle, and use the vector search ability of the build in vector search in TiDB. But We should learn what is vector search and how it works?</p>
<h2 id="heading-vector-search">Vector Search</h2>
<p>Vector Search return similar items based on their semantic meaning, rather than exact matches. This is different from traditional keyword-based searches.</p>
<p><strong>Traditional Search works like:</strong></p>
<p>query: King results: King, Kingbird, Kingcup, Kingdom</p>
<p><strong>Vector Search Example:</strong></p>
<p>query: King</p>
<p>results: King, Queen, Kingdom, Monarch, Ruler, Prince</p>
<h3 id="heading-vector-search-in-tidb">Vector Search in TiDB</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759182873663/d1e82958-7961-4332-a8f7-6ed6d61e4976.png" alt="Here a diagram explaining vector search by TiDB.  https://docs.pingcap.com/tidbcloud/vector-search-overview/?plan=starter" class="image--center mx-auto" /></p>
<p>Here a diagram explaining vector search by TiDB. <a target="_blank" href="https://docs.pingcap.com/tidbcloud/vector-search-overview/?plan=starter">https://docs.pingcap.com/tidbcloud/vector-search-overview/?plan=starter</a></p>
<ul>
<li>Vector type in TiDB</li>
</ul>
<p>When creating a table, you can define a column as a <a target="_blank" href="https://docs.pingcap.com/tidbcloud/vector-search-overview/#vector-embedding">vector</a> column by specifying the <code>VECTOR</code> data type.</p>
<p>example</p>
<pre><code class="lang-sql"><span class="hljs-keyword">USE</span> <span class="hljs-keyword">test</span>;
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> embedded_documents (
    <span class="hljs-keyword">id</span>        <span class="hljs-built_in">INT</span>       PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-comment">-- Column to store the original content of the document.</span>
    <span class="hljs-keyword">document</span>  <span class="hljs-built_in">TEXT</span>,
    <span class="hljs-comment">-- Column to store the vector representation of the document.</span>
    embedding VECTOR(<span class="hljs-number">3</span>)
);
</code></pre>
<p>Inserting:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> embedded_documents
<span class="hljs-keyword">VALUES</span>
    (<span class="hljs-number">1</span>, <span class="hljs-string">'dog'</span>, <span class="hljs-string">'[1,2,1]'</span>),
    (<span class="hljs-number">2</span>, <span class="hljs-string">'fish'</span>, <span class="hljs-string">'[1,2,4]'</span>),
    (<span class="hljs-number">3</span>, <span class="hljs-string">'tree'</span>, <span class="hljs-string">'[1,0,0]'</span>);
</code></pre>
<p>Querying :</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> embedded_documents;
</code></pre>
<p>Output:</p>
<pre><code class="lang-sql">+<span class="hljs-comment">----+----------+-----------+</span>
| id | document | embedding |
+<span class="hljs-comment">----+----------+-----------+</span>
|  1 | dog      | [1,2,1]   |
|  2 | fish     | [1,2,4]   |
|  3 | tree     | [1,0,0]   |
+<span class="hljs-comment">----+----------+-----------+</span>
3 rows in <span class="hljs-keyword">set</span> (<span class="hljs-number">0.15</span> sec)
</code></pre>
<p>Vector Search</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">id</span>, <span class="hljs-keyword">document</span>, vec_cosine_distance(embedding, <span class="hljs-string">'[1,2,3]'</span>) <span class="hljs-keyword">AS</span> distance
<span class="hljs-keyword">FROM</span> embedded_documents
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> distance
<span class="hljs-keyword">LIMIT</span> <span class="hljs-number">3</span>;
</code></pre>
<p>Output from vector search</p>
<pre><code class="lang-sql">+<span class="hljs-comment">----+----------+---------------------+</span>
| id | document | distance            |
+<span class="hljs-comment">----+----------+---------------------+</span>
|  2 | fish     | 0.00853986601633272 |
|  1 | dog      | 0.12712843905603044 |
|  3 | tree     |  0.7327387580875756 |
+<span class="hljs-comment">----+----------+---------------------+</span>
3 rows in <span class="hljs-keyword">set</span> (<span class="hljs-number">0.15</span> sec)
</code></pre>
<p>Now, you would have a lot of question. Why did we only chose vector size of <code>3</code> ? How to convert text to vectors/embeddings? What is <code>vec_cosine_distance</code> for querying TiDB Database ? Does the Query vector has to be the same size as that of stored in database?</p>
<h2 id="heading-how-vector-search-is-calculated"><strong>How vector search is calculated ?</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759182925034/b69a4623-38b7-45bb-9bd8-d4bd40434987.png" alt class="image--center mx-auto" /></p>
<p>Let’s take a look at how vector search typically work:</p>
<p>1.<strong>Vector embeddings generation</strong>: Data items are first converted into vectors using a feature extraction or embedding technique. For example, images can be represented as vectors using convolutional neural networks (CNNs), and text documents can be represented as vectors using word embeddings or sentence embeddings.</p>
<p><strong>2. Indexing &amp; querying:</strong> The vectors are then indexed in the vector search database. Indexing is the process of organizing the vectors in a way that allows for efficient similarity search. Various indexing techniques and data structures, such as k-d trees, ball trees, and approximate nearest neighbor (ANN) algorithms, can be used to speed up the search process.</p>
<p>For text data, embeddings can be created using methods such as Word2Vec, GloVe or BERT. These methods create vector representations of words, phrases, or sentences based on the semantic and syntactic relationships between them. The embeddings are typically generated by training neural network models on large collections of text. Some popular methods for creating text embeddings include:</p>
<ul>
<li><p>Bag-of-words (BoW) model</p>
</li>
<li><p>Word embeddings (Word2Vec, GloVe)</p>
</li>
<li><p>Pre-trained language models (BERT, GPT)</p>
</li>
</ul>
<h3 id="heading-how-indexing-and-querying-works"><strong>How indexing and querying works</strong></h3>
<p>Vector search finds similar data using approximate nearing neighbor (ANN) algorithms. Compared to traditional keyword search, vector search yields more relevant results and executes faster.</p>
<p>Approximate Nearest Neighbors (ANN) is a class of algorithms used to find the nearest neighbors of a query point in a high-dimensional dataset. These algorithms are called "approximate" because they trade off a small amount of accuracy for a significant speedup compared to exact nearest neighbor search algorithms. ANN algorithms are commonly used in applications such as recommendation systems, image retrieval, natural language processing, and more.</p>
<h3 id="heading-cosine-similarity"><strong>Cosine Similarity</strong></h3>
<p>We use the term “cosine similarity” or “cosine distance” to denote the difference between the orientation of two vectors. For example, how far would you turn to face the front door?</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1400/0*vwdKVPZn_eBXGKUU.png" alt /></p>
<p>We begin by lining the vectors on top of each other again. Start by multiplying the numbers down and then adding all of the results up. Now save that number; call it “x”. Next, we must square each number and add the numbers in each vector. Imagine squaring each number horizontally and adding them together for both vectors.</p>
<h2 id="heading-how-does-vector-search-helps-in-rag-system">How does Vector Search helps in RAG System ?</h2>
<p>Vector Search becomes a key component of the knowledge base in a RAG System.</p>
<h3 id="heading-rag-with-vector-search">RAG with Vector Search</h3>
<ol>
<li><p><strong>Ingest documents</strong> → Break into chunks → Convert to embeddings → Store in a <strong>Vector Database</strong> (like TiDB Vector, etc.).</p>
</li>
<li><p><strong>User Query</strong> → Embed into vector.</p>
</li>
<li><p><strong>Vector Search</strong> → Retrieve top-k similar chunks.</p>
</li>
<li><p><strong>Pass retrieved chunks + query → LLM</strong> → Generate grounded, accurate response.</p>
</li>
</ol>
<h3 id="heading-using-vector-search-with-drizzle-and-tidb">Using Vector Search with drizzle and TiDB</h3>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Since, Vector data types are TiDB specific, and are not supported in MySQL. We need to create a custom vector type. <a target="_self" href="https://docs.pingcap.com/tidbcloud/vector-search-data-types/?plan=starter#vector-data-types">Read more about the vector type in TiDB</a>.</div>
</div>

<p>Create a Custom Vector Type</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { sql } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm"</span>;

<span class="hljs-keyword">import</span> { mysqlTable, varchar, text, float, timestamp, int, customType } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm/mysql-core"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> vector = customType&lt;{
    data: <span class="hljs-built_in">number</span>[];
    config: { length: <span class="hljs-built_in">number</span> };
    configRequired: <span class="hljs-literal">true</span>;
    driverData: <span class="hljs-built_in">string</span>;
}&gt;({
    dataType(config) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">`VECTOR(<span class="hljs-subst">${config.length}</span>)`</span>;
    },
    toDriver(value: <span class="hljs-built_in">number</span>[]) {
        <span class="hljs-comment">// TiDB expects `[x,y,z]`</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">`[<span class="hljs-subst">${value.join(<span class="hljs-string">","</span>)}</span>]`</span>;
    },
    fromDriver(value: <span class="hljs-built_in">string</span>) {
        <span class="hljs-comment">// TiDB returns "[0.1,0.2,...]"</span>
        <span class="hljs-keyword">try</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.parse(value) <span class="hljs-keyword">as</span> <span class="hljs-built_in">number</span>[];
        } <span class="hljs-keyword">catch</span> {
            <span class="hljs-keyword">return</span> value
                .replace(<span class="hljs-regexp">/^\\[|\\]$/g</span>, <span class="hljs-string">""</span>)
                .split(<span class="hljs-string">","</span>)
                .map(<span class="hljs-built_in">Number</span>);
        }
    },
});
</code></pre>
<p>Let’s Create a Media Chunks Table. As you can see we can only create vector of specific sizes. The usual process is to use a text Clunker/splitter that would create small vector chunks for the document uploaded.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> mediaChunks = mysqlTable(<span class="hljs-string">"media_chunks"</span>, {
    id: varchar(<span class="hljs-string">"id"</span>, { length: <span class="hljs-number">36</span> })
        .primaryKey()
        .default(sql<span class="hljs-string">`(UUID())`</span>), <span class="hljs-comment">// use MySQL's UUID()</span>

    mediaId: varchar(<span class="hljs-string">"media_id"</span>, { length: <span class="hljs-number">36</span> })
        .notNull()
        .references(<span class="hljs-function">() =&gt;</span> media.id, { onDelete: <span class="hljs-string">"cascade"</span> }),
    chunk: text(<span class="hljs-string">"chunk"</span>).notNull(),
    embedding: vector(<span class="hljs-string">"embedding"</span>, { length: <span class="hljs-number">768</span> }).notNull(),
    order: int(<span class="hljs-string">"order"</span>).notNull(),
})
</code></pre>
<p>We will create a media table.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> media = mysqlTable(<span class="hljs-string">"media"</span>, {
    id: varchar(<span class="hljs-string">"id"</span>, { length: <span class="hljs-number">36</span> })
        .primaryKey()
        .default(sql<span class="hljs-string">`(UUID())`</span>), <span class="hljs-comment">// use MySQL's UUID()</span>
    title: text(<span class="hljs-string">"title"</span>).notNull(),
    fileUrl: text(<span class="hljs-string">"file_url"</span>).notNull(),
    <span class="hljs-keyword">type</span>: varchar(<span class="hljs-string">"type"</span>, { length: <span class="hljs-number">50</span> }), <span class="hljs-comment">// pdf, image, doc</span>
    size: float(<span class="hljs-string">"size"</span>).notNull(), <span class="hljs-comment">// in MB</span>
    createdAt: timestamp(<span class="hljs-string">"created_at"</span>)
        .default(sql<span class="hljs-string">`CURRENT_TIMESTAMP`</span>)
        .notNull(),
});
</code></pre>
<p>Let’s Connect drizzle with TiDB</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { serverOnly } <span class="hljs-keyword">from</span> <span class="hljs-string">"@tanstack/react-start"</span>;
<span class="hljs-keyword">import</span> { drizzle } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm/tidb-serverless"</span>;

<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> schema <span class="hljs-keyword">from</span> <span class="hljs-string">"~/lib/db/schema"</span>;

<span class="hljs-keyword">const</span> getDatabase = serverOnly(<span class="hljs-function">() =&gt;</span>
  drizzle({
    connection: { url: process.env.DATABASE_URL },
    schema,
  }));

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> db = getDatabase();
</code></pre>
<p>Now, Let’s Create an upload api that would upload the component to CMS provider, use the text splitter to create chunks.</p>
<p>Example of api route</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// getting the text from the website, you can use pdf as well </span>
<span class="hljs-keyword">const</span> url = <span class="hljs-string">"&lt;https://coolhead.in&gt;"</span>;

<span class="hljs-comment">// we will use the reaper api by jina.ai to get the content from the website</span>
<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://r.jina.ai/<span class="hljs-subst">${url}</span>`</span>);

<span class="hljs-keyword">const</span> content = <span class="hljs-keyword">await</span> result.text();  <span class="hljs-comment">//&lt;--- Content</span>

<span class="hljs-comment">//Chunking</span>
<span class="hljs-keyword">const</span> segmentsResult = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://segment.jina.ai`</span>, {
  method: <span class="hljs-string">"POST"</span>,
  headers: {
    Authorization: <span class="hljs-string">`Bearer <span class="hljs-subst">${process.env.JINA_API_KEY}</span>`</span>,
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
  },
  body: <span class="hljs-built_in">JSON</span>.stringify({
    content,
    return_tokens: <span class="hljs-literal">true</span>,
    return_chunks: <span class="hljs-literal">true</span>,
    max_chunk_length: <span class="hljs-number">1000</span>,
  }),
});

<span class="hljs-comment">//Now we will create small chunks content for the </span>

 <span class="hljs-keyword">const</span> segmentsData =
    (<span class="hljs-keyword">await</span> segmentsResult.json()) <span class="hljs-keyword">as</span> JinaSegmenterResponse;

<span class="hljs-comment">// Creating Embeddings of size 768    </span>

<span class="hljs-keyword">const</span> embeddingsResult = <span class="hljs-keyword">await</span> fetch(
  <span class="hljs-string">"&lt;https://api.jina.ai/v1/embeddings&gt;"</span>,
  {
    method: <span class="hljs-string">"POST"</span>,
    headers: {
      Authorization: <span class="hljs-string">`Bearer <span class="hljs-subst">${process.env.JINA_API_KEY}</span>`</span>,
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    },
    body: <span class="hljs-built_in">JSON</span>.stringify({
      model: <span class="hljs-string">"jina-embeddings-v3"</span>,
      task: <span class="hljs-string">"retrieval.passage"</span>,
      late_chunking: <span class="hljs-literal">true</span>,
      dimensions: <span class="hljs-number">768</span>,
      embedding_type: <span class="hljs-string">"float"</span>,
      input: segmentsData.chunks,
    }),
  },
);

<span class="hljs-comment">// Save the Embedding the data to out TiDB database. </span>
<span class="hljs-keyword">const</span> embeddingsData =
  (<span class="hljs-keyword">await</span> embeddingsResult.json()) <span class="hljs-keyword">as</span> JinaEmbeddingsResponse;

<span class="hljs-keyword">const</span> mediaId = <span class="hljs-string">"9203fd63-869b-11f0-bb4b-9ee057d67487"</span> <span class="hljs-comment">// already present in the media table</span>

<span class="hljs-keyword">const</span> values = embeddingsData.data.map(<span class="hljs-function">(<span class="hljs-params">embedding, index</span>) =&gt;</span> ({
  mediaId,
  chunk: segmentsData.chunks[embedding.index],
  embedding: embedding.embedding,
  order: index,
}));

<span class="hljs-keyword">await</span> db.insert(mediaChunks).values(values);  <span class="hljs-comment">//&lt;---- return this from api</span>
</code></pre>
<p>Querying: Create an vector embeddings for the <code>query</code> . Then use vector cosine search to get the required Chunks of the document.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">//get the query from the request</span>
<span class="hljs-keyword">const</span> body = <span class="hljs-keyword">await</span> request.json();
<span class="hljs-keyword">const</span> { query } = body <span class="hljs-keyword">as</span> { query: <span class="hljs-built_in">string</span> };

<span class="hljs-comment">//Create embeddings for the query</span>

<span class="hljs-keyword">const</span> embeddingsResult = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"&lt;https://api.jina.ai/v1/embeddings&gt;"</span>, {
  method: <span class="hljs-string">"POST"</span>,
  headers: {
    Authorization: <span class="hljs-string">`Bearer <span class="hljs-subst">${process.env.JINA_API_KEY}</span>`</span>,
    <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
  },
  body: <span class="hljs-built_in">JSON</span>.stringify({
    model: <span class="hljs-string">"jina-embeddings-v3"</span>,
    task: <span class="hljs-string">"retrieval.query"</span>,
    dimensions: <span class="hljs-number">768</span>,
    embedding_type: <span class="hljs-string">"float"</span>,
    input: [query],
  }),
});

<span class="hljs-keyword">const</span> embeddingsData = <span class="hljs-keyword">await</span> embeddingsResult.json();
<span class="hljs-keyword">const</span> queryEmbedding = embeddingsData.data[<span class="hljs-number">0</span>].embedding <span class="hljs-keyword">as</span> <span class="hljs-built_in">number</span>[];

<span class="hljs-keyword">const</span> embeddingLiteral = [<span class="hljs-built_in">JSON</span>.stringify(queryEmbedding)]

<span class="hljs-keyword">const</span> embeddingLiteral = [<span class="hljs-built_in">JSON</span>.stringify(queryEmbedding)]

  <span class="hljs-keyword">const</span> { rows } = <span class="hljs-keyword">await</span> db.execute(
    sql<span class="hljs-comment">/*sql*/</span><span class="hljs-string">`
  SELECT 
    id,
    media_id,
    chunk,
    \\`</span>order\\<span class="hljs-string">`,
    vec_cosine_distance(
      embedding,
      <span class="hljs-subst">${embeddingLiteral}</span>
    ) AS distance
  FROM <span class="hljs-subst">${mediaChunks}</span>
  ORDER BY distance
  LIMIT 5
`</span>
  );

<span class="hljs-keyword">const</span> chunks = rows?.map(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span> r.chunk).join(<span class="hljs-string">"\\n\\n"</span>);

<span class="hljs-comment">// use the chunks and give to LLM to generate an response to the query. </span>
<span class="hljs-keyword">const</span> { text } = <span class="hljs-keyword">await</span> generateText({
  model,

  prompt: query,
  system: <span class="hljs-string">`You are an question answer assistant. 
Context:\\n<span class="hljs-subst">${chunks}</span>\\n\\n
`</span>,
});
</code></pre>
<p>There are other Vector distance functions as well in TiDB. I would suggest you to try other as well. <a target="_blank" href="https://docs.pingcap.com/tidbcloud/vector-search-functions-and-operators/?plan=starter">Learn More about TiDB Vector Functions</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759183277245/b9abca3a-5875-49b2-a65b-2895ecb3ce4d.png" alt class="image--center mx-auto" /></p>
<p>This code was taken from my RAG <a target="_blank" href="https://github.com/biomathcode/FamCare">FamCare</a>. FamCare shows how RAG + vector search can turn raw medical data into actionable, context-aware insights and create medicine Scheduling all powered by AI. If you’d like to explore the code, experiment, or even extend it with your own ideas, head over to the <a target="_blank" href="https://github.com/biomathcode/FamCare">GitHub repo and give i</a>t a ⭐️.</p>
]]></content:encoded></item><item><title><![CDATA[Best PDF Parsers for RAG Applications]]></title><description><![CDATA[Overcoming PDF Hell
In Retrieval-Augmented Generation (RAG) and other LLM-based applications, PDF parsing is one of the trickiest challenges. PDF files are everywhere—invoices, academic papers, scans, reports—and getting reliable, semantically meanin...]]></description><link>https://blog.coolhead.in/best-pdf-parsers-for-rag-applications</link><guid isPermaLink="true">https://blog.coolhead.in/best-pdf-parsers-for-rag-applications</guid><category><![CDATA[datalab.to]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[AI]]></category><category><![CDATA[LlamaIndex]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Mon, 22 Sep 2025 16:58:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758560244003/0fc16667-7859-40d3-a2f8-040bb996572a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-overcoming-pdf-hell">Overcoming PDF Hell</h1>
<p>In Retrieval-Augmented Generation (RAG) and other LLM-based applications, PDF parsing is one of the trickiest challenges. PDF files are everywhere—invoices, academic papers, scans, reports—and getting reliable, semantically meaningful text out of them is harder than you’d think. Below, we explore what makes PDF parsing hard (“PDF Hell”), the major challenges, what features you need in a good parser, and compare some of the best tools &amp; libraries (open-source and commercial) you can use.</p>
<h2 id="heading-key-challenges-when-parsing-pdfs-for-rag-llm-use">Key Challenges When Parsing PDFs for RAG / LLM Use</h2>
<p>Here are the major obstacles you’ll face, drawn from the article and from general experience:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Challenge</td><td>Description / Effects</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Fixed layout &amp; lack of semantic markup</strong></td><td>PDFs are spatial: text is positioned by coordinates. Headings, paragraphs, sidebars, columns etc often are not tagged semantically. This makes simple extraction yield scrambled text order.</td></tr>
<tr>
<td><strong>Multi-column, irregular layouts</strong></td><td>Scientific papers, invoices, newsletters often have multiple columns or unpredictable layout. Tools that read line-by-line left to right may jumble the order.</td></tr>
<tr>
<td><strong>Scanned PDFs / image PDFs</strong></td><td>Some PDFs are just images (scans or photos). You need OCR + preprocessing (de-skew, noise removal, etc). Otherwise text extraction fails or is very low quality.</td></tr>
<tr>
<td><strong>Mixed content</strong></td><td>PDFs containing both native text and text embedded in images, watermarks, background images, form elements, handwritten text etc. These complicate detection and extraction workflows.</td></tr>
<tr>
<td><strong>Tables</strong></td><td>Extracting tabular data is especially hard: how to detect the table, its rows/columns, spanning over pages, borders vs visual layout etc. Pure text extractors often fail; computer-vision or hybrid approaches may help.</td></tr>
<tr>
<td><strong>Orientation / rotation / skew</strong></td><td>Pages may be rotated or scanned at odd angles. Some pages might switch between portrait/landscape. Need auto-detection &amp; correction.</td></tr>
<tr>
<td><strong>Bad generators / curves instead of text</strong></td><td>Some PDFs store what appears to be text as vector graphics (“curves”) instead of real text glyphs. Then text extraction doesn’t work; you must fall back to OCR or image conversion.</td></tr>
<tr>
<td><strong>Header/footer noise</strong></td><td>Repeated headers, footers, page numbers, watermarks — all add noise and token waste when feeding into LLMs. Removing or ignoring them is helpful.</td></tr>
<tr>
<td><strong>Searchable PDFs with poor underlying OCR</strong></td><td>A PDF may already have a text layer, but that layer might be low quality, split text spans weirdly, double-spaced, mis-positioned, etc. Assumptions that “searchable = good” often fail.</td></tr>
<tr>
<td><strong>Performance, cost, and privacy</strong></td><td>OCR is expensive compute-wise; cloud services may raise privacy concerns; large documents slow to process. If handling many PDFs, these factors matter.</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-what-features-a-good-pdf-parser-extraction-pipeline-should-have">What Features a Good PDF Parser / Extraction Pipeline Should Have</h2>
<p>To deal well with PDF Hell, a parser or extraction system should satisfy many of the following:</p>
<ul>
<li><p><strong>Layout preservation</strong> or at least metadata about positions, so that paragraphs, tables, columns etc can be reconstructed.</p>
</li>
<li><p><strong>Mode detection / switching</strong>, e.g. detect if a page is native text, or image / scanned, or mixture, and choose different extraction strategy (text extraction vs OCR vs hybrid).</p>
</li>
<li><p><strong>Preprocessing of images</strong>: de-skewing, noise reduction, rotation correction, contrast adjustments.</p>
</li>
<li><p><strong>Table extraction support</strong>: detecting tables visually or via layout, reconstructing rows and columns in a useful format.</p>
</li>
<li><p><strong>Form / interactive element support</strong>: being able to extract data from checkboxes, radio buttons, filled fields.</p>
</li>
<li><p><strong>Header/footer detection and removal</strong> (or at least tagging) to avoid token bloat.</p>
</li>
<li><p><strong>Scalability &amp; performance</strong>: ability to process large numbers of pages, large documents, efficiently.</p>
</li>
<li><p><strong>Privacy / deployment options</strong>: e.g. on-premise vs SaaS, encryption etc.</p>
</li>
<li><p><strong>Robust error handling &amp; fallback strategies</strong>: what to do when the PDF is weird (curves, mixed types, bad layouts etc).</p>
</li>
</ul>
<hr />
<h2 id="heading-survey-popular-tools-amp-libraries">Survey: Popular Tools &amp; Libraries</h2>
<p>Given those challenges &amp; requirements, here are some of the leading tools / frameworks you might consider. I’ll compare them on strengths, weaknesses, suitability for RAG use.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tool / Library</td><td>Strengths / Best For</td><td>Weaknesses / Limitations</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Datalet (Marker)</strong></td><td>Likely good for structured extraction, maybe layout awareness. <em>Note: specific details depend on documentation.</em></td><td>May have limited community / maturity; possibly less flexible for unusual layouts.</td></tr>
<tr>
<td><strong>llamaindex</strong></td><td>Popular in the RAG / LLM community; good for embedding + indexing + pipelines. You can plug in different document loaders / parsers.</td><td>Parsing support depends on external libraries; handling really bad PDFs / scans may require additional modules / custom logic.</td></tr>
<tr>
<td><strong>jina ai</strong></td><td>Strong in search, embeddings, building vector indexes; likely has tools or connectors for document ingestion.</td><td>Might require configuration / customization for advanced table extraction or for scans / OCR.</td></tr>
<tr>
<td><strong>Unstructured.io</strong></td><td>Very strong in extracting structured info from complex documents; good tools for handling layout, splitting etc.</td><td>Might be more resource intensive; licensing / cost if using commercial or enterprise versions.</td></tr>
<tr>
<td><strong>Vectorize.io</strong></td><td>Good commercial options; probably optimized for speed / production usage.</td><td>May cost; may limit customization; handling odd edge cases might require fallback logic.</td></tr>
<tr>
<td><strong>GroundX by eyelevel.ai</strong></td><td>Likely focused, perhaps with custom models; possibly good quality for particular domains.</td><td>Might have less documentation / community; possibly domain-specific bias.</td></tr>
<tr>
<td><strong>LangChain</strong></td><td>Excellent orchestration framework; many existing document loaders that use PDF libraries + OCR; great for building full RAG pipelines.</td><td>LangChain itself is not a PDF extractor — quality depends on underlying extraction tool; for many edge cases you’ll need to extend/customize.</td></tr>
<tr>
<td><strong>PyMuPDF (fitz)</strong></td><td>Strong low-level library; very good for getting text, images, extracting metadata, positions. Fair speed.</td><td>Doesn’t do OCR out of the box; tables detection is minimal; complex layout rebuilding / semantic understanding has to be built on top.</td></tr>
<tr>
<td><strong>pdf-js</strong></td><td>Good for browser / NodeJS usage; rendering, interacting with PDFs in client side or server side. Can extract text.</td><td>Limited in table detection, forms, OCR; not ideal if you need heavy layout or image-based extraction.</td></tr>
</tbody>
</table>
</div>]]></content:encoded></item><item><title><![CDATA[How to add NProgess/Youtube loading bar in tanstack start]]></title><description><![CDATA[Install the library from npm:
npm install nprogress

in the ___root.tsx file
import {
  createRootRouteWithContext,
  useRouterState,
} from "@tanstack/react-router";

import Nprogress from "nprogress";

function RootComponent() {
  const routerState...]]></description><link>https://blog.coolhead.in/how-to-add-nprogessyoutube-loading-bar-in-tanstack-start</link><guid isPermaLink="true">https://blog.coolhead.in/how-to-add-nprogessyoutube-loading-bar-in-tanstack-start</guid><category><![CDATA[React]]></category><category><![CDATA[tanstack-query]]></category><category><![CDATA[tanstack router]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Mon, 08 Sep 2025 10:26:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757327176398/015f6efc-6b76-478a-9325-590046a41d3e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-install-the-library-from-npm">Install the library from npm:</h3>
<pre><code class="lang-tsx">npm install nprogress
</code></pre>
<p>in the <code>___root.tsx</code> file</p>
<pre><code class="lang-tsx">import {
  createRootRouteWithContext,
  useRouterState,
} from "@tanstack/react-router";

import Nprogress from "nprogress";

function RootComponent() {
  const routerState = useRouterState();

  useEffect(() =&gt; {
    if (routerState.isLoading) {
      Nprogress.start();
    } else {
      Nprogress.done();
    }
  }, [routerState.isLoading]);
  return (
    &lt;RootDocument&gt;
      &lt;Outlet /&gt;
    &lt;/RootDocument&gt;
  );
}

export const Route = createRootRouteWithContext()({
  component: RootComponent,
});
</code></pre>
]]></content:encoded></item><item><title><![CDATA[The CAP Theorem for Marketing]]></title><description><![CDATA[Cap Theorem

CAP Theorem For Marketing]]></description><link>https://blog.coolhead.in/the-cap-theorem-for-marketing</link><guid isPermaLink="true">https://blog.coolhead.in/the-cap-theorem-for-marketing</guid><category><![CDATA[marketing]]></category><category><![CDATA[CAP-Theorem]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Tue, 22 Jul 2025 13:45:08 GMT</pubDate><content:encoded><![CDATA[<p>Cap Theorem</p>
<p><img src="https://img.notionusercontent.com/s3/prod-files-secure%2F79ac2202-deb0-4ff8-8451-0b0847417e92%2F10ec6767-d280-487e-b6d0-b8a43927f92a%2Fimage.png/size/w=1320?exp=1753192673&amp;sig=_pExopwVulKCd86Kj5BxwP8iB3kUltBGtS6eNHOAqKI&amp;id=232f2cef-3802-803d-995e-d962c739f666&amp;table=block&amp;userId=224a1e6b-d7eb-4f67-93ba-2af4d42daae2" alt /></p>
<p>CAP Theorem For Marketing</p>
<p><img src="https://img.notionusercontent.com/s3/prod-files-secure%2F79ac2202-deb0-4ff8-8451-0b0847417e92%2F278c6ccf-3f7b-4c7a-a570-f057aae282ba%2Fimage.png/size/w=960?exp=1753192756&amp;sig=zh0uDQrnW6BvkwxhB4_oKd4MfiRY5MYhcUOdfl7D1Jc&amp;id=232f2cef-3802-8076-8a02-fa3a419e8025&amp;table=block&amp;userId=224a1e6b-d7eb-4f67-93ba-2af4d42daae2" alt /></p>
]]></content:encoded></item><item><title><![CDATA[Learning Through Pain Points]]></title><description><![CDATA[I remember when i first got into web dev. I realised that i can search my queries and get the answers. But once you are into the rabbit hole of debugging, you do learn a lot and still not get the issue fixed. That is quite common for all devs. Once i...]]></description><link>https://blog.coolhead.in/learning-through-pain-points</link><guid isPermaLink="true">https://blog.coolhead.in/learning-through-pain-points</guid><category><![CDATA[General Programming]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Thu, 05 Jun 2025 01:08:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/MltM5Bu-mYg/upload/0bc17d26f69d7e26547850ce3f106545.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I remember when i first got into web dev. I realised that i can search my queries and get the answers. But once you are into the rabbit hole of debugging, you do learn a lot and still not get the issue fixed. That is quite common for all devs. Once is a while you get solutions that will solve your problems that you haven’t even face.</p>
<p>Let me give you an example. In the beginning the toughest task for me was how to setup a MongoDb database. I thought it would be super easy. It was not. I had to create an account, setup billing, create cluster, and what not on a pretty slow website. This would lead to procrastination. Now, finally after a day or two i did it. i would get random error connecting to MongoDb. I would search through the errors, try to solve it. Obviously i was making mistake in the syntax of the connection string.</p>
<p>The thing was i would face the same problem, again and again. This would become a great pain point in my learning process.</p>
<p>Now, think of doing the same with other databases Postgres, MySQL, Neo4j, TigerDB, and Redis.</p>
<p>Then in the Stackoverflow Forums i would see this word again and again. DOCKER, followed by a ORCHESTRATION, CONTAINER.</p>
<p>I would stop myself from learning new tech(Docker in my case), because</p>
<ul>
<li><p>Didn’t had the time</p>
</li>
<li><p>More focused on learning concept, or in my case mongodb</p>
</li>
<li><p>would that work with my hardware(windows)</p>
</li>
</ul>
<p>After few years, I <s>learnt</s> used docker. I had to deploy something for my company and i had to just go through the process.</p>
<p>Docker reduced my procrastinating time.</p>
<p>I am always asked this one question again and again in tech. Why do we have to learn so many things?</p>
<p>In tech, we try to solve for scale, performance and availability. We have to learn the tech, and with time you get to know the tools as well.</p>
<p>Problem starts when we start learning the tools. Tool learning highly dependent on the problems that you have faced.</p>
<p>When you are asked ( in interviews) about virtualisation for performance in react, people wanna know if you have faced that pain points or not. And this Pain Points come when you have worked with something that scale. <em>( this is what i think, interviews are crazy )</em></p>
<p>Learning tools without having those pain points, would lead to shallow understanding. Wouldn’t compound as well. Docker might compound your productivity. You wouldn’t become a successful engineer, just by learning docker, you have to used it. Use it to solved your Pain Points.</p>
]]></content:encoded></item><item><title><![CDATA[🏷 How to Build a Custom Badge Web Component with Theme, Size, RTL Support, and Icons]]></title><description><![CDATA[Badges are small UI elements that provide contextual hints, often used to represent statuses, counts, or metadata. In this article, we’ll walk through how to create a modern, customizable <x-badge> Web Component.

✨ Web Components provide encapsulate...]]></description><link>https://blog.coolhead.in/how-to-build-a-custom-badge-web-component-with-theme-size-rtl-support-and-icons</link><guid isPermaLink="true">https://blog.coolhead.in/how-to-build-a-custom-badge-web-component-with-theme-size-rtl-support-and-icons</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Mon, 26 May 2025 07:36:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748244552697/7ee088cb-8167-4bb9-a318-673553496d55.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Badges are small UI elements that provide contextual hints, often used to represent statuses, counts, or metadata. In this article, we’ll walk through how to create a modern, customizable <code>&lt;x-badge&gt;</code> Web Component.</p>
<blockquote>
<p>✨ Web Components provide encapsulated, reusable UI with native browser support. Let’s use that power to create a badge that adapts to any theme or language direction!</p>
</blockquote>
<h2 id="heading-1-create-a-simple-badge-web-component">1. Create a Simple Badge Web Component</h2>
<p>We start by defining a basic custom element using the <code>HTMLElement</code> class.</p>
<h3 id="heading-mainjs"><code>main.js</code></h3>
<pre><code class="lang-jsx"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BadgeComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HTMLElement</span> </span>{
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">get</span> <span class="hljs-title">observedAttributes</span>() {
    <span class="hljs-keyword">return</span> [<span class="hljs-string">'dir'</span>, <span class="hljs-string">'size'</span>, <span class="hljs-string">'theme'</span>, <span class="hljs-string">'variant'</span>];
  }

  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-keyword">const</span> template = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'template'</span>);
    template.innerHTML = <span class="hljs-string">`
      &lt;link rel="stylesheet" href="./styles.css" /&gt;
      &lt;slot name="icon"&gt;&lt;/slot&gt;&lt;slot&gt;&lt;/slot&gt;
    `</span>;
    <span class="hljs-built_in">this</span>.attachShadow({ <span class="hljs-attr">mode</span>: <span class="hljs-string">'open'</span> }).appendChild(template.content.cloneNode(<span class="hljs-literal">true</span>));
  }

  attributeChangedCallback(name, _oldVal, newVal) {
    <span class="hljs-keyword">if</span> (name === <span class="hljs-string">'dir'</span>) {
      <span class="hljs-built_in">this</span>.style.setProperty(<span class="hljs-string">'--dir'</span>, newVal);
    }
  }
}

customElements.define(<span class="hljs-string">'x-badge'</span>, BadgeComponent);
</code></pre>
<h2 id="heading-attributechangedcallback"><code>attributeChangedCallback</code></h2>
<p>This lifecycle method lets us respond to attribute changes:</p>
<pre><code class="lang-typescript">attributeChangedCallback(name, _oldVal, newVal) {
  <span class="hljs-keyword">if</span> (name === <span class="hljs-string">'dir'</span>) {
    <span class="hljs-built_in">this</span>.style.setProperty(<span class="hljs-string">'--dir'</span>, newVal);
  }
}
</code></pre>
<blockquote>
<p>“This is where your component becomes reactive to external changes, just like frameworks do under the hood.”</p>
</blockquote>
<hr />
<h2 id="heading-2-styling-the-badge-with-variants-and-themes">🧑‍🎨 2. Styling the Badge with Variants and Themes</h2>
<h3 id="heading-why-use-host-and-slotted">Why use <code>:host</code> and <code>::slotted</code>?</h3>
<ul>
<li><p><code>:host</code> lets us style the outermost custom element (<code>&lt;x-badge&gt;</code>) based on its attributes.</p>
</li>
<li><p><code>::slotted()</code> targets user-provided content like <code>&lt;span slot="icon"&gt;</code>.</p>
</li>
</ul>
<h3 id="heading-stylescss"><code>styles.css</code></h3>
<pre><code class="lang-css"><span class="hljs-selector-pseudo">:host</span> {
  <span class="hljs-attribute">display</span>: inline-flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">font-family</span>: sans-serif;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">500</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">1em</span>;
  <span class="hljs-attribute">white-space</span>: nowrap;
  <span class="hljs-attribute">direction</span>: <span class="hljs-built_in">var</span>(--dir, ltr);
  <span class="hljs-attribute">font-size</span>: <span class="hljs-built_in">var</span>(--badge-font-size, <span class="hljs-number">0.75rem</span>);
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">0.4em</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.2em</span> <span class="hljs-number">0.6em</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">var</span>(--badge-bg, #e0e0e0);
  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--badge-color, #<span class="hljs-number">000</span>);
}

<span class="hljs-comment">/* Themes */</span>
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[theme=<span class="hljs-string">"light"</span>]</span>) {
  <span class="hljs-attribute">--badge-bg</span>: <span class="hljs-number">#f0f0f0</span>;
  <span class="hljs-attribute">--badge-color</span>: <span class="hljs-number">#000</span>;
}

<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[theme=<span class="hljs-string">"dark"</span>]</span>) {
  <span class="hljs-attribute">--badge-bg</span>: <span class="hljs-number">#333</span>;
  <span class="hljs-attribute">--badge-color</span>: <span class="hljs-number">#fff</span>;
}

<span class="hljs-comment">/* Variants */</span>
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[variant=<span class="hljs-string">"info"</span>]</span>)     { <span class="hljs-attribute">--badge-bg</span>: <span class="hljs-number">#2680eb</span>; <span class="hljs-attribute">--badge-color</span>: <span class="hljs-number">#fff</span>; }
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[variant=<span class="hljs-string">"positive"</span>]</span>) { <span class="hljs-attribute">--badge-bg</span>: <span class="hljs-number">#2d9d78</span>; <span class="hljs-attribute">--badge-color</span>: <span class="hljs-number">#fff</span>; }
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[variant=<span class="hljs-string">"negative"</span>]</span>) { <span class="hljs-attribute">--badge-bg</span>: <span class="hljs-number">#e34850</span>; <span class="hljs-attribute">--badge-color</span>: <span class="hljs-number">#fff</span>; }
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[variant=<span class="hljs-string">"warning"</span>]</span>)  { <span class="hljs-attribute">--badge-bg</span>: <span class="hljs-number">#fca73c</span>; <span class="hljs-attribute">--badge-color</span>: <span class="hljs-number">#000</span>; }

<span class="hljs-comment">/* Sizes */</span>
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[size=<span class="hljs-string">"s"</span>]</span>)  { <span class="hljs-attribute">--badge-font-size</span>: <span class="hljs-number">0.625rem</span>; <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.1em</span> <span class="hljs-number">0.4em</span>; }
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[size=<span class="hljs-string">"m"</span>]</span>)  { <span class="hljs-attribute">--badge-font-size</span>: <span class="hljs-number">0.75rem</span>;  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.2em</span> <span class="hljs-number">0.5em</span>; }
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[size=<span class="hljs-string">"l"</span>]</span>)  { <span class="hljs-attribute">--badge-font-size</span>: <span class="hljs-number">0.875rem</span>; <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.3em</span> <span class="hljs-number">0.6em</span>; }
<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[size=<span class="hljs-string">"xl"</span>]</span>) { <span class="hljs-attribute">--badge-font-size</span>: <span class="hljs-number">1rem</span>;     <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.4em</span> <span class="hljs-number">0.7em</span>; }

<span class="hljs-comment">/* Icon */</span>
<span class="hljs-selector-pseudo">::slotted(</span><span class="hljs-selector-attr">[slot=<span class="hljs-string">'icon'</span>]</span>) {
  <span class="hljs-attribute">display</span>: inline-flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">block-size</span>: <span class="hljs-number">1em</span>;
  <span class="hljs-attribute">inline-size</span>: <span class="hljs-number">1em</span>;
  <span class="hljs-attribute">color</span>: currentColor;
  <span class="hljs-attribute">margin-inline-end</span>: <span class="hljs-number">0.3em</span>;
}

<span class="hljs-selector-pseudo">:host(</span><span class="hljs-selector-attr">[dir=<span class="hljs-string">"rtl"</span>]</span>) <span class="hljs-selector-pseudo">::slotted(</span><span class="hljs-selector-attr">[slot=<span class="hljs-string">'icon'</span>]</span>) {
  <span class="hljs-attribute">margin-inline-start</span>: <span class="hljs-number">0.3em</span>;
  <span class="hljs-attribute">margin-inline-end</span>: <span class="hljs-number">0</span>;
}
</code></pre>
<hr />
<h2 id="heading-3-add-size-property">📏 3. Add Size Property</h2>
<p>The badge supports <code>size="s"</code>, <code>"m"</code>, <code>"l"</code>, and <code>"xl"</code>.</p>
<p>This is handled by setting <code>--badge-font-size</code> and adjusting the <code>padding</code> accordingly using the <code>:host([size="..."])</code> CSS selectors.</p>
<blockquote>
<p>“Using CSS custom properties for sizing allows easy overrides and scaling.”</p>
</blockquote>
<hr />
<h2 id="heading-4-add-support-for-rtl-and-ltr">🌐 4. Add Support for RTL and LTR</h2>
<p>We can use the <code>dir</code> attribute to support right-to-left languages like Arabic or Hebrew.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">x-badge</span> <span class="hljs-attr">dir</span>=<span class="hljs-string">"rtl"</span> <span class="hljs-attr">variant</span>=<span class="hljs-string">"info"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"m"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"icon"</span>&gt;</span>🔔<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> إشعار
<span class="hljs-tag">&lt;/<span class="hljs-name">x-badge</span>&gt;</span>
</code></pre>
<p>When <code>dir="rtl"</code> is present, we switch icon spacing using <code>:host([dir="rtl"])</code>.</p>
<p>The <code>attributeChangedCallback</code> in JavaScript dynamically updates a <code>--dir</code> property so it can be used in <code>direction</code>.</p>
<hr />
<h2 id="heading-5-icons-inside-badges">✨ 5. Icons Inside Badges</h2>
<p>Use <code>&lt;slot name="icon"&gt;</code> for inline icons:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">x-badge</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"m"</span> <span class="hljs-attr">variant</span>=<span class="hljs-string">"positive"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"icon"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">svg</span> <span class="hljs-attr">...</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  Success
<span class="hljs-tag">&lt;/<span class="hljs-name">x-badge</span>&gt;</span>
</code></pre>
<p>The icon remains scalable and vertically centered, with automatic margin on the correct side depending on direction.</p>
<hr />
<h2 id="heading-6-putting-it-all-together">📄 6. Putting It All Together</h2>
<h3 id="heading-indexhtml"><code>index.html</code></h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">x-badge</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"m"</span> <span class="hljs-attr">variant</span>=<span class="hljs-string">"info"</span> <span class="hljs-attr">theme</span>=<span class="hljs-string">"light"</span>&gt;</span>Info<span class="hljs-tag">&lt;/<span class="hljs-name">x-badge</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">x-badge</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"l"</span> <span class="hljs-attr">variant</span>=<span class="hljs-string">"positive"</span> <span class="hljs-attr">theme</span>=<span class="hljs-string">"dark"</span> <span class="hljs-attr">dir</span>=<span class="hljs-string">"rtl"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"icon"</span>&gt;</span>✅<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  ناجح
<span class="hljs-tag">&lt;/<span class="hljs-name">x-badge</span>&gt;</span>
</code></pre>
<p>You can dynamically create or update badges via JavaScript:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> badge = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'x-badge'</span>);
badge.setAttribute(<span class="hljs-string">'variant'</span>, <span class="hljs-string">'warning'</span>);
badge.setAttribute(<span class="hljs-string">'theme'</span>, <span class="hljs-string">'light'</span>);
badge.setAttribute(<span class="hljs-string">'size'</span>, <span class="hljs-string">'xl'</span>);
badge.textContent = <span class="hljs-string">'Alert!'</span>;
<span class="hljs-built_in">document</span>.body.appendChild(badge);
</code></pre>
<hr />
<h2 id="heading-final-tips">🧠 Final Tips</h2>
<ul>
<li><p>Use CSS variables for all spacing, colors, and typography.</p>
</li>
<li><p>Add <code>aria-label</code> or use <code>&lt;slot&gt;</code> meaningfully for accessibility.</p>
</li>
<li><p>Consider adding <code>icon-only</code> mode or badges with dismiss buttons.</p>
</li>
</ul>
<hr />
<h3 id="heading-final-codepen-with-full-code">Final Codepen - with Full Code</h3>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/pratiksharma15/pen/ZYGEPwg">https://codepen.io/pratiksharma15/pen/ZYGEPwg</a></div>
<p> </p>
<h2 id="heading-stay-connected-amp-explore-more">🔗 Stay Connected &amp; Explore More</h2>
<p>If you found this article helpful or want to see more UI experiments, open-source components, and thoughts on building better interfaces:</p>
<h3 id="heading-check-out-my-work">👉 Check out my work:</h3>
<ul>
<li><p>🌐 <a target="_blank" href="https://coolhead.in"><strong>Website</strong> – coolhead.in</a></p>
</li>
<li><p>📝 <a target="_blank" href="https://blog.coolhead.in"><strong>Blog</strong> – blog.coolhead.in</a></p>
</li>
<li><p>💼 <a target="_blank" href="https://linkedin.com/in/biomathcode"><strong>LinkedIn</strong> – @biomathcode</a></p>
</li>
<li><p>💻 <a target="_blank" href="https://github.com/biomathcode"><strong>GitHub</strong> – @biomathcode</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[System Design: Build your own Calendar]]></title><description><![CDATA[This is about me learning/preparing for System Design while creating an Calendar app. Blog is not written as a tutorial but more like an personal guide.

I tried to build a google Calendar keeping in mind the what, how and why. This Readme would give...]]></description><link>https://blog.coolhead.in/system-design-build-your-own-calendar</link><guid isPermaLink="true">https://blog.coolhead.in/system-design-build-your-own-calendar</guid><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sat, 17 May 2025 21:30:27 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>This is about me learning/preparing for System Design while creating an Calendar app. Blog is not written as a tutorial but more like an personal guide.</p>
</blockquote>
<p>I tried to build a google Calendar keeping in mind the what, how and why. This Readme would give you a refresher on how apps like amie, rise, cron(notion calendar now), or google calendar works. I have tried to show the RADIO(requirement, high level Architecture, Data Model, API Design(model), Optimization/performace) process of any design system interview. Feedback or issue are welcome, if you find any mistakes in the technical context of writing or grammatical mistakes that i would have made on my side.</p>
<p>I also tried to write the code for the requirements and build a pretty good clone. In the beginning i was just prototyping in javascript thinking if i will be able to build something complex or with the time limitation. Turn out i did. I rewrote the whole codebase in Typescript. Because why not. Rewriting or refactoring is the best way to learn something and also helps to correct my mistakes that i was not aware of in the beginning. I also didn't do much research while prototyping with javascript. I tried a some libraries that didn't solve my requirements. I faced a lot of issue with date type.</p>
<p>In the begining of january 2024 there were a lot of calendar apps that where getting traction. Getting a good UX of a calendar is very hard. Different Calendars try to solve the UI/UX problems differently. eg:</p>
<ol>
<li><p>Create an event</p>
<ul>
<li>Rise and cron has a sidebar, whereas google calendar uses a popover</li>
</ul>
</li>
<li><p>Event Display</p>
<ul>
<li><p>Google Calendar - show start and end time of an event, Background is fully colour,</p>
</li>
<li><p>Rise - shows start time only, background has a alpha opacity to it</p>
</li>
</ul>
</li>
<li><p>Weekly Display</p>
<ul>
<li><p>Google calendar - Uses Pagination</p>
</li>
<li><p>Rise &amp; cron - uses infinite horizontal scroll (with virtualization)</p>
</li>
</ul>
</li>
<li><p>Long Event - Event longer than two days</p>
<ul>
<li>usually are added on the top of timelines,</li>
</ul>
</li>
<li><p>Drag and drop events its usually the same</p>
<ul>
<li>You can drag an events on timeslots, starttime, endtime, and date will change based on the time slot you add in.</li>
</ul>
</li>
<li><p>Drag to create a new events</p>
<ul>
<li>You can drag on timeline to create a new event, it will show a preview of the event with time display</li>
</ul>
</li>
<li><p>Event Types</p>
<ul>
<li><p>Google Calendar and Amie have tasks and events</p>
</li>
<li><p>Rise has events only</p>
</li>
</ul>
</li>
<li><p>Sharing Time Slots</p>
<ul>
<li><p>You can share timeslots for meeting, or anyone can add an event on your calendar.</p>
</li>
<li><p>Rise has this auto meeting conflict resolution, which will just schedule a meeting later based on your preferences.</p>
</li>
</ul>
</li>
<li><p>Timezones</p>
<ul>
<li>You can change the timezones</li>
</ul>
</li>
</ol>
<hr />
<h3 id="heading-understanding-dates">Understanding dates</h3>
<p>There are two way to save dates,</p>
<ul>
<li>one save in the ISO string formate</li>
</ul>
<p>"2024-01-17T09:30:00.000Z" =&gt; We will store the user participants timeZone as well. Used by Cal.com</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Assume this timestamp is retrieved from the database</span>
<span class="hljs-keyword">const</span> timestampFromDatabase = <span class="hljs-string">"2024-01-16T20:45:00.000Z"</span>;

<span class="hljs-comment">// Get the user's timezone (you might obtain this from user preferences or browser settings)</span>
<span class="hljs-keyword">const</span> userTimezone = <span class="hljs-string">"Asia/Kolkata"</span>; <span class="hljs-comment">// Example timezone</span>

<span class="hljs-comment">// Create a Date object from the timestamp (in UTC)</span>
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(timestampFromDatabase);

<span class="hljs-comment">// Adjust the date to the user's timezone</span>
date.toLocaleString(<span class="hljs-string">"en-US"</span>, { <span class="hljs-attr">timeZone</span>: userTimezone });

<span class="hljs-comment">// Display or use the adjusted date as needed</span>
<span class="hljs-built_in">console</span>.log(date.toLocaleString()); <span class="hljs-comment">// Adjusted timestamp for the user's timezone</span>
</code></pre>
<ul>
<li>Storing Date By Amie</li>
</ul>
<p>other is to save ISO String + the offset =&gt; the offset is based on the user locations</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> timestamp = <span class="hljs-string">"2024-01-16T20:45:00.000+05:30"</span>;
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(timestamp);

<span class="hljs-comment">// Format the date with time zone offset</span>
<span class="hljs-keyword">const</span> formattedDate = date.toLocaleString(<span class="hljs-string">"en-US"</span>, {
  <span class="hljs-attr">timeZoneName</span>: <span class="hljs-string">"short"</span>,
});

<span class="hljs-built_in">console</span>.log(formattedDate);
</code></pre>
<p>TimeStamp to ISOString;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> timestamp = <span class="hljs-number">1704306028000</span>;
<span class="hljs-keyword">const</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(timestamp);

<span class="hljs-built_in">console</span>.log(date.toISOString());
</code></pre>
<p>ISOString to TimeStamp;</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(); <span class="hljs-comment">// Current date and time</span>
<span class="hljs-keyword">const</span> todayTimestamp = today.getTime(); <span class="hljs-comment">// Timestamp in milliseconds</span>

<span class="hljs-built_in">console</span>.log(todayTimestamp);
</code></pre>
<p>Important</p>
<p>Google Calendar uses TimeStamps 1704306028000 The value 1704306028000 represents the number of milliseconds since the Unix Epoch (January 1, 1970, UTC). You can convert this timestamp to a human-readable date using JavaScript.</p>
<h3 id="heading-difference-between-locale-and-timezone">Difference between Locale and Timezone</h3>
<p>A locale is a set of parameters that defines the user's language, region, and cultural preferences. It includes information such as language, country, currency, date and time formats, and other regional settings.</p>
<p>A timezone is a region of the Earth that has the same standard time. It is determined by the longitudinal position of the location and can be expressed as an offset from Coordinated Universal Time (UTC).</p>
<p>the locale is more about language and cultural preferences affecting the presentation of information, the timezone is critical for handling time-related calculations</p>
<h3 id="heading-requirements">Requirements</h3>
<p>Here is a Google Calendar Video from frontend Enginner</p>
<ul>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=leo1FZ6vu1I">Video</a></p>
</li>
<li><p><a target="_blank" href="https://viewer.diagrams.net/?tags=%7B%7D&amp;highlight=0000ff&amp;edit=_blank&amp;layers=1&amp;nav=1&amp;title=Calendar.drawio#Uhttps%3A%2F%2Fdrive.google.com%2Fuc%3Fid%3D19n3i6lMGn0HjDy8MRIAn4BTJNjBcd9vd%26export%3Ddownload">Diagram</a></p>
</li>
</ul>
<h3 id="heading-networking">Networking</h3>
<ul>
<li><p>HTTP1</p>
</li>
<li><p>HTTP2</p>
</li>
<li><p>GraphQL</p>
</li>
<li><p>Pulling/Long, Polling/REST API</p>
</li>
<li><p>Web Sockets</p>
</li>
<li><p>SSE - Server Side Events</p>
</li>
</ul>
<details><summary>Here is how Rise Events looks Like</summary><div data-type="detailsContent"></div></details><details><summary>get all events preview</summary><div data-type="detailsContent"></div></details>

<p>Amie uses Graphql</p>
<p>Graphql get request to get all Events</p>
<p>Google Calendar Clone</p>
<p><a target="_blank" href="https://timelayout.vercel.app/">timelayout.vercel.app</a></p>
]]></content:encoded></item><item><title><![CDATA[Web Workers vs Service Workers vs Worklets]]></title><description><![CDATA[What are Web Workers?
Web Workers provide a way to run JavaScript code in a separate thread from the main UI thread of the browser. This allows for resource-intensive computations without affecting the responsiveness of the user interface.
Key Charac...]]></description><link>https://blog.coolhead.in/web-workers-vs-service-workers-vs-worklets</link><guid isPermaLink="true">https://blog.coolhead.in/web-workers-vs-service-workers-vs-worklets</guid><category><![CDATA[General Programming]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sat, 17 May 2025 21:24:13 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-what-are-web-workers">What are Web Workers?</h2>
<p>Web Workers provide a way to run JavaScript code in a separate thread from the main UI thread of the browser. This allows for resource-intensive computations without affecting the responsiveness of the user interface.</p>
<h3 id="heading-key-characteristics-of-web-workers">Key Characteristics of Web Workers:</h3>
<ul>
<li><p>Runs in a separate thread from the main UI thread.</p>
</li>
<li><p>Cannot directly access the DOM but can communicate via <code>postMessage()</code>.</p>
</li>
<li><p>Suitable for CPU-intensive tasks (data processing, calculations).</p>
</li>
</ul>
<h3 id="heading-example-usage">Example Usage</h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// main.js</span>
<span class="hljs-keyword">const</span> worker = <span class="hljs-keyword">new</span> Worker(<span class="hljs-string">'worker.js'</span>);
worker.postMessage(<span class="hljs-string">'Hello, Worker!'</span>);
worker.onmessage = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Message from Worker:'</span>, event.data);
};

<span class="hljs-comment">// worker.js</span>
self.onmessage = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  self.postMessage(<span class="hljs-string">'Worker received: '</span> + event.data);
};
</code></pre>
<h2 id="heading-what-are-service-workers">What are Service Workers?</h2>
<p>Service Workers act as a proxy between the web application and the network, enabling features like offline support, caching, and background sync. They run separately from the web page but can intercept network requests.</p>
<h3 id="heading-key-characteristics-of-service-workers">Key Characteristics of Service Workers:</h3>
<ul>
<li><p>Runs in a background thread, independent of web pages.</p>
</li>
<li><p>Can intercept and cache network requests.</p>
</li>
<li><p>Ideal for offline support and background synchronization.</p>
</li>
<li><p>Requires HTTPS for security reasons.</p>
</li>
</ul>
<h3 id="heading-example-usage-1">Example Usage</h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// Registering a service worker</span>
<span class="hljs-keyword">if</span> (<span class="hljs-string">'serviceWorker'</span> <span class="hljs-keyword">in</span> navigator) {
  navigator.serviceWorker.register(<span class="hljs-string">'/service-worker.js'</span>).then(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Service Worker registered successfully.'</span>);
  });
}
</code></pre>
<h2 id="heading-what-are-worklets">What are Worklets?</h2>
<p>Worklets are lightweight, specialized workers designed for specific tasks, such as audio processing (Audio Worklet) or CSS custom painting (Paint Worklet).</p>
<h3 id="heading-key-characteristics-of-worklets">Key Characteristics of Worklets:</h3>
<ul>
<li><p>Extremely lightweight and fast to initialize.</p>
</li>
<li><p>No direct access to the DOM or global scope.</p>
</li>
<li><p>Primarily used for specific purposes (audio, CSS painting).</p>
</li>
</ul>
<h3 id="heading-example-usage-2">Example Usage</h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// Registering a paint worklet</span>
CSS.paintWorklet.addModule(<span class="hljs-string">'paint-worklet.js'</span>);
</code></pre>
<h3 id="heading-in-summary">In Summary:</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td></td><td>Web Workers</td><td>Service Workers</td><td>Worklets</td></tr>
</thead>
<tbody>
<tr>
<td>Execution Context</td><td>Separate Thread</td><td>Background Thread</td><td>Specialized Context</td></tr>
<tr>
<td>DOM Access</td><td>No</td><td>No</td><td>No</td></tr>
<tr>
<td>Network Control</td><td>No</td><td>Yes (can intercept requests)</td><td>No</td></tr>
<tr>
<td>Use Cases</td><td>CPU-intensive tasks</td><td>Offline support, caching</td><td>Custom painting, audio</td></tr>
<tr>
<td>Lifetime</td><td>Active as long as needed</td><td>Persistent, independent of pages</td><td>Short-lived</td></tr>
</tbody>
</table>
</div><hr />
]]></content:encoded></item><item><title><![CDATA[Creating a Performant Rectangle Selection Box with Callbacks Using Web Components]]></title><description><![CDATA[In this article, you'll learn how to create a performant rectangle selection box using web components and JavaScript. The objective is to build an interactive tool that allows users to select multiple elements within a defined rectangular area, with ...]]></description><link>https://blog.coolhead.in/creating-a-performant-rectangle-selection-box-with-callbacks-using-web-components</link><guid isPermaLink="true">https://blog.coolhead.in/creating-a-performant-rectangle-selection-box-with-callbacks-using-web-components</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Components]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Fri, 07 Feb 2025 16:47:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738946123627/54dbc5a2-6c45-47ed-bd68-9de4e3ff4dd9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, you'll learn how to create a performant rectangle selection box using web components and JavaScript. The objective is to build an interactive tool that allows users to select multiple elements within a defined rectangular area, with a callback function that provides all the elements within the selection.</p>
<p>Let's break down the implementation into small, manageable problems.</p>
<h2 id="heading-1-getting-dom-elements-within-a-rectangle">1. <strong>Getting DOM Elements within a Rectangle</strong></h2>
<p>To identify all elements within the selection rectangle, we need to check if the rectangle boundaries intersect with the bounding boxes of the elements on the page.</p>
<pre><code class="lang-jsx">getElementsWithinSelection(rect) {
  <span class="hljs-keyword">const</span> allElements = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">document</span>.body.querySelectorAll(<span class="hljs-string">'*'</span>));
  <span class="hljs-keyword">return</span> allElements.filter(<span class="hljs-function"><span class="hljs-params">element</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> elRect = element.getBoundingClientRect();
    <span class="hljs-keyword">return</span> (
      elRect.top &lt; rect.bottom &amp;&amp;
      elRect.bottom &gt; rect.top &amp;&amp;
      elRect.left &lt; rect.right &amp;&amp;
      elRect.right &gt; rect.left
    );
  });
}
</code></pre>
<h3 id="heading-how-it-works"><strong>How It Works:</strong></h3>
<ul>
<li><p><code>getBoundingClientRect()</code> gets the position and dimensions of an element.</p>
</li>
<li><p>We filter the elements whose bounding boxes intersect with the given rectangle.</p>
</li>
</ul>
<h2 id="heading-2-drawingrendering-the-selection-ui">2. <strong>Drawing/Rendering the Selection UI</strong></h2>
<p>To visually represent the selection area, we'll create an overlay element styled with a transparent background.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
  <span class="hljs-selector-pseudo">:host</span> {
    <span class="hljs-attribute">position</span>: fixed;
    <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">z-index</span>: <span class="hljs-number">9999</span>;
    <span class="hljs-attribute">pointer-events</span>: none;
  }
  <span class="hljs-selector-class">.selection-overlay</span> {
    <span class="hljs-attribute">position</span>: absolute;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.2</span>);
    <span class="hljs-attribute">clip-path</span>: <span class="hljs-built_in">polygon</span>(<span class="hljs-number">0</span> <span class="hljs-number">0</span>, <span class="hljs-number">0</span> <span class="hljs-number">0</span>, <span class="hljs-number">0</span> <span class="hljs-number">0</span>, <span class="hljs-number">0</span> <span class="hljs-number">0</span>);
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"selection-overlay"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h2 id="heading-3-creating-a-component-using-web-components">3. <strong>Creating a Component Using Web Components</strong></h2>
<p>Web components encapsulate the functionality and styling, making the selection tool reusable and modular.</p>
<h3 id="heading-constructor"><strong>Constructor</strong></h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">constructor</span>() {
  <span class="hljs-built_in">super</span>();
  <span class="hljs-built_in">this</span>.attachShadow({ <span class="hljs-attr">mode</span>: <span class="hljs-string">'open'</span> });

  <span class="hljs-built_in">this</span>.startX = <span class="hljs-number">0</span>;
  <span class="hljs-built_in">this</span>.startY = <span class="hljs-number">0</span>;
  <span class="hljs-built_in">this</span>.isSelecting = <span class="hljs-literal">false</span>;

  <span class="hljs-built_in">this</span>.shadowRoot.innerHTML = <span class="hljs-string">`
  &lt;style&gt;
    :host {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 9999;
      pointer-events: none;
    }
    .selection-overlay {
      position: absolute;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 255, 0.2);
      clip-path: polygon(0 0, 0 0, 0 0, 0 0);
      opacity: 0;
    }
  &lt;/style&gt;
  &lt;div class="selection-overlay"&gt;&lt;/div&gt;
`</span>;

  <span class="hljs-built_in">this</span>.overlay = <span class="hljs-built_in">this</span>.shadowRoot.querySelector(<span class="hljs-string">'.selection-overlay'</span>);
}
</code></pre>
<h3 id="heading-connecting-and-disconnecting-event-listeners"><strong>Connecting and Disconnecting Event Listeners</strong></h3>
<p>We add mouse event listeners to capture user interactions.</p>
<pre><code class="lang-jsx">connectedCallback() {
  <span class="hljs-built_in">this</span>.addEventListeners();
}

disconnectedCallback() {
  <span class="hljs-built_in">this</span>.removeEventListeners();
}

addEventListeners() {
  <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mousedown'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> <span class="hljs-built_in">this</span>.onMouseDown(event));
  <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mouseup'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> <span class="hljs-built_in">this</span>.onMouseUp(event));
  <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mousemove'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> <span class="hljs-built_in">this</span>.onMouseMove(event));
}

removeEventListeners() {
  <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">'mousedown'</span>, <span class="hljs-built_in">this</span>.onMouseDown);
  <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">'mouseup'</span>, <span class="hljs-built_in">this</span>.onMouseUp);
  <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">'mousemove'</span>, <span class="hljs-built_in">this</span>.onMouseMove);
}
</code></pre>
<h2 id="heading-4-adding-propsattributes-to-web-components">4. <strong>Adding Props/Attributes to Web Components</strong></h2>
<p>We can define attributes that control the behavior or appearance of the component. In this case, let's support a customizable background.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">static</span> <span class="hljs-keyword">get</span> <span class="hljs-title">observedAttributes</span>() {
  <span class="hljs-keyword">return</span> [<span class="hljs-string">'background'</span>];
}

attributeChangedCallback(name, oldValue, newValue) {
  <span class="hljs-keyword">if</span> (name === <span class="hljs-string">'background'</span>) {
    <span class="hljs-built_in">this</span>.setBackground(newValue);
  }
}

setBackground(background) {
  <span class="hljs-built_in">this</span>.overlay.style.background = background;
}
</code></pre>
<h2 id="heading-5-propagating-custom-events-with-callbacks">5. <strong>Propagating Custom Events with Callbacks</strong></h2>
<p>When the selection is complete, dispatch a custom event with the selected elements.</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">this</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'selection-complete'</span>, {
  <span class="hljs-attr">detail</span>: { <span class="hljs-attr">elements</span>: elementsWithinSelection },
  <span class="hljs-attr">bubbles</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">composed</span>: <span class="hljs-literal">true</span>,
}));
</code></pre>
<h2 id="heading-6-using-the-component-and-listening-for-callbacks">6. <strong>Using the Component and Listening for Callbacks</strong></h2>
<p>To use the custom selection tool component and handle the callback, add the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">cr-selection</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"selection-tool"</span> <span class="hljs-attr">background</span>=<span class="hljs-string">"rgba(255, 0, 0, 0.1)"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">cr-selection</span>&gt;</span>
</code></pre>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> selectionTool = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'selection-tool'</span>);

<span class="hljs-comment">// Listen for the selection-complete event</span>
selectionTool.addEventListener(<span class="hljs-string">'selection-complete'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> selectedElements = event.detail.elements;

  <span class="hljs-comment">// Log the selected elements</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Selected Elements:'</span>, selectedElements);

  <span class="hljs-comment">// Highlight the selected elements</span>
  selectedElements.forEach(<span class="hljs-function"><span class="hljs-params">el</span> =&gt;</span> {
    el.style.border = <span class="hljs-string">'2px solid red'</span>;
  });
});
</code></pre>
<h3 id="heading-how-it-works-1"><strong>How It Works:</strong></h3>
<ol>
<li><p>The component listens for mouse events to define the selection rectangle.</p>
</li>
<li><p>When the selection completes, the <code>selection-complete</code> event fires with the selected elements.</p>
</li>
<li><p>The callback function handles highlighting the selected elements.</p>
</li>
</ol>
<h3 id="heading-full-javascript-code">Full Javascript Code</h3>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CrSelection</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HTMLElement</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">super</span>();
        <span class="hljs-built_in">this</span>.attachShadow({ <span class="hljs-attr">mode</span>: <span class="hljs-string">'open'</span> });

        <span class="hljs-built_in">this</span>.startX = <span class="hljs-number">0</span>;
        <span class="hljs-built_in">this</span>.startY = <span class="hljs-number">0</span>;
        <span class="hljs-built_in">this</span>.isSelecting = <span class="hljs-literal">false</span>;

        <span class="hljs-built_in">this</span>.shadowRoot.innerHTML = <span class="hljs-string">`
        &lt;style&gt;
          :host {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 9999;
            pointer-events: none;
          }
          .selection-overlay {
            position: absolute;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 255, 0.2);
            clip-path: polygon(0 0, 0 0, 0 0, 0 0);
            opacity: 0;
          }
        &lt;/style&gt;
        &lt;div class="selection-overlay"&gt;&lt;/div&gt;
      `</span>;

        <span class="hljs-built_in">this</span>.overlay = <span class="hljs-built_in">this</span>.shadowRoot.querySelector(<span class="hljs-string">'.selection-overlay'</span>);
    }

    <span class="hljs-keyword">static</span> <span class="hljs-keyword">get</span> <span class="hljs-title">observedAttributes</span>() {
        <span class="hljs-keyword">return</span> [<span class="hljs-string">'background'</span>]
    }

    attributeChangedCallback(name, oldValue, newValue) {
        <span class="hljs-keyword">if</span> (name === <span class="hljs-string">'background'</span>) {
            <span class="hljs-built_in">this</span>.setBackground(newValue);
        }
    }

    setBackground(background) {
        <span class="hljs-built_in">this</span>.overlay.style.background = background;
    }



    connectedCallback() {
        <span class="hljs-built_in">this</span>.addEventListeners();
    }

    disconnectedCallback() {
        <span class="hljs-built_in">this</span>.removeEventListeners();
    }

    addEventListeners() {
        <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mousedown'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> <span class="hljs-built_in">this</span>.onMouseDown(event));
        <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mouseup'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> <span class="hljs-built_in">this</span>.onMouseUp(event));
        <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'mousemove'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> <span class="hljs-built_in">this</span>.onMouseMove(event));
    }

    removeEventListeners() {
        <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">'mousedown'</span>, <span class="hljs-built_in">this</span>.onMouseDown);
        <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">'mouseup'</span>, <span class="hljs-built_in">this</span>.onMouseUp);
        <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">'mousemove'</span>, <span class="hljs-built_in">this</span>.onMouseMove);
    }

    onMouseDown(event) {
        <span class="hljs-keyword">if</span> (event.button !== <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span>; <span class="hljs-comment">// Only left-click</span>

        <span class="hljs-built_in">this</span>.startX = event.clientX;
        <span class="hljs-built_in">this</span>.startY = event.clientY;
        <span class="hljs-built_in">this</span>.isSelecting = <span class="hljs-literal">true</span>;

        <span class="hljs-built_in">this</span>.overlay.style.clipPath = <span class="hljs-string">'none'</span>; <span class="hljs-comment">// Reset the clip-path</span>
    }

    onMouseMove(event) {
        <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isSelecting) <span class="hljs-keyword">return</span>;

        <span class="hljs-keyword">const</span> currentX = event.clientX;
        <span class="hljs-keyword">const</span> currentY = event.clientY;

        <span class="hljs-keyword">const</span> x1 = <span class="hljs-built_in">Math</span>.min(<span class="hljs-built_in">this</span>.startX, currentX);
        <span class="hljs-keyword">const</span> y1 = <span class="hljs-built_in">Math</span>.min(<span class="hljs-built_in">this</span>.startY, currentY);
        <span class="hljs-keyword">const</span> x2 = <span class="hljs-built_in">Math</span>.max(<span class="hljs-built_in">this</span>.startX, currentX);
        <span class="hljs-keyword">const</span> y2 = <span class="hljs-built_in">Math</span>.max(<span class="hljs-built_in">this</span>.startY, currentY);
        <span class="hljs-built_in">this</span>.overlay.style.opacity = <span class="hljs-string">'100'</span>


        <span class="hljs-built_in">this</span>.overlay.style.clipPath = <span class="hljs-string">`
            polygon(
                <span class="hljs-subst">${x1}</span>px <span class="hljs-subst">${y1}</span>px, 
                <span class="hljs-subst">${x2}</span>px <span class="hljs-subst">${y1}</span>px, 
                <span class="hljs-subst">${x2}</span>px <span class="hljs-subst">${y2}</span>px, 
                <span class="hljs-subst">${x1}</span>px <span class="hljs-subst">${y2}</span>px
            )
        `</span>;
    }

    onMouseUp(event) {
        <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isSelecting) <span class="hljs-keyword">return</span>;

        <span class="hljs-built_in">this</span>.isSelecting = <span class="hljs-literal">false</span>;

        <span class="hljs-keyword">const</span> selectionRect = {
            <span class="hljs-attr">top</span>: <span class="hljs-built_in">Math</span>.min(<span class="hljs-built_in">this</span>.startY, event.clientY),
            <span class="hljs-attr">left</span>: <span class="hljs-built_in">Math</span>.min(<span class="hljs-built_in">this</span>.startX, event.clientX),
            <span class="hljs-attr">right</span>: <span class="hljs-built_in">Math</span>.max(<span class="hljs-built_in">this</span>.startX, event.clientX),
            <span class="hljs-attr">bottom</span>: <span class="hljs-built_in">Math</span>.max(<span class="hljs-built_in">this</span>.startY, event.clientY),
        };

        <span class="hljs-keyword">const</span> elementsWithinSelection = <span class="hljs-built_in">this</span>.getElementsWithinSelection(selectionRect);

        <span class="hljs-built_in">this</span>.dispatchEvent(<span class="hljs-keyword">new</span> CustomEvent(<span class="hljs-string">'selection-complete'</span>, {
            <span class="hljs-attr">detail</span>: { <span class="hljs-attr">elements</span>: elementsWithinSelection },
            <span class="hljs-attr">bubbles</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">composed</span>: <span class="hljs-literal">true</span>,
        }));

        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'elements in selection'</span>, elementsWithinSelection);

        <span class="hljs-built_in">this</span>.overlay.style.clipPath = <span class="hljs-string">'none'</span>; <span class="hljs-comment">// Clear selection area</span>
        <span class="hljs-built_in">this</span>.overlay.style.opacity = <span class="hljs-string">'0'</span>
    }

    getElementsWithinSelection(rect) {
        <span class="hljs-keyword">const</span> allElements = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">document</span>.body.querySelectorAll(<span class="hljs-string">'*'</span>));

        <span class="hljs-keyword">return</span> allElements.filter(<span class="hljs-function"><span class="hljs-params">element</span> =&gt;</span> {
            <span class="hljs-keyword">if</span> (element === <span class="hljs-built_in">this</span> || <span class="hljs-built_in">this</span>.contains(element)) {
                <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
            }
            <span class="hljs-keyword">const</span> elRect = element.getBoundingClientRect();
            <span class="hljs-keyword">return</span> (
                elRect.top &lt; rect.bottom &amp;&amp;
                elRect.bottom &gt; rect.top &amp;&amp;
                elRect.left &lt; rect.right &amp;&amp;
                elRect.right &gt; rect.left
            );
        });
    }
}

customElements.define(<span class="hljs-string">'cr-selection'</span>, CrSelection);
</code></pre>
<h3 id="heading-codepen">Codepen</h3>
<p>Here the Full Code in Codepen :</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/pratiksharma15/pen/RNbXVaZ">https://codepen.io/pratiksharma15/pen/RNbXVaZ</a></div>
<p> </p>
<p>Try Click and Dragging in the above Codepen</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>With this approach, we've built a performant and customizable rectangle selection box using web components. This tool can be extended for various applications such as graphic editors, data selection, or visual analysis tools. The modular design ensures it's reusable and maintainable for future projects.</p>
]]></content:encoded></item><item><title><![CDATA[CSS Animation Performance - CheatSheet]]></title><description><![CDATA[Here’s a comprehensive table of CSS properties categorized by their impact on browser rendering performance, specifically focusing on Layout, Paint, and Composite:

Layout: Calculate the size and position of elements on the page.

Paint: Draw the pag...]]></description><link>https://blog.coolhead.in/css-animation-performance-cheatsheet</link><guid isPermaLink="true">https://blog.coolhead.in/css-animation-performance-cheatsheet</guid><category><![CDATA[CSS]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Python]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Fri, 07 Feb 2025 10:42:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738924860408/67cc8343-fa4c-46ad-9a9f-8c5322fc36f3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Here’s a comprehensive table of CSS properties categorized by their impact on browser rendering performance, specifically focusing on <strong>Layout</strong>, <strong>Paint</strong>, and <strong>Composite</strong>:</p>
<ul>
<li><p><strong><em>Layout</em></strong>: Calculate the size and position of elements on the page.</p>
</li>
<li><p><strong><em>Paint</em></strong>: Draw the page into graphical layers - essentially individual images that make up the page.</p>
</li>
<li><p><strong><em>Composite</em></strong>: Draw these layers to the viewport.</p>
</li>
</ul>
<blockquote>
<p>Properties <code>clip-path</code>, <code>opacity</code> , <code>transform</code>, <code>z-index</code>, <code>visibility</code>, <code>filter</code> , are best for performing web animations</p>
</blockquote>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>CSS Property</strong></td><td><strong>Layout</strong></td><td><strong>Paint</strong></td><td><strong>Composite</strong></td><td><strong>Notes</strong></td></tr>
</thead>
<tbody>
<tr>
<td><code>width</code>, <code>height</code></td><td>✅</td><td>❌</td><td>❌</td><td>Affects element and child layout</td></tr>
<tr>
<td><code>margin</code>, <code>padding</code></td><td>✅</td><td>❌</td><td>❌</td><td>Triggers layout changes</td></tr>
<tr>
<td><code>border</code></td><td>❌</td><td>✅</td><td>❌</td><td>Repaints element boundary</td></tr>
<tr>
<td><code>box-shadow</code></td><td>❌</td><td>✅</td><td>❌</td><td>Complex paints for shadows</td></tr>
<tr>
<td><code>top</code>, <code>left</code>, <code>right</code>, <code>bottom</code></td><td>✅</td><td>❌</td><td>❌</td><td>Reflows and triggers layout</td></tr>
<tr>
<td><code>position</code></td><td>✅</td><td>❌</td><td>❌</td><td>Changes element's positioning model</td></tr>
<tr>
<td><code>display</code></td><td>✅</td><td>❌</td><td>❌</td><td>Can remove or reflow elements entirely</td></tr>
<tr>
<td><code>color</code>, <code>background-color</code></td><td>❌</td><td>✅</td><td>❌</td><td>Simple paint update</td></tr>
<tr>
<td><code>background-image</code></td><td>❌</td><td>✅</td><td>❌</td><td>Complex paint updates</td></tr>
<tr>
<td><code>transform</code></td><td>❌</td><td>❌</td><td>✅</td><td>GPU accelerated; efficient compositing</td></tr>
<tr>
<td><code>opacity</code></td><td>❌</td><td>❌</td><td>✅</td><td>Composited efficiently</td></tr>
<tr>
<td><code>z-index</code></td><td>❌</td><td>❌</td><td>✅</td><td>Layer stacking order</td></tr>
<tr>
<td><code>visibility</code></td><td>❌</td><td>❌</td><td>✅</td><td>Affects visibility without layout</td></tr>
<tr>
<td><code>overflow</code></td><td>✅</td><td>❌</td><td>❌</td><td>Layout affected by scrollbars</td></tr>
<tr>
<td><code>clip-path</code></td><td>❌</td><td>❌</td><td>✅</td><td>Efficient compositing</td></tr>
<tr>
<td><code>border-radius</code></td><td>❌</td><td>✅</td><td>❌</td><td>Paint complexity increases</td></tr>
<tr>
<td><code>filter</code></td><td>❌</td><td>❌</td><td>✅</td><td>GPU optimized for modern browsers</td></tr>
<tr>
<td><code>box-sizing</code></td><td>✅</td><td>❌</td><td>❌</td><td>Changes size calculations</td></tr>
<tr>
<td><code>font-size</code>, <code>font-family</code></td><td>✅</td><td>✅</td><td>❌</td><td>Relayout and repaint text</td></tr>
<tr>
<td><code>line-height</code>, <code>letter-spacing</code></td><td>✅</td><td>✅</td><td>❌</td><td>Text rendering changes</td></tr>
</tbody>
</table>
</div><h3 id="heading-legend"><strong>Legend:</strong></h3>
<ul>
<li><p>✅: Triggers the specified phase</p>
</li>
<li><p>❌: Does not trigger the phase</p>
</li>
</ul>
<h3 id="heading-performance-tip"><strong>Performance Tip:</strong></h3>
<ul>
<li><p>Prefer <strong>transform</strong> and <strong>opacity</strong> changes for animations instead of properties like <code>top</code>, <code>left</code>, or <code>width</code> to avoid costly layout recalculations.</p>
</li>
<li><p>Reduce unnecessary paints and layout reflows by using GPU-accelerated properties (<code>transform</code>, <code>opacity</code>).</p>
</li>
<li><p><code>transform</code> and <code>opacity</code> are cheapest to render in all browsers. Browsers are improving the rendering performance of other styles (and SVG) all the time, with <code>filter</code>, <code>background-color</code> and <code>clip-path</code> on the horizon.</p>
</li>
</ul>
<h3 id="heading-how-to-use-will-change">How to use Will-change ?</h3>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/will-change"><strong>will-change</strong></a> <strong>css</strong> property hints to browsers how an element is expected to change. Browsers may set up optimisations before an element is actually changed.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Keyword values */</span>
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">auto</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">scroll-position</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">contents</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">transform</span>; <span class="hljs-comment">/* Example of &lt;custom-ident&gt; */</span>
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">opacity</span>; <span class="hljs-comment">/* Example of &lt;custom-ident&gt; */</span>
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">left</span>, <span class="hljs-selector-tag">top</span>; <span class="hljs-comment">/* Example of two &lt;animatable-feature&gt; */</span>

<span class="hljs-comment">/* Global values */</span>
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">inherit</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">initial</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">revert</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">revert-layer</span>;
<span class="hljs-selector-tag">will-change</span>: <span class="hljs-selector-tag">unset</span>;
</code></pre>
<p>You can hint to the browser that they should create a new layer by setting the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/will-change"><code>willChange</code> style</a> to <code>"transform"</code>:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">element</span><span class="hljs-selector-class">.style</span><span class="hljs-selector-class">.willChange</span> = "<span class="hljs-selector-tag">transform</span>"
</code></pre>
<p>Instead of animating <code>boxShadow</code>, animate <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/filter"><code>filter</code> with the <code>drop-shadow</code> function</a>:</p>
<pre><code class="lang-css">// ❌

<span class="hljs-selector-id">#box</span><span class="hljs-selector-pseudo">:hover</span> { <span class="hljs-attribute">boxShadow</span>: <span class="hljs-string">"10px 10px black"</span> };

// ✅

<span class="hljs-selector-id">#box</span><span class="hljs-selector-pseudo">:hover</span> { <span class="hljs-attribute">filter</span>: <span class="hljs-string">"drop-shadow(10px 10px black)"</span> };
</code></pre>
<h3 id="heading-browser-rendering">Browser Rendering :</h3>
<h3 id="heading-1-layout-reflow">1. <strong>Layout (Reflow)</strong></h3>
<p><strong>Definition:</strong></p>
<p>The layout phase calculates the position and size of elements in the document based on the CSS and DOM structure.</p>
<p><strong>When It's Triggered:</strong></p>
<ul>
<li><p>Adding, removing, or changing the size/position of elements (<code>width</code>, <code>height</code>, <code>margin</code>, <code>padding</code>, etc.).</p>
</li>
<li><p>Resizing the window or changing the font size.</p>
</li>
</ul>
<p><strong>Performance Impact:</strong></p>
<ul>
<li><p>Expensive, as it affects the entire document or subtree of elements.</p>
</li>
<li><p>Causes reflow for child elements when dimensions change.</p>
</li>
</ul>
<hr />
<h3 id="heading-2-paint-repaint">2. <strong>Paint (Repaint)</strong></h3>
<p><strong>Definition:</strong></p>
<p>The paint phase involves filling in pixels for visual elements, such as colors, borders, text, and shadows.</p>
<p><strong>When It's Triggered:</strong></p>
<ul>
<li>Changes to visual properties that don’t affect the layout (<code>color</code>, <code>background-color</code>, <code>border</code>, <code>box-shadow</code>).</li>
</ul>
<p><strong>Performance Impact:</strong></p>
<ul>
<li>Moderate cost as it redraws only the visual parts of elements but doesn't impact the layout.</li>
</ul>
<hr />
<h3 id="heading-3-composite-layer-composition">3. <strong>Composite (Layer Composition)</strong></h3>
<p><strong>Definition:</strong></p>
<p>The composite phase involves assembling the different painted layers on the GPU to display the final image on the screen.</p>
<p><strong>When It's Triggered:</strong></p>
<ul>
<li>GPU-accelerated properties such as <code>transform</code>, <code>opacity</code>, and <code>filter</code>.</li>
</ul>
<p><strong>Performance Impact:</strong></p>
<ul>
<li><p>Least expensive as it avoids recalculating layout or repainting.</p>
</li>
<li><p>Efficiently handled by the GPU for smoother animations.</p>
</li>
</ul>
<hr />
<h3 id="heading-summary-table"><strong>Summary Table</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Phase</strong></td><td><strong>Triggered By</strong></td><td><strong>Performance Impact</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Layout</strong></td><td>Size and position changes</td><td>High</td></tr>
<tr>
<td><strong>Paint</strong></td><td>Visual appearance changes</td><td>Moderate</td></tr>
<tr>
<td><strong>Composite</strong></td><td>GPU-based transforms and effects</td><td>Low</td></tr>
</tbody>
</table>
</div><h3 id="heading-further-read">Further Read:</h3>
<ol>
<li><a target="_blank" href="https://developer.chrome.com/blog/inside-browser-part3">https://developer.chrome.com/blog/inside-browser-part3</a></li>
</ol>
<h3 id="heading-reference">Reference:</h3>
<ol>
<li><p><a target="_blank" href="https://motion.dev/docs/performance">https://motion.dev/docs/performance</a></p>
</li>
<li><p><a target="_blank" href="https://motion.dev/blog/do-you-still-need-framer-motion">https://motion.dev/blog/do-you-still-need-framer-motion</a></p>
</li>
<li><p><a target="_blank" href="https://developer.chrome.com/blog/inside-browser-part3">https://developer.chrome.com/blog/inside-browser-part3</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[10 Exciting Web Trends to Watch in 2025]]></title><description><![CDATA[Web GPU

Web Components

Container Queries

Css Animation → View Transition, Scroll Animation

Going Vanilla instead of Frameworks

Chrome Browser AI

New Component Based Libraries

Fancy Components

Aceternity UI



React 19

Routing Libraries

Sign...]]></description><link>https://blog.coolhead.in/10-exciting-web-trends-to-watch-in-2025</link><guid isPermaLink="true">https://blog.coolhead.in/10-exciting-web-trends-to-watch-in-2025</guid><category><![CDATA[Web Development]]></category><category><![CDATA[webdev]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Python]]></category><category><![CDATA[Web Design]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sun, 05 Jan 2025 13:58:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1736085365990/5a81a3b4-3c49-4968-8484-b43e1f8023a5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Web GPU</p>
</li>
<li><p>Web Components</p>
</li>
<li><p>Container Queries</p>
</li>
<li><p>Css Animation → View Transition, Scroll Animation</p>
</li>
<li><p>Going Vanilla instead of Frameworks</p>
</li>
<li><p>Chrome Browser AI</p>
</li>
<li><p>New Component Based Libraries</p>
<ol>
<li><p>Fancy Components</p>
</li>
<li><p>Aceternity UI</p>
</li>
</ol>
</li>
<li><p>React 19</p>
</li>
<li><p>Routing Libraries</p>
</li>
<li><p>Signal API</p>
</li>
</ol>
<h2 id="heading-1-web-gpu">1. Web GPU</h2>
<p>Web GPU is set to revolutionize how we handle graphics and compute workloads in the browser. It provides developers with low-level access to the GPU, enabling high-performance rendering, data processing, and machine learning applications. Unlike its predecessor WebGL, Web GPU is more flexible and closer to modern graphics APIs like Vulkan and DirectX 12. This opens up new possibilities for gaming, 3D modeling, and AI-powered applications directly in the browser.</p>
<h2 id="heading-2-web-components">2. Web Components</h2>
<p>Web Components are gaining traction as a standard for reusable and encapsulated UI elements. With technologies like Shadow DOM, HTML templates, and custom elements, developers can create components that work seamlessly across any framework or vanilla JavaScript. As browser support improves, Web Components are becoming a cornerstone for modular and maintainable web applications.</p>
<h2 id="heading-3-container-queries">3. Container Queries</h2>
<p>CSS Container Queries are a game-changer for responsive design. Unlike media queries, which depend on the viewport size, container queries allow styles to adapt based on the size of a parent container. This enables truly modular and reusable components, making it easier to build responsive layouts in complex, component-based architectures.</p>
<h2 id="heading-4-css-animations-view-transition-api-amp-scroll-linked-animations">4. CSS Animations: View Transition API &amp; Scroll-Linked Animations</h2>
<p>CSS animations are evolving with new APIs that make creating sophisticated transitions easier than ever. The View Transition API simplifies animations between different pages or states, providing smoother user experiences. Scroll-linked animations allow developers to tie animations to scrolling behavior, opening up possibilities for storytelling, parallax effects, and interactive designs.</p>
<h2 id="heading-5-going-vanilla-instead-of-frameworks">5. Going Vanilla Instead of Frameworks</h2>
<p>There’s a growing movement toward using vanilla JavaScript over heavy frameworks for lightweight and performance-critical applications. Modern JavaScript features, along with libraries like Lit and Alpine.js, make it easier to build functional, maintainable web apps without the overhead of larger frameworks. This trend emphasizes simplicity, performance, and better understanding of core web technologies.</p>
<h2 id="heading-6-chrome-browser-ai">6. Chrome Browser AI</h2>
<p>Google’s Chrome team is leveraging AI to enhance the browser experience. Features like improved accessibility tools, real-time translation, and intelligent page navigation are becoming standard. The integration of AI-driven features directly into the browser promises to make web applications smarter and more user-friendly.</p>
<h2 id="heading-7-new-component-based-libraries">7. New Component-Based Libraries</h2>
<p>New libraries focused on modern UI paradigms are cropping up. Two standout names are:</p>
<ul>
<li><p><a target="_blank" href="https://www.fancycomponents.dev/"><strong>Fancy Components</strong></a><strong>:</strong> A library emphasizing beautifully designed, out-of-the-box UI components that can be customized for any project.</p>
</li>
<li><p><a target="_blank" href="https://ui.aceternity.com/"><strong>Aceternity UI</strong></a><strong>:</strong> A sleek and lightweight library for building modular and accessible components, targeting both developers and designers.</p>
</li>
</ul>
<p>These libraries help bridge the gap between design and development, offering robust tools for rapid prototyping and production-ready components.</p>
<h2 id="heading-8-react-19">8. React 19</h2>
<p>React continues to dominate the frontend ecosystem, and the upcoming React 19 promises to push boundaries even further. With improvements in server-side rendering, streaming, and concurrent rendering, React 19 aims to make applications faster and more responsive. Its focus on developer ergonomics ensures that building complex interfaces remains intuitive and efficient.</p>
<h2 id="heading-9-routing-libraries">9. Routing Libraries</h2>
<p>Routing is a fundamental part of web development, and new libraries are taking routing to the next level. Libraries like React Router 7 and TanStack Router offer enhanced features like data fetching, nested routing, and improved performance. These tools simplify the creation of dynamic and scalable web applications while providing better user experiences.</p>
<h2 id="heading-10-signal-api">10. Signal API</h2>
<p>The Signal API introduces a reactive programming model directly into the browser. It allows developers to create reactive state management systems without relying on external libraries. With its focus on reactivity and efficiency, the Signal API simplifies how we handle application state, making it a promising tool for the future of web development.</p>
<hr />
<p>Want to discuss/meet with me ? <a target="_blank" href="https://cal.com/biomathcode">Meet Link</a></p>
]]></content:encoded></item><item><title><![CDATA[Explaining Scoped Context in React with example]]></title><description><![CDATA[React Context is a Global Variable

In Javascript, variables are scoped within function definitions.
Explaining Scoped Context in React with Examples
React Context is often described as a mechanism to manage global state, acting as a shared variable ...]]></description><link>https://blog.coolhead.in/explaining-scoped-context-in-react-with-example</link><guid isPermaLink="true">https://blog.coolhead.in/explaining-scoped-context-in-react-with-example</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sat, 21 Dec 2024 15:22:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734794448310/88133455-d822-4853-9ccd-0c77fc572bb8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>React Context is a Global Variable</strong></p>
</blockquote>
<p>In Javascript, variables are <a target="_blank" href="https://blog.coolhead.in/difference-between-function-scope-and-block-scope-in-javascript">scoped</a> within function definitions.</p>
<h2 id="heading-explaining-scoped-context-in-react-with-examples">Explaining Scoped Context in React with Examples</h2>
<p>React Context is often described as a mechanism to manage global state, acting as a shared variable accessible across a React component tree. While this description is accurate, it oversimplifies the capabilities of Context. In this article, we’ll dive into how to scope Context effectively, ensuring that it is used only where needed and avoids unnecessary re-renders.</p>
<h3 id="heading-what-is-react-context">What is React Context?</h3>
<p>React Context provides a way to pass data through the component tree without having to pass props manually at every level. It’s created using <code>React.createContext</code> and consists of a <code>Provider</code> and <code>Consumer</code> pair. A <code>Provider</code> component supplies the value, and any component wrapped with the <code>Consumer</code> or the <code>useContext</code> hook can access it.</p>
<p>Here’s a basic example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { createContext, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> ThemeContext = createContext(<span class="hljs-string">"light"</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ThemeContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"dark"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Toolbar</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ThemeContext.Provider</span>&gt;</span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Toolbar</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ThemedButton</span> /&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ThemedButton</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> theme = useContext(ThemeContext);
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>{`Theme: ${theme}`}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In this example, <code>ThemedButton</code> can access the <code>theme</code> value provided by <code>ThemeContext.Provider</code> without explicitly passing props through <code>Toolbar</code>.</p>
<h3 id="heading-why-scoped-context">Why Scoped Context?</h3>
<p>While Context is powerful, using it indiscriminately can lead to performance issues. When the value provided by a <code>Context.Provider</code> changes, all components consuming that context will re-render. In complex applications, this can cause unnecessary re-renders of unrelated components.</p>
<p>Scoped Context refers to the practice of limiting the usage of Context to only the parts of the component tree that actually need it. This approach helps maintain performance and keeps the component structure clean and understandable.</p>
<h3 id="heading-challenges-in-compound-components">Challenges in Compound Components</h3>
<p>Consider scenarios involving compound components, such as those provided by libraries like Radix Primitives. These components often use Context internally to manage state and interactions. However, issues can arise when similar components are composed together, leading to context collisions.</p>
<h4 id="heading-example-with-radix-primitives">Example with Radix Primitives</h4>
<p>Radix Primitives provides highly composable APIs for building accessible components. Here’s an example:</p>
<pre><code class="lang-typescript">&lt;AlertDialog.Root&gt;
  &lt;Dialog.Root&gt;
    &lt;Dialog.Trigger /&gt;
    &lt;Dialog.Content&gt;
      &lt;AlertDialog.Trigger /&gt; {<span class="hljs-comment">/* note the alert trigger in dialog content */</span>}
    &lt;/Dialog.Content&gt;
  &lt;/Dialog.Root&gt;

  &lt;AlertDialog.Content /&gt;
&lt;/AlertDialog.Root&gt;
</code></pre>
<p>An issue arises here because <code>AlertDialog</code> is a composition of <code>Dialog</code> with additional functionality to meet <code>AlertDialog</code> requirements. This means <code>AlertDialog.Root</code> is also a <code>Dialog.Root</code>, so it provides both <code>DialogContext</code> and <code>AlertDialogContext</code>.</p>
<p>In this setup, the <code>AlertDialog.Trigger</code> (which is also a <code>Dialog.Trigger</code>) might retrieve the wrong context via <code>useContext(DialogContext)</code>, ending up with the context from <code>Dialog.Root</code> instead of <code>AlertDialog.Root</code>. As a result, clicking the <code>AlertDialog.Trigger</code> could toggle the <code>Dialog.Content</code> rather than behaving as intended.</p>
<h4 id="heading-scoped-context-solution">Scoped Context Solution</h4>
<p>To prevent such issues, Radix Primitives uses scoped context. Scoped context ensures that <code>AlertDialog.Trigger</code> only interacts with <code>AlertDialog</code> parts and does not accidentally retrieve context from a similarly composed component. This is achieved by creating a new context internally and passing it to the <code>Dialog</code> component through a custom prop, such as <code>__scopeDialog</code>. The <code>Dialog</code> component then uses this scoped context in its <code>useContext</code> calls, ensuring isolation.</p>
<p>Source code from radix ui github repo:</p>
<p><a target="_blank" href="https://github.com/radix-ui/primitives/blob/dae8ef4920b45f736e2574abf23676efab103645/packages/react/dialog/src/Dialog.tsx#L69">https://github.com/radix-ui/primitives/blob/dae8ef4920b45f736e2574abf23676efab103645/packages/react/dialog/src/Dialog.tsx#L69</a></p>
<h3 id="heading-heres-an-abstraction-of-how-scoped-contexts-work-in-radix-ui">Here’s an abstraction of how scoped contexts work in Radix UI:</h3>
<ol>
<li><p><strong>Scope Creation</strong>: A <code>createScope</code> utility generates a unique namespace for each component or compound component. This ensures that each set of contexts is isolated and doesn’t conflict with others.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">import</span> { createScope } <span class="hljs-keyword">from</span> <span class="hljs-string">'@radix-ui/react-context'</span>;

 <span class="hljs-keyword">const</span> [createDialogContext, useDialogScope] = createScope(<span class="hljs-string">'Dialog'</span>);
</code></pre>
</li>
<li><p><strong>Scoped Providers</strong>: When creating contexts, they are tied to the scope. This binds the provider and consumer to the same namespace.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">const</span> DialogContext = createDialogContext(<span class="hljs-string">'DialogContext'</span>);
</code></pre>
</li>
<li><p><strong>Consumer Isolation</strong>: Scoped hooks, like <code>useDialogScope</code>, ensure that consumers access only the context from their intended scope.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> useDialogContext = <span class="hljs-function">(<span class="hljs-params">scope</span>) =&gt;</span> useContext(DialogContext, useDialogScope(scope));
</code></pre>
</li>
</ol>
<h4 id="heading-benefits-of-scoped-context">Benefits of Scoped Context</h4>
<ul>
<li><p><strong>Context Collisions Prevention</strong>: By scoping contexts, components like <code>AlertDialog.Trigger</code> can always find their associated context (<code>AlertDialogContext</code>), even when nested inside other contexts.</p>
</li>
<li><p><strong>Flexible Composition</strong>: Scoped contexts enable flexible and safe composition of components, ensuring that interactions remain predictable.</p>
</li>
<li><p><strong>Reusability</strong>: Developers can reuse generic components (e.g., <code>Dialog.Trigger</code>) across different scopes without modifications.</p>
</li>
</ul>
<h4 id="heading-how-it-applies-to-the-example">How It Applies to the Example</h4>
<p>In your example:</p>
<ul>
<li><p>The <code>AlertDialog.Root</code> creates a scoped <code>AlertDialogContext</code> that encapsulates its state and interactions.</p>
</li>
<li><p>Nested <code>Dialog.Root</code> and <code>AlertDialog.Trigger</code> coexist without conflicts because each references its respective scoped context.</p>
</li>
<li><p>This design pattern is a key feature of Radix UI, ensuring that complex component hierarchies work seamlessly without unintended behavior.</p>
</li>
</ul>
<h4 id="heading-references">References:</h4>
<ol>
<li><p><a target="_blank" href="https://dev.to/romaintrotard/use-context-selector-demystified-4f8e">https://dev.to/romaintrotard/use-context-selector-demystified-4f8e</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/radix-ui/primitives">https://github.com/radix-ui/primitives</a></p>
</li>
<li><p><a target="_blank" href="https://react.dev/reference/react/createContext">https://react.dev/reference/react/createContext</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Top 10 Books on Design System that i Read last year]]></title><description><![CDATA[This blog would be helpful for UI/UX designers, product manager, product designers, frontend developers, if you have peer or friends in those roles do share the blog with them. Can be a good new year gift as well. Just saying 🥹!

Creating a Design S...]]></description><link>https://blog.coolhead.in/top-10-books-on-design-system-that-i-read-last-year</link><guid isPermaLink="true">https://blog.coolhead.in/top-10-books-on-design-system-that-i-read-last-year</guid><category><![CDATA[Design]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[design and architecture]]></category><category><![CDATA[design system]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[UI]]></category><category><![CDATA[UX]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sat, 14 Dec 2024 05:45:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734155053525/168abd59-600e-42d1-91ca-c0afd69d880f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>This blog would be helpful for UI/UX designers, product manager, product designers, frontend developers, if you have peer or friends in those roles do share the blog with them. Can be a good <strong>new year gift</strong> as well. Just saying 🥹!</p>
</blockquote>
<h2 id="heading-creating-a-design-system-the-why-book"><strong>Creating a Design System - The Why Book</strong></h2>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-1044b2ab-0949-456c-8e84-7e9832fbdaa4.webp" alt /></p>
<p>Creating anything of great value requires a great purpose around it. Purpose exists in the problem space. If your purpose is to solve the problems of your stakeholders you must understand their problems better than them. And therefore you need new perspective lense. Reading this book would give you that lense and pattern to discovery user problems, you can then create a framework in your mind to solve the problems.</p>
<h3 id="heading-1-continuous-discovery-habits-by-teresa-torres"><strong>1. CONTINUOUS DISCOVERY HABITS - by Teresa Torres</strong></h3>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-a314c3ec-1ed2-4dc7-b09a-b15b3ebe7c82.webp" alt /></p>
<p>Recommended for Product Designers, Product manager, UX Designer much for then Frontend developers or UI Designers.</p>
<p>Few Notes from the book :</p>
<ul>
<li><p><strong>Begin With the End in Mind</strong></p>
</li>
<li><p><strong>Opportunity Solution Tree</strong></p>
</li>
<li><p><strong>Frame, refine, and prioritize the opportunity space</strong></p>
</li>
<li><p><strong>Prioritizing Opportunities, not solutions</strong></p>
</li>
<li><p><strong>Two way Door Decisions</strong></p>
</li>
<li><p><strong>Quantity Leads to Quality</strong></p>
</li>
<li><p><strong>Testing Assumption, Not Ideas</strong></p>
</li>
<li><p><strong>Measuring Impact</strong></p>
</li>
</ul>
<h3 id="heading-2-laying-the-foundations-by-andrew-couldwell"><strong>2. Laying the Foundations - by Andrew Couldwell</strong></h3>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-f1ff829d-f06b-433f-9014-12e53c879f17.webp" alt /></p>
<p>Design System 101</p>
<blockquote>
<p><strong>This book is real talk about creating design systems. No jargon, no glossing over the hard realities, and no company hat. Just good advice, experience, and practical tips.</strong></p>
</blockquote>
<p>Notes:</p>
<ul>
<li><p>How to Sell a design system at your company ?</p>
</li>
<li><p>Mission, values, and principles of a design System</p>
<p>  <img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-b8831979-6c16-4ad8-b492-d48f2ec2f1d1.webp" alt /></p>
</li>
<li><p>Much more learning from the book</p>
</li>
</ul>
<p>I would highly recommend the book to UI Designer, Product Designer, the book also focus more on practical tips, and setting up realistic expectations</p>
<h3 id="heading-3-thinking-in-systems-a-primer-by-donella-meadows"><strong>3. Thinking in Systems: A Primer - By Donella Meadows</strong></h3>
<p><strong>Thinking in Systems: A Primer</strong> by <strong>Donella Meadows</strong> is an insightful guide to understanding and working with complex systems.</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-d4946c61-8b71-495f-b2fe-c9dbe2083315.webp" alt /></p>
<p>Here's a brief summary of the book's key concepts:</p>
<ul>
<li><p>What is a System?</p>
</li>
<li><p>Stocks and Flows</p>
</li>
<li><p>Feedback Loops, Delays, Leverage Points</p>
</li>
<li><p>System Traps and Opportunities</p>
</li>
<li><p>Mental Models</p>
</li>
</ul>
<p>Recommended for Product Manager, Team Leads, or developers as well, anyone who like systems in general.</p>
<h3 id="heading-4-articulating-design-decisions"><strong>4. Articulating Design Decisions:</strong></h3>
<blockquote>
<p>Great Designers are great StoryTellers as well</p>
</blockquote>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-a8f3c3f2-30b9-486d-9a53-fc55511b20f1.webp" alt /></p>
<ul>
<li><p>Easy to Read,</p>
</li>
<li><p>Book is highly about communication, meeting, getting consensus, understand client needs or how to handle them.</p>
</li>
</ul>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-5d1c9705-d28c-4d2e-b8c9-2239a397f410.webp" alt /></p>
<ul>
<li>Some of the advice may be highly general, but give a good context.</li>
</ul>
<p>Recommended for Designers, Product Designer, Freelancers.</p>
<h2 id="heading-designing-design-system-the-what-books"><strong>Designing Design System - The What Books</strong></h2>
<p>What and who to Design for, Do you understand the domain, Do you know the Design foundations even ?</p>
<h3 id="heading-1-design-systems-by-alia-kholmatova"><strong>1. Design Systems - By Alia Kholmatova</strong></h3>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-e36cb453-ebac-407b-810b-bf26662fbbaf.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>I found the book highly visually appealing, very structured, and filled with example</p>
</li>
<li><p>Book give you everything, pattern, principles, structure as to how to start creating Design System</p>
</li>
<li><p>The Books is quite short, have a number of reference after every chapter.</p>
</li>
</ul>
<p>Recommended for Designers, Developers, and Product Managers as well. I quite like the book,i am a bit biased.</p>
<h3 id="heading-2-design-school-type"><strong>2. Design School - Type</strong></h3>
<p><strong>The Book</strong> is a practical and visually engaging guide that delves into the fundamentals of typography and its application in design.</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-42841b98-dbf6-4e97-a857-233ff8a59302.webp" alt /></p>
<p>Here's a concise summary of the book's key takeaways:</p>
<ul>
<li><p>Typography Basics</p>
</li>
<li><p>Type Hierarchy</p>
</li>
<li><p>okay i like the aesthetics of the book</p>
</li>
<li><p>Typography in Layouts and Grids</p>
</li>
<li><p>Typographic Principles</p>
</li>
<li><p>Just Read the Book it's great</p>
</li>
</ul>
<p>Recommended for Designers, Product Designer.</p>
<h3 id="heading-3-design-school-layout"><strong>3. Design School - Layout</strong></h3>
<p>Yup I read this first, and then I read the type one. i like the aesthetics of this books</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-a1ce2397-6fd6-42bb-805d-0f5a7d595d17.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>Layout Fundamentals</p>
</li>
<li><p>Grids, Grid System,</p>
</li>
<li><p>Layout Composition</p>
</li>
<li><p>Terminologies</p>
</li>
<li><p>Book also have a test your knowledge section at the end of each chapter. Nice!</p>
</li>
</ul>
<blockquote>
<p>I was really bad with layout understanding, and grids as a developer. This book helped me with that, now i love grids. Good tutorial for css <a target="_blank" href="https://www.joshwcomeau.com/css/interactive-guide-to-grid/">Grid</a></p>
</blockquote>
<h2 id="heading-building-design-system-the-how-books"><strong>Building Design System - The How Books</strong></h2>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-b9d1d4ba-65b5-45ae-bcfd-10d7283c93ad.webp" alt /></p>
<p>Creating a cohesive and effective design system is no small feat—it requires a deep understanding of design principles, organization, and collaboration.</p>
<h3 id="heading-1-frontend-architecture-for-design-systems"><strong>1. Frontend Architecture for Design Systems</strong></h3>
<p>Recommended for Developer, Design Engineers, Team lead, Product Manager</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-bc41ace2-b56c-410a-ac5a-e68b5ac83af3.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>the Book is quite old now, published in pre tailwind era (2016)</p>
</li>
<li><p>Css Approaches mentioned are good</p>
</li>
<li><p>a wholesome book, filled with real life example</p>
</li>
<li><p>Best learning was the way of break down of design into design system at Red hat .com</p>
</li>
<li><p>As we say basics remain the same, this books will be great refresher on them. code examples are quite outdated.</p>
</li>
</ul>
<h3 id="heading-2-design-system-for-developers-by-michael-mangialardi"><strong>2. Design System for Developers - By Michael Mangialardi</strong></h3>
<p>Recommended for Developer, Design Engineers, It's like a hands on tutorial on creating Design System.</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-265412b2-71fc-4b4f-b62a-9af5ca54a3a3.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>Learn how to code design systems that scale</p>
</li>
<li><p>Best Hands on guide on Design System for Developers.</p>
</li>
<li><p>Goes in depth with Naming, creating, developing Design Tokens</p>
</li>
<li><p>Learn Style-dictionary</p>
</li>
<li><p>Tailwind example</p>
</li>
</ul>
<h3 id="heading-3-building-design-systems-by-sarrah-vesselov-and-taurie-davis"><strong>3. Building Design Systems - by Sarrah Vesselov and Taurie Davis</strong></h3>
<p>Recommended for Designers, Developers, Product Managers, Product Designers. Loved the perspective of Sarrah and Taurie.</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-9edfcc44-5bbf-4488-9f30-b952135f6882.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>Creating a Typographic System</p>
</li>
<li><p>An Accessible Color System</p>
</li>
<li><p>The Case study of Gitlab is great</p>
</li>
<li><p>Gives you primers on Open sourcing your Design System</p>
</li>
<li><p>Loved the Concept of <strong>Shared Design Language</strong></p>
</li>
</ul>
<h3 id="heading-4-practical-web-inclusion-and-accessibility-ashley-firth"><strong>4. Practical Web Inclusion and Accessibility - Ashley Firth</strong></h3>
<p>Recommended for Designers, Developers, QA, PM, Product Designers.</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-3a7ea6b7-b26a-464c-a053-7c52ba8831ba.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>Chapter are based on Disabilities and how to</p>
</li>
<li><p>Learn Aria</p>
</li>
<li><p>Keyboard Accessibility</p>
</li>
<li><p>Intro to Screen Reader Softwares, Browser build-in ones</p>
</li>
<li><p>After each chapter there are a number of reference, so that you can learn in depth about the same</p>
</li>
<li><p>styling cue in audio and video tags, didn't know that</p>
</li>
</ul>
<blockquote>
<p>An extensive guide on how to style for RTL in CSS<br /><a target="_blank" href="https://rtlstyling.com/posts/rtl-styling">https://rtlstyling.com/posts/rtl-styling</a></p>
</blockquote>
<h3 id="heading-5-inclusive-design-patterns-by-heydon-pickering"><strong>5. Inclusive Design Patterns - By Heydon Pickering</strong></h3>
<p>Recommended for Developers, QA, PM, Product Designers.</p>
<p><img src="https://dqy38fnwh4fqs.cloudfront.net/UHOKQDAKLK7KQDOH7B6RJQKG7BAB/blog/blog-content-image-2d3e545c-1672-47e2-832b-b06d99ee04d4.webp" alt /></p>
<p>Notes:</p>
<ul>
<li><p>Filled with code example for accessibility</p>
</li>
<li><p>Schematic HTML is explained well</p>
</li>
<li><p>Using readability checker</p>
</li>
<li><p>Some of the tips are highly practical</p>
</li>
<li><p>Explains the bad practise and how to solve them</p>
</li>
<li><p>Every chapter has things to avoid</p>
</li>
<li><p>Testing for accessibility</p>
</li>
</ul>
<blockquote>
<p>Perks of reading the whole article, or scrolling. If you need any of the book pdf files, do dm me. I will share them with you.</p>
</blockquote>
<p>Want to discuss more on Design systems ? <a target="_blank" href="https://cal.com/biomathcode">https://cal.com/biomathcode</a></p>
]]></content:encoded></item><item><title><![CDATA[Explained: Symbol in Javascript with examples]]></title><description><![CDATA[Symbol is a built-in object whose constructor returns a symbol primitive — also called a Symbol value or just a Symbol — that's guaranteed to be unique. Symbols are often used to add unique property keys to an object that won't collide with keys any ...]]></description><link>https://blog.coolhead.in/explained-symbol-in-javascript-with-examples</link><guid isPermaLink="true">https://blog.coolhead.in/explained-symbol-in-javascript-with-examples</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sat, 30 Nov 2024 06:35:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732948461520/e244b573-5d2a-4739-aed2-343667cab69c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><code>Symbol</code> is a built-in object whose constructor returns a <code>symbol</code> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">primitive</a> — also called a <strong>Symbol value</strong> or just a <strong>Symbol</strong> — that's guaranteed to be unique. Symbols are often used to add unique property keys to an object that won't collide with keys any other code might add to the object, and which are hidden from any mechanisms other code will typically use to access the object. That enables a form of weak <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Encapsulation">encapsulation</a>, or a weak form of <a target="_blank" href="https://en.wikipedia.org/wiki/Information_hiding">information hiding</a>.</p>
<h3 id="heading-example-using-symbol-as-unique-property-keys">Example: Using <code>Symbol</code> as Unique Property Keys</h3>
<pre><code class="lang-jsx">javascript
Copy code
<span class="hljs-comment">// Create unique symbols</span>
<span class="hljs-keyword">const</span> id = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'id'</span>);
<span class="hljs-keyword">const</span> name = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'name'</span>);

<span class="hljs-comment">// Create an object with symbol-based properties</span>
<span class="hljs-keyword">const</span> user = {
    [id]: <span class="hljs-number">101</span>,
    [name]: <span class="hljs-string">'Alice'</span>,
    <span class="hljs-attr">age</span>: <span class="hljs-number">25</span>
};

<span class="hljs-comment">// Access the symbol properties</span>
<span class="hljs-built_in">console</span>.log(user[id]); <span class="hljs-comment">// 101</span>
<span class="hljs-built_in">console</span>.log(user[name]); <span class="hljs-comment">// "Alice"</span>

<span class="hljs-comment">// Add another property using a symbol</span>
<span class="hljs-keyword">const</span> email = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'email'</span>);
user[email] = <span class="hljs-string">'alice@example.com'</span>;

<span class="hljs-built_in">console</span>.log(user[email]); <span class="hljs-comment">// "alice@example.com"</span>

<span class="hljs-comment">// Symbols are not enumerable in for...in loops or Object.keys</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">in</span> user) {
    <span class="hljs-built_in">console</span>.log(key); <span class="hljs-comment">// Only "age" is logged</span>
}

<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.keys(user)); <span class="hljs-comment">// ["age"]</span>

<span class="hljs-comment">// You can still access all properties if you know the symbol keys</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.getOwnPropertySymbols(user)); <span class="hljs-comment">// [Symbol(id), Symbol(name), Symbol(email)]</span>
</code></pre>
<hr />
<h3 id="heading-example-using-symboliterator-to-make-an-object-iterable">Example: Using <code>Symbol.iterator</code> to Make an Object Iterable</h3>
<pre><code class="lang-jsx">javascript
Copy code
<span class="hljs-keyword">const</span> collection = {
    <span class="hljs-attr">items</span>: [<span class="hljs-string">'apple'</span>, <span class="hljs-string">'banana'</span>, <span class="hljs-string">'cherry'</span>],
    [<span class="hljs-built_in">Symbol</span>.iterator]() {
        <span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">const</span> items = <span class="hljs-built_in">this</span>.items;
        <span class="hljs-keyword">return</span> {
            next() {
                <span class="hljs-keyword">if</span> (index &lt; items.length) {
                    <span class="hljs-keyword">return</span> { <span class="hljs-attr">value</span>: items[index++], <span class="hljs-attr">done</span>: <span class="hljs-literal">false</span> };
                } <span class="hljs-keyword">else</span> {
                    <span class="hljs-keyword">return</span> { <span class="hljs-attr">done</span>: <span class="hljs-literal">true</span> };
                }
            }
        };
    }
};

<span class="hljs-comment">// Iterate over the object</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> item <span class="hljs-keyword">of</span> collection) {
    <span class="hljs-built_in">console</span>.log(item);
}
<span class="hljs-comment">// Output:</span>
<span class="hljs-comment">// apple</span>
<span class="hljs-comment">// banana</span>
<span class="hljs-comment">// cherry</span>
</code></pre>
<p>This example shows how <code>Symbol.iterator</code> allows a custom object to be iterated using <code>for...of</code>.</p>
<h3 id="heading-symbols-usable-in-popular-npm-library">Symbols usable in popular npm library :</h3>
<p><strong>Example: Using</strong> <code>Symbol</code> in a Popular npm Library</p>
<p>A notable example of <code>Symbol</code> usage is in the <a target="_blank" href="https://github.com/expressjs/express">Express.js</a> framework, a widely used web application framework for Node.js. In Express.js, <code>Symbol</code> is employed to define unique property keys, preventing potential conflicts with user-defined properties.</p>
<p><strong>Code Snippet from Express.js:</strong></p>
<pre><code class="lang-jsx">javascript
Copy code
<span class="hljs-comment">// In Express.js, a symbol is used to define a unique property key</span>
<span class="hljs-keyword">const</span> app = express();
app[<span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'router'</span>)] = router;
</code></pre>
<p>In this snippet, <code>Symbol('router')</code> creates a unique symbol that serves as a property key for the <code>app</code> object. This approach ensures that the <code>router</code> property is distinct and does not interfere with other properties that might be added to the <code>app</code> object.</p>
<p><strong>Benefits of Using</strong> <code>Symbol</code> in Libraries:</p>
<ul>
<li><p><strong>Uniqueness:</strong> Symbols guarantee that property keys are unique, reducing the risk of accidental overwrites.</p>
</li>
<li><p><strong>Immutability:</strong> Once created, symbols cannot be changed, providing a stable identifier.</p>
</li>
<li><p><strong>Non-enumerability:</strong> Properties keyed by symbols are not enumerable in loops, which can be beneficial for internal properties that should not be exposed.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mixins in typescript]]></title><description><![CDATA[A mixin is an abstract subclass; i.e. a subclass definition that may be applied to different superclasses to create a related family of modified classes.
Gilad Bracha and William Cook,  Mixin-based Inheritance


mixin definition: The definition of a ...]]></description><link>https://blog.coolhead.in/mixins-in-typescript</link><guid isPermaLink="true">https://blog.coolhead.in/mixins-in-typescript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Sat, 30 Nov 2024 06:27:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732947974801/64ca5863-1168-444a-90cb-e8a6a86e1a48.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>A mixin is an abstract subclass; i.e. a subclass definition that may be applied to different superclasses to create a related family of modified classes.</em></p>
<p><em><cite>Gilad Bracha and William Cook, </cite></em> <a target="_blank" href="http://www.bracha.org/oopsla90.pdf"><em><cite>Mixin-based Inheritance</cite></em></a></p>
</blockquote>
<ul>
<li><p><em>mixin definition</em>: The definition of a class that may be applied to different superclasses.</p>
</li>
<li><p><em>mixin application</em>: The application of a mixin definition to a specific superclass, producing a new subclass.</p>
</li>
</ul>
<p>Mixin libraries like <a target="_blank" href="https://github.com/onsi/cocktail">Cocktail, traits</a><a target="_blank" href="http://soft.vub.ac.be/~tvcutsem/traitsjs/">.js, and pat</a>terns described in many blog posts (like one of the latest to hit Hacker News: <a target="_blank" href="http://raganwald.com/2015/06/26/decorators-in-es7.html">Using ES7 Decorators as Mixins), generally work by modifying</a> objects in place, copying in properties from mixin objects and overwriting existing properties.</p>
<p>This is often implemented via <a target="_blank" href="https://github.com/onsi/cocktail">a funct</a>ion <a target="_blank" href="http://soft.vub.ac.be/~tvcutsem/traitsjs/">similar</a> to this:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mixin</span>(<span class="hljs-params">source, target</span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> prop <span class="hljs-keyword">in</span> source) {
    <span class="hljs-keyword">if</span> (source.hasOwnProperty(prop)) {
      target[prop] = source[prop];
    }
  }
}
</code></pre>
<p>A version of this has even made it into JavaScript as <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign">Object.assign</a>.</p>
<p><code>mixin()</code> is usually then called on a prototype:</p>
<pre><code class="lang-js">mixin(MyMixin, MyClass.prototype);
</code></pre>
<p>and now <code>MyClass</code> has all the properties defined in <code>MyMixin</code>.</p>
<p>functors: function which creates a function</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">myloggerFunction</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">str</span>) =&gt;</span> {<span class="hljs-built_in">console</span>.log(str)}
}

<span class="hljs-keyword">const</span> logger1 = myloggerFunction();

logger1(<span class="hljs-string">'hello'</span>);
</code></pre>
<p>functions that creates class</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">myloggerFunction</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyLoggerClass</span>() </span>{
        private 
    }
}
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">myLogFunction</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">str: string</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(str);
  };
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">myLoggerClass</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> (<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Logger</span> </span>{
    private completeLog: string = <span class="hljs-string">""</span>;
    log(str: string) {
      <span class="hljs-built_in">console</span>.log(str);
      <span class="hljs-built_in">this</span>.completeLog += <span class="hljs-string">`<span class="hljs-subst">${str}</span>\n`</span>;
    }
    dumpLog() {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.completeLog;
    }
  })();
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SimpleMemoryDatabase</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SimpleMemoryDatabase</span> </span>{
    private db: Record&lt;string, T&gt; = {};

    set(id: string, <span class="hljs-attr">value</span>: T): <span class="hljs-keyword">void</span> {
      <span class="hljs-built_in">this</span>.db[id] = value;
    }

    get(id: string): T {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.db[id];
    }

    getObject(): Record&lt;string, T&gt; {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.db;
    }
  };
}

<span class="hljs-keyword">const</span> StringDatabase = SimpleMemoryDatabase&lt;string&gt;();

<span class="hljs-keyword">const</span> sdb1 = <span class="hljs-keyword">new</span> StringDatabase();
sdb1.set(<span class="hljs-string">"name"</span>, <span class="hljs-string">"Jack"</span>);
<span class="hljs-built_in">console</span>.log(sdb1.get(<span class="hljs-string">"name"</span>));

type Constructor&lt;T&gt; = <span class="hljs-keyword">new</span> (...args: any[]) =&gt; T;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Dumpable</span>&lt;
  <span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">Constructor</span>&lt;</span>{
    getObject(): object;
  }&gt;
&gt;(Base: T) {
  <span class="hljs-keyword">return</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dumpable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span> </span>{
    dump() {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.getObject());
    }
  };
}

<span class="hljs-keyword">const</span> DumpableStringDatabase = Dumpable(StringDatabase);
<span class="hljs-keyword">const</span> sdb2 = <span class="hljs-keyword">new</span> DumpableStringDatabase();
sdb2.set(<span class="hljs-string">"name"</span>, <span class="hljs-string">"Jack"</span>);
sdb2.dump();
</code></pre>
<p>[A mixin is] a function that</p>
<ol>
<li><p>takes a constructor,</p>
</li>
<li><p>creates a class that extends that constructor with new functionality</p>
</li>
<li><p>returns the new class</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-comment">// Needed for all mixins</span>
type Constructor&lt;T = {}&gt; = <span class="hljs-keyword">new</span> (...args: any[]) =&gt; T;

<span class="hljs-comment">////////////////////</span>
<span class="hljs-comment">// Example mixins</span>
<span class="hljs-comment">////////////////////</span>

<span class="hljs-comment">// A mixin that adds a property</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Timestamped</span>&lt;<span class="hljs-title">TBase</span> <span class="hljs-title">extends</span> <span class="hljs-title">Constructor</span>&gt;(<span class="hljs-params">Base: TBase</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span> </span>{
    timestamp = <span class="hljs-built_in">Date</span>.now();
  };
}

<span class="hljs-comment">// a mixin that adds a property and methods</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Activatable</span>&lt;<span class="hljs-title">TBase</span> <span class="hljs-title">extends</span> <span class="hljs-title">Constructor</span>&gt;(<span class="hljs-params">Base: TBase</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span> </span>{
    isActivated = <span class="hljs-literal">false</span>;

    activate() {
      <span class="hljs-built_in">this</span>.isActivated = <span class="hljs-literal">true</span>;
    }

    deactivate() {
      <span class="hljs-built_in">this</span>.isActivated = <span class="hljs-literal">false</span>;
    }
  };
}

<span class="hljs-comment">////////////////////</span>
<span class="hljs-comment">// Usage to compose classes</span>
<span class="hljs-comment">////////////////////</span>

<span class="hljs-comment">// Simple class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
  name = <span class="hljs-string">''</span>;
}

<span class="hljs-comment">// User that is Timestamped</span>
<span class="hljs-keyword">const</span> TimestampedUser = Timestamped(User);

<span class="hljs-comment">// User that is Timestamped and Activatable</span>
<span class="hljs-keyword">const</span> TimestampedActivatableUser = Timestamped(Activatable(User));

<span class="hljs-comment">////////////////////</span>
<span class="hljs-comment">// Using the composed classes</span>
<span class="hljs-comment">////////////////////</span>

<span class="hljs-keyword">const</span> timestampedUserExample = <span class="hljs-keyword">new</span> TimestampedUser();
<span class="hljs-built_in">console</span>.log(timestampedUserExample.timestamp);

<span class="hljs-keyword">const</span> timestampedActivatableUserExample = <span class="hljs-keyword">new</span> TimestampedActivatableUser();
<span class="hljs-built_in">console</span>.log(timestampedActivatableUserExample.timestamp);
<span class="hljs-built_in">console</span>.log(timestampedActivatableUserExample.isActivated);
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// Define a simple class with a greet method</span>
<span class="hljs-keyword">class</span> Greeter {
  greet(name: <span class="hljs-built_in">string</span>) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>!`</span>);
  }
}

<span class="hljs-comment">// Define a mixin that adds a log method to a class</span>
<span class="hljs-keyword">type</span> Loggable = { log(message: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">void</span> };

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withLogging</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">new</span> (<span class="hljs-params">...args: <span class="hljs-built_in">any</span>[]</span>) =&gt; <span class="hljs-title">Loggable</span>&gt;(<span class="hljs-params">Base: T</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">class</span> <span class="hljs-keyword">extends</span> Base {
    log(message: <span class="hljs-built_in">string</span>) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString()}</span>] <span class="hljs-subst">${message}</span>`</span>);
    }
  };
}

<span class="hljs-comment">// Create a new class that combines the Greeter and Loggable mixins</span>
<span class="hljs-keyword">const</span> MyGreeter = withLogging(Greeter);

<span class="hljs-comment">// Use the new class to create an instance and call its methods</span>
<span class="hljs-keyword">const</span> greeter = <span class="hljs-keyword">new</span> MyGreeter();
greeter.greet(<span class="hljs-string">"Alice"</span>); <span class="hljs-comment">// Output: "Hello, Alice!"</span>
greeter.log(<span class="hljs-string">"An event occurred."</span>); <span class="hljs-comment">// Output: "[2023-04-04T12:00:00.000Z] An event occurred."</span>
</code></pre>
<p>This is just the beginning of many topics related to mixins in JavaScript. I'll post more about things like:</p>
<ul>
<li><p><a target="_blank" href="http://justinfagnani.com/2016/01/07/enhancing-mixins-with-decorator-functions/">Enhancing Mixins with Decorator Functions</a> new post that covers:</p>
</li>
<li><p>Caching mixin applications so that the same mixin applied to the same superclass reuses a prototype.</p>
</li>
<li><p>Getting <code>instanceof</code> to work.</p>
</li>
<li><p>How mixin inheritance can address the fear that ES6 classes and classical inheritance are bad for JavaScript.</p>
</li>
<li><p>Using subclass-factory-style mixins in ES5.</p>
</li>
<li><p>De-duplicating mixins so mixin composition is more usable.</p>
</li>
</ul>
<h3 id="heading-references">References:</h3>
<p><a target="_blank" href="https://bryntum.com/blog/the-mixin-pattern-in-typescript-all-you-need-to-know/">https://bryntum.com/blog/the-mixin-pattern-in-typescript-all-you-need-to-know/</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=LvjNGo5ALyQ">https://www.youtube.com/watch?v=LvjNGo5ALyQ</a></div>
<p> </p>
<p><a target="_blank" href="https://medium.com/@saif.adnan/typescript-mixin-ee962be3224d">https://medium.com/@saif.adnan/typescript-mixin-ee962be3224d</a></p>
<p><a target="_blank" href="https://egghead.io/lessons/typescript-use-the-optional-chaining-operator-in-typescript">https://egghead.io/lessons/typescript-use-the-optional-chaining-operator-in-typescript</a></p>
<p><a target="_blank" href="https://javascript.info/mixins">https://javascript.info/mixins</a></p>
]]></content:encoded></item><item><title><![CDATA[Mental Model For Typescript's Type System]]></title><description><![CDATA[This article is based on my learning from the book Effective Typescript by Dan Vanderkam

Think of TypeScript’s type system as a "domain for JavaScript." It's a layer that adds structure and safety to JavaScript, which is inherently dynamic and loose...]]></description><link>https://blog.coolhead.in/mental-model-for-typescripts-type-system</link><guid isPermaLink="true">https://blog.coolhead.in/mental-model-for-typescripts-type-system</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Pratik Sharma]]></dc:creator><pubDate>Mon, 09 Sep 2024 11:52:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725882341279/319831ce-b555-4548-91e4-60a70022fc55.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>This article is based on my learning from the book Effective Typescript by Dan Vanderkam</p>
</blockquote>
<p>Think of TypeScript’s type system as a "domain for JavaScript." It's a layer that adds structure and safety to JavaScript, which is inherently dynamic and loosely typed. Understanding how TypeScript works helps you write safer, more predictable code. Let's break down some key concepts that will help you form a solid mental model for TypeScript.</p>
<h4 id="heading-1-types-vs-values-in-typescript">1. Types vs. Values in TypeScript</h4>
<p>A common source of confusion is the difference between the <strong>type space</strong> and the <strong>value space</strong> in TypeScript:</p>
<ul>
<li><p><strong>Type Space</strong>: This is where TypeScript defines types like <code>number</code>, <code>string</code>, <code>boolean</code>, <code>Array&lt;T&gt;</code>, and user-defined types like <code>interfaces</code> or <code>types</code>.</p>
</li>
<li><p><strong>Value Space</strong>: This is the actual JavaScript runtime where values like <code>5</code>, <code>'hello'</code>, or <code>['item1', 'item2']</code> exist.</p>
</li>
</ul>
<p>Understanding this separation is crucial because TypeScript types exist only during development (at compile-time) and are erased in the compiled JavaScript output.</p>
<h4 id="heading-2-interface-vs-type">2. Interface vs. Type</h4>
<p>While both <code>interface</code> and <code>type</code> can be used to define object shapes, there are subtle differences:</p>
<ul>
<li><p><strong>Interface</strong>: Best used when you need to define the shape of an object and can extend other interfaces. It's more suited for object-oriented programming models.</p>
<pre><code class="lang-typescript">  typescriptCopy codeinterface Person {
    name: <span class="hljs-built_in">string</span>;
    age: <span class="hljs-built_in">number</span>;
  }
</code></pre>
</li>
<li><p><strong>Type</strong>: More flexible and can be used to define unions, intersections, tuples, or primitives. Use it for more complex or conditional types.</p>
<pre><code class="lang-typescript">  typescriptCopy codetype Point = { x: <span class="hljs-built_in">number</span>; y: <span class="hljs-built_in">number</span> };
  <span class="hljs-keyword">type</span> StringOrNumber = <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>;
</code></pre>
</li>
</ul>
<h4 id="heading-3-type-declarations-vs-type-assertions">3. Type Declarations vs. Type Assertions</h4>
<ul>
<li><p><strong>Type Declarations</strong>: You declare the type of a variable or function parameter. Type declarations enable TypeScript's type-checking capabilities and help catch errors early.</p>
<pre><code class="lang-typescript">  typescriptCopy codeconst age: <span class="hljs-built_in">number</span> = <span class="hljs-number">25</span>;
</code></pre>
</li>
<li><p><strong>Type Assertions</strong>: Use when you know more about a value than TypeScript does, and you want to override TypeScript's type inference. Use assertions sparingly, as they can lead to unsafe code.</p>
<pre><code class="lang-typescript">  typescriptCopy codeconst input = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'username'</span>) <span class="hljs-keyword">as</span> HTMLInputElement;
  input.value = <span class="hljs-string">'TypeScript'</span>;
</code></pre>
</li>
</ul>
<h4 id="heading-4-type-checking-and-primitives">4. Type Checking and Primitives</h4>
<p>JavaScript has several primitive types (like <code>string</code>, <code>number</code>, <code>boolean</code>) and their <strong>object wrappers</strong> (<code>String</code>, <code>Number</code>, <code>Boolean</code>). TypeScript recognizes both but focuses on the primitive versions for type checking.</p>
<ul>
<li><strong>TypeScript Primitives</strong>: Types like <code>string</code>, <code>number</code>, and <code>boolean</code> are key to defining most TypeScript code.</li>
</ul>
<h4 id="heading-5-type-checking-does-not-happen-at-runtime">5. Type Checking Does Not Happen at Runtime</h4>
<p>TypeScript is a <em>static</em> type checker; it does not enforce types at runtime. If you want to ensure runtime safety, you need to write runtime checks yourself.</p>
<h4 id="heading-6-type-assertions-and-type-declarations">6. Type Assertions and Type Declarations</h4>
<p>Prefer <strong>type declarations</strong> over <strong>type assertions</strong> because declarations provide TypeScript with more information, helping it catch more errors. For example, this code avoids a common mistake:</p>
<pre><code class="lang-typescript">typescriptCopy codeconst user = { name: <span class="hljs-string">"Alice"</span>, age: <span class="hljs-number">25</span> }; <span class="hljs-comment">// inferred type</span>
</code></pre>
<p>versus:</p>
<pre><code class="lang-typescript">typescriptCopy codeconst user = { name: <span class="hljs-string">"Alice"</span>, age: <span class="hljs-number">25</span> } <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>; <span class="hljs-comment">// type assertion</span>
</code></pre>
<h4 id="heading-7-the-any-type">7. The "Any" Type</h4>
<p>Using <code>any</code> is like telling TypeScript to "turn off" type checking for a particular variable. It should be avoided wherever possible because it removes all the benefits TypeScript provides.</p>
<h4 id="heading-8-type-inference">8. Type Inference</h4>
<p>TypeScript can often infer the type of a variable or function return type:</p>
<pre><code class="lang-typescript">typescriptCopy codeconst x = <span class="hljs-number">12</span>; <span class="hljs-comment">// TypeScript infers that x is of type number</span>
</code></pre>
<p>However, type inference does not work well for function parameters:</p>
<pre><code class="lang-typescript">typescriptCopy codefunction greet(name: <span class="hljs-built_in">string</span>) {
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>`</span>;
}
</code></pre>
<p>Explicitly typing parameters is necessary for proper type safety.</p>
<h4 id="heading-9-excess-property-checking">9. Excess Property Checking</h4>
<p>By specifying types for objects, TypeScript checks if there are extra or missing properties, helping catch bugs:</p>
<pre><code class="lang-typescript">typescriptCopy codeconst user = { name: <span class="hljs-string">"Alice"</span>, age: <span class="hljs-number">30</span> };
<span class="hljs-keyword">const</span> person: { name: <span class="hljs-built_in">string</span>; age: <span class="hljs-built_in">number</span> } = user; <span class="hljs-comment">// OK</span>
</code></pre>
<h4 id="heading-10-widening-and-narrowing">10. Widening and Narrowing</h4>
<p>TypeScript uses <strong>widening</strong> and <strong>narrowing</strong> to infer more general or specific types.</p>
<ul>
<li><p><strong>Widening</strong>: When TypeScript expands a specific type to a more general one.</p>
<pre><code class="lang-typescript">  typescriptCopy codeconst x = <span class="hljs-number">1</span>; <span class="hljs-comment">// Type is inferred as number (widened)</span>
</code></pre>
</li>
<li><p><strong>Narrowing</strong>: When TypeScript reduces a broader type to a more specific one, based on control flow.</p>
<pre><code class="lang-typescript">  typescriptCopy codeconst el = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'foo'</span>);
  <span class="hljs-keyword">if</span> (el) {
    el.innerHTML = <span class="hljs-string">'Hello'</span>; <span class="hljs-comment">// Type is narrowed to HTMLElement</span>
  }
</code></pre>
</li>
</ul>
<h4 id="heading-11-type-guards">11. Type Guards</h4>
<p>You can define custom functions to help TypeScript narrow down types in complex scenarios:</p>
<pre><code class="lang-typescript">typescriptCopy codefunction isString(value: <span class="hljs-built_in">any</span>): value is <span class="hljs-built_in">string</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">'string'</span>;
}
</code></pre>
<h4 id="heading-12-contextual-typing">12. Contextual Typing</h4>
<p>Avoid separating a value from its context. For example:</p>
<pre><code class="lang-typescript">typescriptCopy codefunction panTo(where: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>]) {}
panTo([<span class="hljs-number">10</span>, <span class="hljs-number">20</span>]); <span class="hljs-comment">// OK</span>

<span class="hljs-keyword">const</span> loc = [<span class="hljs-number">10</span>, <span class="hljs-number">20</span>]; <span class="hljs-comment">// Bad, as the type context is lost</span>
</code></pre>
<p>Better:</p>
<pre><code class="lang-typescript">typescriptCopy codeconst loc: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>] = [<span class="hljs-number">10</span>, <span class="hljs-number">20</span>];
</code></pre>
<h4 id="heading-13-type-design-principles">13. Type Design Principles</h4>
<ul>
<li><p><strong>Be Liberal in What You Accept and Strict in What You Produce</strong>: Accept a broad range of inputs and produce specific outputs.</p>
</li>
<li><p><strong>Use the Narrowest Possible Scope for Types</strong>: The narrower your types, the more specific your functions and objects can be.</p>
</li>
</ul>
<h4 id="heading-14-version-management-for-type-declarations">14. Version Management for Type Declarations</h4>
<p>Understand that every package can have three versions to consider:</p>
<ul>
<li><p>The version of the package.</p>
</li>
<li><p>The version of its type declarations (e.g., <code>@types</code> package).</p>
</li>
<li><p>The version of TypeScript itself.</p>
</li>
</ul>
<h4 id="heading-15-use-tsdoc-for-api-comments">15. Use TSDoc for API Comments</h4>
<p>Document your code using TSDoc, the TypeScript standard for inline documentation.</p>
<pre><code class="lang-typescript">typescriptCopy code<span class="hljs-comment">/**
 * Generate a greeting.
 * @param name Name of the person to greet
 * @param title The person's title
 * @returns A greeting formatted for human consumption.
 */</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greetFullTSDoc</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, title: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hello <span class="hljs-subst">${title}</span> <span class="hljs-subst">${name}</span>`</span>;
}
</code></pre>
<h4 id="heading-16-provide-a-type-for-this-in-callbacks">16. Provide a Type for <code>this</code> in Callbacks</h4>
<p>Ensure you understand how <code>this</code> works and provide types for it in callbacks, especially when it's part of your API.</p>
<h4 id="heading-17-dom-types">17. DOM Types</h4>
<p>Know the differences between <code>Node</code>, <code>Element</code>, <code>HTMLElement</code>, and <code>EventTarget</code>. Use the most specific type possible to prevent errors.</p>
<h4 id="heading-18-debugging-typescript">18. Debugging TypeScript</h4>
<p>Use source maps to debug your TypeScript code, ensuring you can trace errors back to your TypeScript code rather than the compiled JavaScript.</p>
]]></content:encoded></item></channel></rss>