Learning Svelte - Project 1: Dependency Resolution Tool
Tags: svelte, javascript, webdev, codesandbox
Published: 2020-10-20 07:00:42

I've binge-read the Svelte tutorials for the last few days and it's time to start writing some basic test projects to go beyond basic concepts.

I'll be posting progress and insights here as I go.

# About
I found a basic dependency resolution algorithm [Gist](https://gist.github.com/RubyTuesdayDONO/5006455) the other day and decided to use it as the basis for learning more about Svelte. Basically, an excuse to do something other than stay stuck in tutorial-mode.

[Graph theory](https://en.wikipedia.org/wiki/Graph_theory) lies at the heart so many modern development paradigms that I thought it would make an excellent [MacGuffin](https://en.wikipedia.org/wiki/MacGuffin).

![Graph theory in sociology: Moreno Sociogram (1953) - Wikipedia](https://upload.wikimedia.org/wikipedia/commons/b/b6/Moreno_Sociogram_2nd_Grade.png)

# Project Code
- [CodeSanbox](https://codesandbox.io/s/javascript-dependency-resolver-4ecv0?file=/App.svelte)
- [Github](https://github.com/devwax/dependency-resolution-with-js/tree/main/)

# Features / To Do
👍 Convert current plain JavaScript CodeSandbox to Svelte.
👍 Format the execution order with an ordered list.
👍 User editable dependency lists that update in realtime. (add/remove items in left column)
🔘 Auto color-coding of dependencies.
🔘 Hovering an item highlights its use elsewhere (bi-directional item highlighting for legibility)
🔘 Add infinite nested levels of dependencies.
🔘 Revise language... 'before', 'after', 'subscribers', 'items', etc.
🔘 Toggle real-time mode.
🔘 CodeMirror for the dependencies editor
🔘 Undo/redo changes.
🔘 Read a `package.json` or other dependency configuration and display its resolution. Upload or via URL / fetch.
🔘 Save to localStorage
🔘 Save state to json / file download
🔘 Authenticated users
🔘 Basic CRUD interface for user lists
🔘 Sharing dependency lists
🔘 Visualization of dependency graph
🔘 API - DRaaS (*Dependency Resolution as a Service*)

# Svelte Concepts to incorporate
- Reactivity
- Fetch, Async/Await
- Props
- Slots
- Binding
- Lifecycles
- Stores
- Motion and Transitions
- State management
  - Basic w/out library
  - XState
  - Overmind
- Authentication (oAuth 2.0)
  - [Firebase](https://codechips.me/firebase-authentication-with-xstate-and-svelte/) (w/ Cloudflare Workers KV)
- User storage
  - [Cloudflare Workers KV](https://www.cloudflare.com/products/workers-kv/)
  - Explore [Durable Objects](https://developers.cloudflare.com/workers/runtime-apis/durable-objects) as an option
  - Basic CRUD interface for dependency maps
- API

# Progress

## Oct 21, 2020
I turned the dependencies and execution order sections into Svelte components that update automatically on user input by adding a `resolution` store and auto-subscribing to it.

I'm planning on adding CodeMirror which I'm assuming would be best implemented with a Svelte module.

I found some old libraries that shoe-horned CodeMirror into Svelte, but they were from Svelte 1.x, no longer work and are no longer maintained. Just as well, though, since it will provide an excuse to learn more about Svelte modules and lifecycles.

## Oct 22, 2020
To be honest, now that I've worked with some of the basic fundamentals of Svelte, I'm more interested in its utility as an authenticated app. Which is the way I'll be using it. In other words, an app that you can sign-in to, do stuff (CRUD, etc), and log out of.

So now I want to try Firebase authentication with a router. And for that I have two options in mind that I'd like to explore...

1. **Traditional** - A node server w/ authenticated routes and apis. In which case, [Sapper](https://sapper.svelte.dev/docs#Server_routes).

2. **Edgy** *(literally)* - Achieve the same effect with higher performance and scalability with Cloudflare Workers, KV and [HTMLRewriter](https://developers.cloudflare.com/workers/runtime-apis/html-rewriter) stream injection.

I've recently read through a couple of great tutorials by [Ilia Mikhailov](https://codechips.me/about/) that walk  through using [firebase auth w/ Svelte](https://codechips.me/firebase-authentication-with-svelte/) either directly or [w/ XState](https://codechips.me/firebase-authentication-with-xstate-and-svelte/).

I'll skip XState for now and focus on the more immediate task of evaluating Sapper, Cloudflare, and service workers.

## Oct 25, 2020
It looks like running Sapper on Cloudflare is certainly possible. There is a GitHub repo that demonstrates it.

{% github lukeed/svelte-ssr-worker %}

I also found an interesting svelte/firebase/cloudflare project on Svelt's subreddit: https://www.reddit.com/r/sveltejs/comments/gt16s8/new_side_project_saas_built_with_svelte_open_demo/

## Oct 27, 2020
Sidetracked with a project, but managed to install Sapper locally and get acquainted. Beyond the basics, one idiosyncrasy that I found with Sapper vs Svelte is the difference between the [Client](https://svelte.dev/docs#Client-side_component_API) and [Server](https://svelte.dev/docs#Server-side_component_API) Component APIs.

#### Focusing an input on component mount doesn't work in Sapper
Let's say you have a text input that you want to receive focus on DOM ready.

In Svelte *(w/out Sapper)* you simply add an `onMount` method and focus the element after having bound it to a variable with `bind:this={inputElement}`. [See example](https://svelte.dev/repl/425d987fa48b28dcaa9872f88d5986e3?version=3.0.0-beta.21) *(not mine)*

In Sapper, this doesn't work because, as the [Sapper API explains](https://svelte.dev/docs#Server-side_component_API): 

> Unlike client-side components, server-side components don't have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.

I've yet to work out how to use this insight to accomplish the focus-input-onmount effect.

My initial inquest was to create a separate button that calls a `handleFocus` component handler `on:click` and that works. When you click the button the element is focused. But we want automatic focus `onMount`.

So now it's a matter of how to do it within a Sapper app.

My two initial thoughts on strategy are:
1. The Svelte Way&trade; *(unknown atm)*
2. A traditional DOM event listener of some sort shoe-horned into the Sapper paradigm. *(the least desirable option)*

I don't really need this for anything at the moment, but I don't like the idea of leaving it unsolved as it provides some important insights into the fundamental differences between client and server-side Svelte components.

I'll post with more when I have it.

![I'm Ready - Cat](https://dev-to-uploads.s3.amazonaws.com/i/1xmcigpurgb5zhrausbl.gif)

#### Update: Mystery Solved (a cup of coffee later)
`.focus()` doesn't work `onMount` on purpose for a11y reasons. Here's an explanation from Rich:

{% github https://github.com/sveltejs/sapper/issues/619#issuecomment-480616597 %}

![Thanks for the cup of obvious!](https://dev-to-uploads.s3.amazonaws.com/i/5vvrru5f2jd7fwnjepuh.gif)

#### &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thanks for the cup of obvious.