-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update package scope * Add release workflow * Update version * Add README * Update README
- Loading branch information
Showing
9 changed files
with
167 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
name: Publish package to npm | ||
|
||
on: | ||
release: | ||
types: [published] | ||
|
||
jobs: | ||
teat-and-release: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
id-token: write | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Use Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20 | ||
registry-url: 'https://registry.npmjs.org' | ||
|
||
- name: Install dependencies | ||
run: npm ci | ||
|
||
- name: Check Lint | ||
run: npm run lint | ||
|
||
- name: Check Style | ||
run: npm run style | ||
|
||
- name: Run Tests | ||
run: npm test -- --coverage --coverageReporters lcov | ||
|
||
- name: Publish to npm | ||
run: | | ||
cd packages/pipe | ||
npm publish --provenance --access public | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,113 @@ | ||
# pipe | ||
|
||
A Reactive DOM UI Library built on RxJS and TypeScript. | ||
|
||
## What is Pipe? | ||
|
||
Pipe is a declarative UI library, similar to React.js or Solid.js. This library seeks to provide a lightweight scripting layer on top of HTML/CSS, allowing developers to create simple and interactive web sites. In its current form, the library does not provides only utilities for dynamically rendering HTML into a document. It is not opinionated about state management, single page vs. multi-page applications, or styling. In theory, the library could be used as a drop-in replacement for React, though it is unclear how well that would scale. However, it would also be possible to create many pipe `roots`, as there is minimal overhead for creating a root, and scheduling is delegated to RxJS. | ||
|
||
Pipe is built around observables, specifically the `RxJS` implementation of observables. Observables are reactive and functional in nature, which makes them ideal for programming declarative UI interfaces. Observables are passed as props to DOM elements, which are initialized immediately when `createElement` is called. The DOM element subscribes to each observable prop, and updates immediately when a value is received. There is some overhead here from RxJS to schedule these state updates. This is slightly different from a library like React, which inserts element creation and state updates into an event queue, and constructs/updates a Virtual DOM from these updates before committing them to the actual DOM. The latter approach may scale better with more complex components, avoiding potential issues like screen tearing with batched updates. The former approach is likely faster for less complex components, though. | ||
|
||
Each component function is only called once. This allows us to avoid the need to memoize state updates in most situations. The only exception is when an observable passes a large table of props that need to be parsed separately. In this case, the `distinctUntilKeyChanged` operator is quite useful. | ||
|
||
## Installation | ||
|
||
``` | ||
npm install --save @hmallen99/pipe | ||
``` | ||
|
||
## Usage | ||
|
||
Creating a root: | ||
|
||
```ts | ||
const rootElement = document.querySelector<HTMLDivElement>('#root'); | ||
|
||
const root = createRoot(rootElement); | ||
|
||
root.render(createElement(App, {})); | ||
``` | ||
|
||
Creating a component: | ||
|
||
```ts | ||
const Counter: Component<Record<string, Observable<void>>> = () => { | ||
const click$ = new Subject<void>(); | ||
const onclick = of(() => { | ||
click$.next(); | ||
}); | ||
const textContent = click$.pipe( | ||
scan((x) => x + 1, 0), | ||
map((x) => String(x)), | ||
); | ||
|
||
return createElement('button', { | ||
onclick, | ||
textContent: concat(of('Click Me!'), textContent), | ||
}); | ||
}; | ||
|
||
const App: Component<Record<string, Observable<void>>> = () => { | ||
return createElement('div', {}, [createElement(Counter, {})]); | ||
}; | ||
``` | ||
|
||
Child elements can be either static or dynamic. If a child component is never updated, it can be passed through a list of child elements, as shown above. If child components need to be removed or inserted, an observable can be passed instead of a static array. This allows for rendering lists of children or conditional children. A stable key must be passed with every child element in this configuration to allow for updating and removing the correct child element. | ||
|
||
Conditional children: | ||
|
||
```ts | ||
const SwitchComponent: Component<{ | ||
bool$: Observable<boolean>; | ||
}> = ({ bool$ }) => { | ||
return createElement( | ||
'div', | ||
{}, | ||
bool$.pipe( | ||
map((value) => [ | ||
'default', | ||
value | ||
? createElement('p', { | ||
textContent: new BehaviorSubject('true'), | ||
}) | ||
: createElement('p', { | ||
textContent: new BehaviorSubject('false'), | ||
}), | ||
]), | ||
), | ||
); | ||
}; | ||
``` | ||
|
||
List of children: | ||
|
||
```ts | ||
const TextList: Component<{ | ||
addChild$: Observable<[string, string]>; | ||
}> = ({ addChild$ }) => { | ||
return createElement( | ||
'div', | ||
{}, | ||
addChild$.pipe( | ||
map(([key, value]) => [ | ||
key, | ||
createElement('p', { | ||
textContent: of(value), | ||
}), | ||
]), | ||
), | ||
); | ||
}; | ||
``` | ||
|
||
RxJS observables are re-exported through the pipe library. To avoid importing multiple versions of RxJS, import RxJS observables and operators through `@hmallen99/pipe` | ||
|
||
```ts | ||
import { createElement, createRoot, Subject, of } from '@hmallen99/pipe'; | ||
``` | ||
|
||
For a more detailed exploration of usage, view the [example todo app](./apps/todo-app/src/TodoApp.ts). | ||
|
||
## Planned work | ||
|
||
Track bugs and new features on GitHub: https://github.com/hmallen99/pipe/issues |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
# Rsbuild Project | ||
# Example TODO App | ||
|
||
A simple todo list application built with pipe. | ||
|
||
## Setup | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,6 @@ | |
"typescript-eslint": "^8.5.0" | ||
}, | ||
"dependencies": { | ||
"@pipe/pipe": "^0.0.1" | ||
"@hmallen99/pipe": "^0.0.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters