# aweft

A full-stack toolkit for applications whose state is a document. An observable document is
the model, the wire and the storage format at once: assign to it, and the change is a commit
that a page renders, a peer receives and a store keeps. Every piece is a package with one job,
and a package that does not need another does not know it exists.

## Hello, three ways

A document:

```ts
import { atomic, createObject, observer } from '@aweftjs/core';

const doc = createObject({ title: 'plan', done: 0 });
const stop = observer(doc).path('title').watch(() => console.log(doc.title));

doc.title = 'plan b';                                   // one commit; the watcher runs once
atomic(() => { doc.title = 'plan c'; doc.done = 1; });  // one commit, however much it writes
stop();
```

A page:

```tsx
import { mutable } from '@aweftjs/core';
import { h, mount } from '@aweftjs/ui';

const Counter = () => {
	const clicks = mutable(0);
	return <button theme="button" onClick={() => clicks.set(clicks.get() + 1)}>clicked {clicks} times</button>;
};

mount(document.body, <Counter />);
```

A server:

```ts
import { auth, paths } from '@aweftjs/auth';
import { fromDirectory } from '@aweftjs/modules/node';
import { createServer } from '@aweftjs/server';
import { node } from '@aweftjs/server/node';
import { createStore, memoryDriver } from '@aweftjs/store';

const store = createStore({ driver: memoryDriver(), declare: { ...paths } });
const server = createServer({ sources: [fromDirectory('./modules'), auth], store, gate: 'auth/Gate', listener: node({ port: 8080 }) });
await server.start();
```

That is the whole boot. Everything else the server does is a module in `./modules`, and the
page reaches it over one socket that carries both the shared documents and the calls.
[`recipes/full-stack/`](/docs/recipes/full-stack) is the two halves in one directory, with the page reaching the server in
development through the dev server's proxy; its README carries the manifest and `tsconfig` an
application starts from.

## Install

```sh
npm i @aweftjs/core @aweftjs/ui
```

[Read the guide](/docs/start)
