Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/raycar5/valv
A tiny but powerful web framework built on top of lit-html and rxjs
https://github.com/raycar5/valv
framework lit-html rxjs typescript web
Last synced: about 2 months ago
JSON representation
A tiny but powerful web framework built on top of lit-html and rxjs
- Host: GitHub
- URL: https://github.com/raycar5/valv
- Owner: raycar5
- License: mit
- Created: 2018-11-13T08:12:21.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-06-23T03:18:17.000Z (over 2 years ago)
- Last Synced: 2023-03-06T12:23:29.954Z (almost 2 years ago)
- Topics: framework, lit-html, rxjs, typescript, web
- Language: TypeScript
- Homepage:
- Size: 1.02 MB
- Stars: 10
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: code-of-conduct.md
Awesome Lists containing this project
README
# | Valv |
A tiny but powerful web framework built on top of [lit-html](https://github.com/Polymer/lit-html) and [rxjs](https://github.com/ReactiveX/rxjs)
## [Demo](https://valv-hn.firebaseapp.com/top/1) ([Source](https://github.com/raycar5/valv-hn))
## Features
- Easy ui design and composition thanks to lit-html
- Powerful state management thanks to rxjs
- Fast! (no traversing trees to see what changed)
- SPA router in the box
- 100% Web component compatible
- Nice api for web animations
- Tiny (10KB gzipped)## Naming
Due to the extensive use of rx in this library I've opted for the following naming convention for the frequently used types:
- Observables: observable\$
- Subjects: \$subject\$
- Observers: \$observer## Guide
Valv is all about controlling the flow of streams, whenever an event happens, it gets put into an observable and the job of the application is to build a pipeline with rxjs that turns that event into a UI update.
**It is an absolute requirement that you understand rxjs in order to use this framework, so please read the documentation at [ReactiveX](http://reactivex.io/intro.html) if you haven't done so.**
Valv has 2 main parts, Widgets and Blocs:
### Widgets
A widget is a function that takes context, some props and returns a lit-html TemplateResult, it is wrapped in the `Widget` function for convinience.
```typescript
interface MyWidgetProps {
text: string;
}
const MyWidgetDefaultProps = { text: 'HelloWorld' };
const MyWidget = Widget((context, { text }: MyWidgetProps = MyWidgetDefaultProps) =>
html`
${text}
`;
);
```Rendering a widget is easy!
```typescript
render(MyWidget(context), document.getElementById('body'));
```Widgets are composable.
```typescript
// Props can have any type you want
const BoldWidget = Widget(
(context, widget: Widget) =>
html`
${widget(context)}
`
);
```### Blocs
A Bloc is any class that uses observers as input and observables as output, the framework does not enforce this, you can put any class you like into a BlocRepo but hopefully after this guide you'll see it's a good way to structure your code.
```typescript
class MyBloc {
public readonly input: Observer; // We don't care about input values, just that the event happened
public readonly output: Observable;// All the pipes are plugged together in the constructor
constructor() {
const subject = new Subject();
const input = subject; // We only expose the Observer side of the subject
const output = subject.pipe(map((x, index) => index)); // Number will increase as events come through the input
}
}
```Widgets access blocs through the bloc repository or BlocRepo.
The code below displays a button and a number that increases every time you press the button.```typescript
const context = new Context(); // Context right now only contains the BlocRepo but might include more information in the future
context.blocs.register(MyBloc);
context.blocs.register(MyParameterizedBloc, new MyParameterizedBloc(32)); // You can also provide an instanceconst MyWidget = Widget(context => {
const myBloc = context.blocs.of(MyBloc);
return html`
${awaito(myBloc.output)}
`;
});
```## awaito
But wait what is that function `awaito`?
It stands for await observable and it's the main tool that Valv provides, it takes an observable of anything that can be rendered in lit-html (text,numbers,TemplateResults) and whenever the observable emits a new value, the previous dom gets replaced with the new one.
It also provides a convinient map function as a second parameter if you want to construct the UI at the call site.
```typescript
awaito(
numberObservable,
number =>
html`
${number}
`
);
```## Todo
- A lot of Documentation
- SSR
- PWA facilities
- more fancy animation stuff### Made with [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter)