Add a readme with some big-picture stuff.
parent
b675692877
commit
945018a8ab
|
@ -0,0 +1,203 @@
|
|||
|
||||
## Rationale
|
||||
|
||||
Modern implementations of web renderers seem to make incremental changes,
|
||||
working from the previous ideas rather than a desired ideal state.
|
||||
|
||||
This means seemingly needless constraints like Svelte's (SvelteKit's)
|
||||
absolute reliance on files.
|
||||
|
||||
We do not want a framework, we want a toolkit from which appropriate
|
||||
frameworks can arise ephemerally to meet various needs. The core engine
|
||||
needs to do one thing: weave arbitrary content with arbitrary form.
|
||||
|
||||
## Requirements
|
||||
|
||||
Here are the requirements:
|
||||
|
||||
The fundamental concept is that both form (for example, templates) and
|
||||
content (such as from a database) are considered data. This project, then,
|
||||
is to be a toolkit that allows you to create data flows.
|
||||
|
||||
We want to be absolutely agnostic to platform, architecture, etc. We are
|
||||
just taking in data and transforming it repeatedly to desired outputs.
|
||||
|
||||
Let's say we have a set of data in the form of:
|
||||
|
||||
* HTML templates (including fragments)
|
||||
* Markdown templates
|
||||
* json data
|
||||
* csv data
|
||||
|
||||
We want to create a pipeline of transformers that do whatever is necessary
|
||||
to merge those in desirable ways. Here are some (overly-)simplified
|
||||
examples:
|
||||
|
||||
```
|
||||
# feed.json
|
||||
{
|
||||
"title": "How to do things",
|
||||
"link": "url.com",
|
||||
"description": "Learn how to do various things."
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
# rss.csv
|
||||
title,link,date
|
||||
"How to see","url.com/story/how-to-see","2023-01-01"
|
||||
"How to eat","url.com/story/how-to-eat","2023-01-02"
|
||||
"How to run","url.com/story/how-to-run","2023-01-03"
|
||||
```
|
||||
|
||||
```
|
||||
# Item.component.xml
|
||||
<item>
|
||||
<title>{item.title}</title>
|
||||
<link>https://{item.link}</link>
|
||||
<description>{item.description}</description>
|
||||
</item>
|
||||
```
|
||||
|
||||
```
|
||||
# rss.template.xml
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>{feed.title}</title>
|
||||
<link>https://{feed.link}</link>
|
||||
<description>{feed.description}</description>
|
||||
<Item data={feed.items[0]}/>
|
||||
<Item data={feed.items[1]}/>
|
||||
<Item data={feed.items[2]}/>
|
||||
</channel>
|
||||
</rss>
|
||||
```
|
||||
|
||||
The toolkit will make it easy to weave these bits of data (both form data
|
||||
and content data) together.
|
||||
|
||||
Here are some flows and dreamcode.
|
||||
|
||||
## Flows
|
||||
|
||||
Possible flows:
|
||||
|
||||
***Fragment-first***
|
||||
|
||||
```
|
||||
1. read Item.component.html
|
||||
2. read rss.csv
|
||||
3. transform rss.csv into a desired format
|
||||
4. produce output XML with all item data fixed.
|
||||
|
||||
5. read rss.template.xml
|
||||
6. read feed.json
|
||||
7. transform feed.json into a desired format
|
||||
8. produce output XML with values fixed.
|
||||
|
||||
9. integrate the two outputs for the final xml
|
||||
10. optimize/minify
|
||||
```
|
||||
|
||||
***Compilation-first***
|
||||
|
||||
```
|
||||
1. read Item.component.html
|
||||
2. read rss.template.xml
|
||||
3. compile a master template
|
||||
|
||||
4. read rss.csv
|
||||
5. read feed.json
|
||||
6. compile a master data source
|
||||
|
||||
7. produce an output XML with values fixed.
|
||||
8. optimize/minify
|
||||
```
|
||||
|
||||
## Dreamcode
|
||||
|
||||
The key here is that components don't have to come from files. Key
|
||||
features:
|
||||
* Modules can come from any string, stream, buffer, or whatever.
|
||||
* Multiple modules can be defined in the same source.
|
||||
* Once a module is loaded, it's available to import with an ES6-like
|
||||
syntax.
|
||||
|
||||
### Compiler / Renderer
|
||||
The target style is to use pure functions. If someone wants something like
|
||||
OO, they can wrap the functions.
|
||||
|
||||
```
|
||||
// functional style
|
||||
(sanitizeXml
|
||||
(compileRenderedComponents
|
||||
(renderXmlWithJson
|
||||
(readXmlTemplate 'rss.template.xml')
|
||||
(readJson 'feed.json'))
|
||||
|
||||
(renderXmlWithJson
|
||||
(readXmlTemplate 'Item.template.xml')
|
||||
(csvToJson (readCsv 'rss.csv')))
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
```
|
||||
// The same in a JavaScript-style syntax
|
||||
const xml = minifyXML(
|
||||
sanitizeXML(
|
||||
compileRenderedComponents(
|
||||
await renderXmlWithJson(
|
||||
readXmlTemplate('rss.template.xml),
|
||||
readJson('feed.json')
|
||||
),
|
||||
|
||||
await renderXmlWithJson(
|
||||
readXmlTemplate('Item.template.xml'),
|
||||
csvToJson(readCsv('rss.csv'))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Components
|
||||
Perhaps components should be in the style of HTML or JSX fragments. I
|
||||
borrowed heavily from Svelte for this.
|
||||
|
||||
```
|
||||
// This "<loom-module>" tag could be created automatically before inserting.
|
||||
<loom-module>
|
||||
<script type="text/loom-module">
|
||||
/**
|
||||
* Key script features:
|
||||
* - Assume ES6?
|
||||
* - Maybe allow other languages that transpile to JS?
|
||||
* - Automatically sandbox css?
|
||||
*/
|
||||
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
<li>Allow multiple comment styles?</li>
|
||||
<li>Plugin-based transformations (AST)</li>
|
||||
<li>Some kind of script scoping</li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
|
||||
<style type="test/scss">
|
||||
/**
|
||||
* Key styling features:
|
||||
*
|
||||
* - Allow all three comment types here? Make this a setting?
|
||||
* - Bake-in postcss transformers? Maybe project-agnostic...
|
||||
* - Automatically sandbox css
|
||||
*/
|
||||
</style>
|
||||
|
||||
</loom-module>
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue