mmm​.s‑ol.nu

fun stuff with code and wires
an error occured while rendering this view:

mmmfs

a file and operating system to live in

motivation

Today, computer users are losing more and more control over their data. Between web and cloud applications holding customer data hostage for providing the services, unappealing and limited mobile file browsing experiences and the non-interoperable, proprietary file formats holding on to their own data has become infeasible for many users. mmmfs is an attempt at rethinking file-systems and the computer user experience to give control back to and empower users.

mmmfs tries to provide a filesystem that is powerful enough to let you use it as your canvas for thinking, and working at the computer. mmmfs is made for more than just storing information. Files in mmmfs can interact and morph to create complex behaviours.

Let us take as an example the simple task of collecting and arranging a mixed collection of images, videos and texts in order to brainstorm. To create an assemblage of pictures and text, many might be tempted to open an Application like Microsoft Word or Adobe Photoshop and create a new document there. Both photoshop files and word documents are capable of containing texts and images, but when the files are saved, direct access to the contained data is lost. It is for example a non-trivial and unenjoyable task to edit an image file contained in a word document in another application and have the changes apply to the document. In the same way, text contained in a photoshop document cannot be edited in a text editor of your choice.

mmmfs tries to change all this. In mmmfs, files can contain other files and so the collage document becomes a container for the collected images and texts just as a regular directory would. This way the individual files remain accessible and can be modified whenever necessary, while the collage document can be edited to change the order, sizes and spatial arrangement of it's content if this is wanted, for example.

The mmmfs file-type system also allows storing types of information that have become impractical to use with current filesystems simply because noone has cared to make suitable applications for them. It is not common practice, for example, to store direct links to online content on the disk for example. In mmmfs, a link to a picture can be stored wherever an actual picture is expected for example, the system will take care of retrieving the real picture as necessary.

in mmmfs, directories, files and applications are all kind of the same thing, or something like that. Listen, I don't really know yet either. The idea is that there is only one type of 'thing' - a fileder[1]. A fileder can store multiple variants and metadata of its content, such as a markdown text and a rendered HTML version of the same document. It could also store a script that transforms the markdown version into HTML and is executed on demand, automatically.

Fileders can also have other fileders as their children (just like directories do in a normal filesystem). You can make a fileder view query these children and display them however you want. A 'Pictures' fileder, for example, could contain a script within itself that renders all the picture files you put into it as little previews and lets you click on them to view the full image.

This means the 'Pictures' fileder can also have an alternate slideshow mode, with fullscreen view and everything (some of this is built, check out the gallery example below), or one that displays geotagged images on a world map, if you really want that. Maybe you could build a music folder that contains links to youtube videos, spotify tracks and just plain mp3 files, and the folder knows how to play them all.
In this way fileders fulfil the purpose of 'Applications' too.

A fileder is also responsible for how it's children are sorted, filtered and interacted with. For example you should be able to create a fileder that is essentially a 'word document' equivalent: it can contain images, websites, links and of course text as children and let you reorder, layout and edit them whenever you open the fileder.

Sounds cool, no? Here's some examples of things a fileder can be or embed:

Hey I'm an almost empty Fileder.

(no renderable content)

A Gallery of 25 random pictures, come on in!

the first pic as a little taste:

Hey I'm like a link to a picture or smth

scripting language support

this Fileder contains some minimal examples showing support for various languages mmmfs supports currently.

Language support is mostly limited by the fact that mmmfs currently targets web browsers, on the server any scripting language that can be executed can theoretically be integrated with minimal effort.

Using the inspector mode to view the source of the Fileders below is encouraged.

I'm not even five lines of markdown but i render myself!

See I have like

  • a list of things
  • (two things)

and some bold text and code tags with me.

details

Fileders are made up of two main parts. The first is the list of facets, which are values identified by a name and type. These values are queried using strings like

The second part of a fileder is the list of it's children, which are fileders itself. The children are stored in an ordered list and currently identified by their name: alpha facet for UI and navigation purposes only (not sure if this is a good idea tbh).

Anyway, this node is set up as a very generic sort of index thing and just lists its children-fileders' alongside this text part you are reading.
For each child it displays the title: text/plain and shows the preview: mmm/dom facet (if set).

converts

So far I have always listed facets as they are being queried, but a main feature of mmmfs is type conversion. This means that you generally ask for content in whichever format suits your application, and rely on the type resolution mechanism to make that happen.

-- render a preview block
preview = (title, content) -> div {
  h3 title, style: { ... },
  content or span '(no renderable content)', style: { ... },
  style: { ... }
}

append div for child in *@children
-- get 'title' as 'text/plain' (error if no value or conversion possible)
title = child\gett 'title', 'text/plain'

-- get 'preview' as a DOM description (nil if no value or conversion possible)
content = child\get 'preview', 'mmm/dom'

preview title, content

Here the code that renders these previews. You can see it asks for the facets title: text/plain and preview: mmm/dom), but the values don't actually have to be defined as these types. For example, the markdown child below only provides preview as text/markdown:

Fileder {
  'title: text/plain': "I'm not even five lines of markdown but i render myself!",
  'preview: text/markdown': "See I have like

  - a list of things
  - (two things)

  and some bold **text** and `code tags` with me.",
}

Then, globally, there are some conversion paths specified; such as one that maps from text/markdown to mmm/dom:

{
  inp: 'text/markdown',
  out: 'mmm/dom',
  transform: (md) ->
    -- polymorphic client/serverside implementation here,
    -- uses lua-discount on the server, marked.js on the client
}

type chains

In addition, a facet type can be encoded using multiple types in a type chain. For example the root node you are viewing currently is actually defined as fn -> mmm/dom, meaning it's value is a pre moon function returing a regular mmm/dom value.

Both value chains and 'sideways' converts are resolved using the same mechanism, so this page is being rendered just using append root\get 'mmm/dom' as well. The convert that resolves the moon type is defined as follows:

{
  inp: 'fn -> (.+)',
  out: '%1',
  transform: (val, fileder) -> val fileder
}

The example with the image is curious as well. In mmmfs, you might want to save a link to an image, without ever saving the actual image on your hard drive (or wherever the data may ever be stored - it is quite transient currently). The image Fileder below has it's main (unnamed) value tagged as URL -> image/png - a png image, encoded as an URL. When accessed as image/png the URL should be resolved, and the binary data provided in it's place (yeah right - I haven't build that yet).

However, if a script is aware of URLs and knows a better way to handle them, then it can ask for and use the URL directly instead. This is what the image demo does in order to pass the URL to an img tag's src attribute:

Fileder {
  'title: text/plain': "Hey I'm like a link to picture or smth",
  'URL -> image/png': 'https://picsum.photos/200?random',
  'preview: fn -> mmm/dom': =>
    import img from require 'mmm.dom'
    img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
}
  1. 1: fileder: file + folder. 'node', 'table' etc. are too general to be used all over.
  2. 2: mmm/dom is a polymorphic content type; on the server it is just an HTML string (like text/html), but on the client it is a JS DOM Element instance.