How to patch browsers to  become modern OS?
Tags: webdev, javascript, serverless, showdev
Published: 2022-02-22 21:20:00

## Can I Call Browser "OS"?
Modern browsers become more powerful day by day in past decades. Now, even OS can be run inside of web pages(Game Console, Win32, DOS, emulators). In this way, can we call browser "OS"? Probably: **No**.  
So, what's different between Browser and OS, or, what's **missing**? I took an investigation on this. 

## What Components Does a Typical OS Have?
I should have learned this in school, but... Let's ask google.

![Google](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0qpjesymrlof2c93sdx.png)

After reading 3 great articles, I summarized it to:

Core components: [1]File System, [2]Process Management, [3]Memory management, [4]I/O Device Management  

Additionally, "User oriented OS" needs: [5]GUI System, [6]Multitasking, [7]Network System, [8]Security Management.  

![OS Components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7fibnjuyzy0nwfj7w43.png)

So, 8 components in total. Less than you expected, isn't it?

## What's Missing?
I looked into browser of those components. They are in several states: 
:+1: : Check = 3 components
:point_right: : Partly check = 4 components
:-1: : Missing = **1 component** 

| Component | Status | Note |
|---|---|---|
| **GUI System** | :+1: | After years competing each other, browsers are all superb at GUI. |
| **Memory Management** | :+1: | Although eating them a lot, browsers handle memory not bad. |
| **Security Management** | :+1: | Not like the old days, browsers are more secure. |
| **Network System** | :point_right: | Browsers are great at **fetch** but not so good at **serve** in network point of view. |
| **Process Management** | :point_right: | There are no *real process* in browser. But we can think every ***window (iframe) as a process***. And they are been greatly managed. |
| **Multitasking** | :point_right: | Like process management, we have pages, iframes, web-workers to work around. |
| **I/O Device Management** | :point_right: | We really can't access those device in browser. But most of their function can be accessed via modern Web API like Web Audio, MediaStream, etc. |
| **File System** | :-1: | Normally, browsers' files come from web site by download. They can't be modified or share access between pages. Although there is a *File System Access API*, it only limited supported by Chrome. |

## Make the Patch?
To make browsers be more like modern OS, the major missing component is the **File System**. 
There are a lot of open source "file-system" can be found on GitHub, but most of them are focused on *One Page* and *temporary* usage. So I started the project: **OS like file-system for web pages**.

## Project Goal 
Make a file system for browser:
- **Compatible:** Work with Chrome(Edge), Safari and Firefox, desktop & mobile.
- **No Cheats:** Use only WEB standard API. No browser extensions or native apps need.  
- **Local:** Contents are stored in device local space, not server side.
- **Permanent:** Files should be kept in a permanent way.
- **Cross Page:** Within same domain, pages access the same contents. 
- **API:** Provide API like node.js to access file-system.
- ***HTTP(Better to have):*** Files can be accessed with URL in browser.

## The Coding Execution
To write such file-system, I met some challenges：

### Choose Storage: IndexDB  

There are two types of permanent storage we can use: *LocalStorage* and *IndexedDB*. The first one is faster and support sync-operations, the second one is bit slower and does not support sync-operations.   
The LocalStorage has two critical problems: size limit (around 10M) and cannot work in web workers. So, for a file-system, IndexedDB looks like the better choice.

### Sync Access to IndexedDB: Failed

IndexDB only has async-API. I tried a several work-around to enable Sync-Access to IndexDB.  

One of them is using **sync-XMLHttpRequest** to fetch data from a Service-Worker that access the IndexedDB. It sounds promising, but only works on Firefox. Other crazier ideas all failed too...  

After struggling with it a while, I gave up the idea of sync-access IndexedDB. Instead, the file-system will run mostly in async-access mode. When needed, certain path will be fetched into memory to perform sync-access. This is **not perfect**.  

### Http Access: Well Done  

To enable direct URL access to files in the file system. I learnt to write a service worker.   
I added one "/" at head of file path as the **pathname** for URL. So file path "/docs/readme.md" turned to URL: "https://[domain]**//**docs/readme.md". The service worker parses request URL, converts it to file-system path and respond with the contents from file system (indexedDB).   


## The Result  
It has done a good job. All project goals are checked! It comes with a **node.js fs API**.
Based on the file system, I made some interesting Apps:

### 1. File Manager

![File Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkii9sjlwqr61erszqjx.png)
It's very much like Windows Explorer and MacOS' Finder. Besides manage files, you can **drag&drop or copy&paste native OS files** into the web file-system. 

### 2. Terminal

![Terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atd4nifx2dtljtj3xnn9.png)
This is a UNIX terminal mockup in web. It supports commands like: ls, cd, mkdir, cp, rm, move, zip, unzip etc...

### 3. Code Editor

![Code Editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3xkesg63ndjn2i7l6hw.png)
Powered by CodeMirror, the code editor can edit HTML, Javascript, JSX, and other text files just like a modern code editors: syntax-highlight, block-fold, auto-complete, search-replace and more. I coded most apps and tools (the terminal, file manager, commands in terminal) with it.

### Fastify Server in Browser

With service worker, we can provide service. So I ported **Fastify** framework to do that.

## Try out
You can try out the file-system and apps based on it at [www.cokecodes.com](www.cokecodes.com)

My file system code git is here: [GitHub:JAXDisk](https://github.com/Avdpro/JAXDisk)