{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Spiralstack",
  "home_page_url": "https://spiralstack.com/",
  "feed_url": "https://spiralstack.com/feeds/json",
  "authors": [
    {
      "name": "spiralstack",
      "avatar": "https://spiralstack.com/build/_assets/logo-512-LOD6LFU2.png"
    }
  ],
  "favicon": "https://spiralstack.com/build/_assets/logo-128-3RCJGPF7.png",
  "icon": "https://spiralstack.com/build/_assets/logo-512-LOD6LFU2.png",
  "language": "en",
  "items": [
    {
      "id": "https://spiralstack.com/notes/validate-schemas-and-declare-types-with-zod",
      "url": "https://spiralstack.com/notes/validate-schemas-and-declare-types-with-zod",
      "title": "Validate schemas and declare types with Zod",
      "content_html": "<div data-reactroot=\"\"><p>Zod is a Typescript package that lets you declare your data types and do runtime type checking.</p><p>Lots of possible utilities for this <a href=\"https://github.com/colinhacks/zod\">library</a>. Validation and <a href=\"https://spiralstack.com/articles/complex-type-guards-for-the-unknown\">type guards</a> come to mind first, but Zod also includes a lot of helpful methods such as <code>default</code> and <code>transform</code>.</p><h2>Quick example</h2><pre><code data-lang=\"typescript\">import { z } from &#x27;zod&#x27;\n\nconst Post = z.object({\n  id: z.string().uuid(),\n  title: z.string().min(1),\n  body: z.string()\n})\n\n// Declare the type\ntype Post = z.infer&lt;typeof Post&gt;\n\nconst myPost = {\n  id: &#x27;c2cffa40-8169-4e9b-bce4-af21bc17b033&#x27;,\n  title: &#x27;Validate schemas and declare types with Zod&#x27;,\n  body: &#x27;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&#x27;\n}\n\nPost.safeParse(myPost)\n\n// {\n//   success: true,\n//   data: {\n//     id: &#x27;c2cffa40-8169-4e9b-bce4-af21bc17b033&#x27;,\n//     title: &#x27;Validate schemas and declare types with Zod&#x27;,\n//     body: &#x27;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&#x27;\n//   }\n// }</code></pre><p></p><p></p></div>",
      "summary": "Zod is a Typescript package that lets you declare your data types and do runtime type checking.",
      "date_published": "2022-02-12T21:32:50.863Z",
      "date_modified": "2022-02-12T21:55:14.606Z",
      "tags": [
        "Typescript"
      ],
      "language": "en"
    },
    {
      "id": "https://spiralstack.com/notes/syntax-highlighting-asts",
      "url": "https://spiralstack.com/notes/syntax-highlighting-asts",
      "title": "Syntax highlighting ASTs",
      "content_html": "<div data-reactroot=\"\"><p>Useful libraries for coloring programming language syntax.</p><p><a href=\"https://github.com/wooorm/lowlight\">Lowlight</a> and <a href=\"https://github.com/wooorm/refractor\">Refractor</a> are two interesting libraries that wrap <a href=\"https://highlightjs.org/\">highlight.js</a> and <a href=\"https://prismjs.com/\">Prism</a> respectively. </p><p>From <a href=\"https://wooorm.com/\">Titus Wormer</a>:</p><blockquote><p>Virtual syntax highlighting for virtual DOMs and non-HTML things.</p></blockquote><p>Instead of returning a HTML string with <code>&lt;span&gt;</code>s and <code>class</code> names, it returns an array of objects that you can use to create HTML or anything else really. Super useful for creating React components without using something like <a href=\"https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml\"><code>dangerouslySetInnerHTML</code></a>.</p></div>",
      "summary": "Useful libraries for coloring programming language syntax.",
      "date_published": "2022-01-28T22:24:07.663Z",
      "date_modified": "2022-01-28T22:46:00.477Z",
      "tags": [
        "React"
      ],
      "language": "en"
    },
    {
      "id": "https://spiralstack.com/articles/complex-type-guards-for-the-unknown",
      "url": "https://spiralstack.com/articles/complex-type-guards-for-the-unknown",
      "title": "Complex type guards for the unknown",
      "content_html": "<div data-reactroot=\"\"><p>In any Typescript project you will inevitably end up working with an unknown data type that you need to know its correct type to proceed with confidence. One strategy for ensuring type correctness is with type guards.</p><h2>What are type guards?</h2><p>According to the <a href=\"https://www.typescriptlang.org/docs/\">Typescript docs</a>:</p><blockquote><p>A type guard is some expression that performs a runtime check that guarantees the type in some scope.</p></blockquote><p>In practice, a type guard is simply a function that accepts some value as an argument and returns a boolean. The function also has a special return type in this format: <code>value is SomeType</code>. If the function returns true, then the value passed in is the type <code>SomeType</code>. If the function returns false, then it’s not. This is especially useful for narrowing a union type or validating data returned from an API.</p><h2>Basic building blocks</h2><p>Some basic type guards can make any project more readable and reduce duplicated code. Starting with a few native JavaScript data types we can have the building block type guards for more complex types. </p><p>The following are type guard examples for the most basic and common data types: <code>array, boolean, null, number, object, string, undefined</code>.</p><pre><code data-lang=\"typescript\">function isArray(value: unknown): value is Array&lt;unknown&gt; {\n  return Array.isArray(value)\n}\n\nfunction isBoolean(value: unknown): value is boolean {\n  return typeof value === &#x27;boolean&#x27;\n}\n\nfunction isNull(value: unknown): value is null {\n  return value === null\n}\n\nfunction isNumber(value: unknown): value is number {\n  return typeof value === &#x27;number&#x27;\n}\n\nfunction isObject(value: unknown): value is Record&lt;string, unknown&gt; {\n  return typeof value === &#x27;object&#x27; &amp;&amp; !Array.isArray(value) &amp;&amp; value !== null\n}\n\nfunction isString(value: unknown): value is string {\n  return typeof value === &#x27;string&#x27;\n}\n\nfunction isUndefined(value: unknown): value is undefined {\n  return typeof value === &#x27;undefined&#x27;\n}</code></pre><p>These basic type guards are super helpful in variety of use cases — notably when discerning an optional type while also improving readability. The first statement uses a reusable type guard and is easier to read.</p><pre><code data-lang=\"typescript\">if (isUndefined(foo)) {\n  // Do something\n} else {\n  // Do something else\n}\n\n// versus\n\nif (typeof foo === &#x27;undefined&#x27;) {\n  // Do something\n} else {\n  // Do something else\n}</code></pre><h2>Layering complexity</h2><p>Consider the following nested type for a <code>Song</code>:</p><pre><code data-lang=\"typescript\">type Song = {\n  title: string\n  album: Album\n}\n\ntype Album = {\n  name: string\n  releaseDate: string\n  band: Band\n}\n\ntype Band = {\n  name: string\n  members: string[]\n  startYear: number\n  endYear: number | null\n}</code></pre><p>For example:</p><pre><code data-lang=\"typescript\">const song: Song = {\n  title: &#x27;Tomorrow Never Knows&#x27;,\n  album: {\n    name: &#x27;Revolver&#x27;,\n    releaseDate: &#x27;5 August 1966&#x27;,\n    band: {\n      name: &#x27;The Beatles&#x27;,\n      members: [\n        &#x27;John Lennon&#x27;,\n        &#x27;Paul McCartney&#x27;,\n        &#x27;George Harrison&#x27;,\n        &#x27;Ringo Starr&#x27;,\n      ],\n      startYear: 1960,\n      endYear: 1970\n    }\n  }\n}</code></pre><p>While we could write a single type guard to check this song object, it’s much easier to break up the object into its primary parts starting with the most deeply nested object. In this case, that’s the <code>members</code> array.</p><pre><code data-lang=\"typescript\">function isMembers(value: unknown): value is string[] {\n  if (!isArray(value)) {\n    return false\n  }\n\n  return value.every((item) =&gt; isString(item))\n}</code></pre><p>Now we have all the pieces to move up to the <code>Band</code> object by using our basic type guards along with our <code>isMembers</code> type guard. </p><pre><code data-lang=\"typescript\">function isBand(value: unknown): value is Band {\n  if (!isObject(value)) {\n    return false\n  }\n\n  return (\n    isString(value.name) &amp;&amp;\n    isMembers(value.members) &amp;&amp;\n    isNumber(value.startYear) &amp;&amp;\n    (isNumber(value.endYear) || isNull(value.endYear))\n  )\n}</code></pre><p>Next, let’s move up to the <code>Album</code> object.</p><pre><code data-lang=\"typescript\">function isAlbum(value: unknown): value is Album {\n  if (!isObject(value)) {\n    return false\n  }\n\n  return (\n    isString(value.name) &amp;&amp; isString(value.releaseDate) &amp;&amp; isBand(value.band)\n  )\n}</code></pre><p>Finally, we can write our <code>Song</code> type guard. And it’s trivial to check for list of songs as well.</p><pre><code data-lang=\"typescript\">// Song type guard\nfunction isSong(value: unknown): value is Song {\n  if (!isObject(value)) {\n    return false\n  }\n\n  return isString(value.title) &amp;&amp; isAlbum(value.album)\n}\n\n// Song list type guard\nfunction isSongList(value: unknown): value is Song[] {\n  if (!isArray(value)) {\n    return false\n  }\n\n  return value.every((item) =&gt; isSong(item))\n}</code></pre><p>What&#x27;s great about this technique is that it is easy to reason about. They&#x27;re also easy to write tests for. Also, you never have to worry about the argument type since we just label that as <code>unknown</code> and you never have to cast  an object in order to read a property off of it.</p><h3>A note on very large objects</h3><p>This layering approach works well when objects aren&#x27;t too large. For larger and more complicated types, it might be a good idea to create a <a href=\"https://json-schema.org/\">JSON Schema</a> file and validate it in your type guard with a library like <a href=\"https://ajv.js.org/\">Ajv</a>.</p><p></p></div>",
      "summary": "In any Typescript project you will inevitably end up working with an unknown data type that you need to know its correct type to proceed with confidence. One strategy for ensuring type correctness is with type guards.",
      "date_published": "2022-01-19T03:34:12.736Z",
      "date_modified": "2022-01-19T03:34:12.736Z",
      "tags": [
        "Typescript"
      ],
      "language": "en"
    },
    {
      "id": "https://spiralstack.com/links/cdn-caching-static-site-generation-and-server-side-rendering",
      "url": "https://spiralstack.com/links/cdn-caching-static-site-generation-and-server-side-rendering",
      "external_url": "https://www.youtube.com/watch?v=bfLFHp7Sbkg",
      "title": "CDN Caching, Static Site Generation, and Server Side Rendering",
      "content_html": "<div data-reactroot=\"\"><p>Ryan Florence gives an excellent summary of different caching and build strategies for your website or app.</p><p>The most exciting aspect of this whole video is the <i>stale-while-revalidate</i> cache control header. This allows server side rendered sites the ability to always be served from a CDN (besides the very first request) similarly to static site generated pages. </p><p>Unfortunately, not many CDNs currently support this. Out of the large CDNs including CloudFront, Cloudflare, and Fastly, it seems that just <a href=\"https://docs.fastly.com/en/guides/serving-stale-content\">Fastly supports it fully</a>, while Cloudflare &quot;supports&quot; in a partial and imperfect way. Smaller networks like <a href=\"https://vercel.com/docs/concepts/edge-network/caching#stale-while-revalidate\">Vercel also support it</a>.</p><p><a href=\"https://spiralstack.com/links/cdn-caching-static-site-generation-and-server-side-rendering\">Permalink</a></p></div>",
      "summary": "Ryan Florence gives an excellent summary of different caching and build strategies for your website or app.",
      "date_published": "2022-01-16T06:43:33.106Z",
      "date_modified": "2022-01-16T06:43:33.106Z",
      "tags": [
        "CDN"
      ],
      "language": "en"
    }
  ]
}