@webqit/webflo 0.11.61 → 0.20.2-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +12 -0
- package/.github/workflows/publish.yml +48 -0
- package/.gitignore +2 -0
- package/LICENSE +2 -2
- package/README.md +71 -2050
- package/package.json +28 -13
- package/site/-/_.md +139 -0
- package/site/-/docs.old.md +2010 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url 2.js +93 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js +93 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js 2.map +7 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js.map +7 -0
- package/site/.vitepress/cache/deps/_metadata 2.json +85 -0
- package/site/.vitepress/cache/deps/_metadata.json +85 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4 2.js +9 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +7 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK 2.js +9719 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js +9719 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js.map +7 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7 2.js +12705 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js +12705 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape 2.js +30278 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent 2.js +4710 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js +4710 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js 2.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape.js +30278 -0
- package/site/.vitepress/cache/deps/cytoscape.js 2.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape.js.map +7 -0
- package/site/.vitepress/cache/deps/dayjs 2.js +285 -0
- package/site/.vitepress/cache/deps/dayjs.js +285 -0
- package/site/.vitepress/cache/deps/dayjs.js 2.map +7 -0
- package/site/.vitepress/cache/deps/dayjs.js.map +7 -0
- package/site/.vitepress/cache/deps/debug 2.js +453 -0
- package/site/.vitepress/cache/deps/debug.js +453 -0
- package/site/.vitepress/cache/deps/debug.js 2.map +7 -0
- package/site/.vitepress/cache/deps/debug.js.map +7 -0
- package/site/.vitepress/cache/deps/package 2.json +3 -0
- package/site/.vitepress/cache/deps/package.json +3 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api 2.js +4507 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4507 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core 2.js +584 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js +584 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap 2.js +1166 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1166 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js 2.js +1667 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1667 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch 2.js +1815 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js +1815 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
- package/site/.vitepress/cache/deps/vue 2.js +344 -0
- package/site/.vitepress/cache/deps/vue.js +344 -0
- package/site/.vitepress/cache/deps/vue.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vue.js.map +7 -0
- package/site/.vitepress/config.ts +147 -0
- package/site/.vitepress/theme/custom.css +50 -0
- package/site/.vitepress/theme/index.ts +6 -0
- package/site/api/webflo-fetch/FormData.md +0 -0
- package/site/api/webflo-fetch/Headers.md +0 -0
- package/site/api/webflo-fetch/LiveResponse.md +0 -0
- package/site/api/webflo-fetch/Request.md +0 -0
- package/site/api/webflo-fetch/Response.md +0 -0
- package/site/api/webflo-fetch/fetch.md +0 -0
- package/site/api/webflo-routing/HttpCookies.md +0 -0
- package/site/api/webflo-routing/HttpEvent/respondWith.md +1 -0
- package/site/api/webflo-routing/HttpEvent/waitUntil.md +1 -0
- package/site/api/webflo-routing/HttpEvent/waitUntilNavigate.md +1 -0
- package/site/api/webflo-routing/HttpEvent.md +30 -0
- package/site/api/webflo-routing/HttpSession.md +0 -0
- package/site/api/webflo-routing/HttpState.md +0 -0
- package/site/api/webflo-routing/HttpUser.md +0 -0
- package/site/api/webflo-routing/handler/fetch.md +42 -0
- package/site/api/webflo-routing/handler/next.md +54 -0
- package/site/api/webflo-routing/handler.md +119 -0
- package/site/api.md +26 -0
- package/site/contributing.md +16 -0
- package/site/docs/advanced/lifecycles.md +20 -0
- package/site/docs/advanced/redirects.md +0 -0
- package/site/docs/advanced/routing.md +1 -0
- package/site/docs/advanced.md +9 -0
- package/site/docs/concepts/realtime.md +637 -0
- package/site/docs/concepts/rendering.md +60 -0
- package/site/docs/concepts/request-response.md +47 -0
- package/site/docs/concepts/routing.md +656 -0
- package/site/docs/concepts/state.md +44 -0
- package/site/docs/concepts/templates.md +48 -0
- package/site/docs/concepts.md +97 -0
- package/site/docs/getting-started.md +378 -0
- package/site/docs/tech-stack.md +56 -0
- package/site/docs.md +100 -0
- package/site/examples/pwa.md +10 -0
- package/site/examples/web.md +11 -0
- package/site/examples.md +10 -0
- package/site/faq.md +13 -0
- package/site/guides/guide-auth.md +13 -0
- package/site/guides/guide-file-upload.md +11 -0
- package/site/guides/guide-service-worker.md +10 -0
- package/site/guides/tutorial-1-todo.md +24 -0
- package/site/guides.md +15 -0
- package/site/index.md +39 -0
- package/site/public/img/brand/logo-670x670.png +0 -0
- package/site/recipes/realtime.md +11 -0
- package/site/recipes/streaming.md +15 -0
- package/site/reference/cli.md +11 -0
- package/site/reference/config.md +13 -0
- package/site/reference/tools.md +9 -0
- package/src/Context.js +3 -11
- package/src/config-pi/deployment/Env.js +6 -19
- package/src/config-pi/deployment/Layout.js +11 -3
- package/src/config-pi/runtime/Client.js +40 -48
- package/src/config-pi/runtime/Server.js +52 -20
- package/src/config-pi/runtime/client/Worker.js +22 -20
- package/src/config-pi/static/Init.js +57 -0
- package/src/config-pi/static/index.js +2 -0
- package/src/deployment-pi/origins/index.js +1 -1
- package/src/deployment-pi/util.js +161 -0
- package/src/index.js +3 -9
- package/src/init-pi/index.js +117 -0
- package/src/init-pi/templates/pwa/app/handler.server.js +8 -0
- package/src/init-pi/templates/pwa/app/page.html +7 -0
- package/src/init-pi/templates/pwa/package.json +19 -0
- package/src/init-pi/templates/pwa/public/assets/app.css +16 -0
- package/src/init-pi/templates/pwa/public/index.html +39 -0
- package/src/init-pi/templates/pwa/public/manifest.json +29 -0
- package/src/init-pi/templates/web/app/handler.server.js +8 -0
- package/src/init-pi/templates/web/app/page.html +7 -0
- package/src/init-pi/templates/web/package.json +19 -0
- package/src/init-pi/templates/web/public/assets/app.css +16 -0
- package/src/init-pi/templates/web/public/index.html +39 -0
- package/src/runtime-pi/WebfloRuntime.js +350 -0
- package/src/runtime-pi/index.js +3 -10
- package/src/runtime-pi/webflo-client/ClientSideCookies.js +17 -0
- package/src/runtime-pi/webflo-client/ClientSideWorkport.js +63 -0
- package/src/runtime-pi/webflo-client/DeviceCapabilities.js +213 -0
- package/src/runtime-pi/webflo-client/WebfloClient.js +500 -0
- package/src/runtime-pi/webflo-client/WebfloRootClient1.js +206 -0
- package/src/runtime-pi/webflo-client/WebfloRootClient2.js +113 -0
- package/src/runtime-pi/webflo-client/WebfloSubClient.js +118 -0
- package/src/runtime-pi/webflo-client/index.js +17 -0
- package/src/runtime-pi/webflo-client/webflo-codegen.js +469 -0
- package/src/runtime-pi/webflo-client/webflo-devmode.js +243 -0
- package/src/runtime-pi/webflo-client/webflo-embedded.js +50 -0
- package/src/runtime-pi/webflo-fetch/LiveResponse.js +437 -0
- package/src/runtime-pi/webflo-fetch/cookies.js +10 -0
- package/src/runtime-pi/webflo-fetch/fetch.js +16 -0
- package/src/runtime-pi/webflo-fetch/formdata.js +54 -0
- package/src/runtime-pi/webflo-fetch/headers.js +151 -0
- package/src/runtime-pi/webflo-fetch/index.js +5 -0
- package/src/runtime-pi/webflo-fetch/message.js +49 -0
- package/src/runtime-pi/webflo-fetch/request.js +62 -0
- package/src/runtime-pi/webflo-fetch/response.js +110 -0
- package/src/runtime-pi/webflo-fetch/util.js +28 -0
- package/src/runtime-pi/webflo-messaging/WQBroadcastChannel.js +10 -0
- package/src/runtime-pi/webflo-messaging/WQMessageChannel.js +26 -0
- package/src/runtime-pi/webflo-messaging/WQMessageEvent.js +87 -0
- package/src/runtime-pi/webflo-messaging/WQMessagePort.js +38 -0
- package/src/runtime-pi/webflo-messaging/WQRelayPort.js +47 -0
- package/src/runtime-pi/webflo-messaging/WQSockPort.js +113 -0
- package/src/runtime-pi/webflo-messaging/WQStarPort.js +104 -0
- package/src/runtime-pi/webflo-messaging/wq-message-port.js +404 -0
- package/src/runtime-pi/webflo-routing/HttpCookies.js +42 -0
- package/src/runtime-pi/webflo-routing/HttpEvent.js +112 -0
- package/src/runtime-pi/webflo-routing/HttpSession.js +11 -0
- package/src/runtime-pi/webflo-routing/HttpState.js +153 -0
- package/src/runtime-pi/webflo-routing/HttpUser.js +54 -0
- package/src/runtime-pi/webflo-routing/WebfloRouter.js +245 -0
- package/src/runtime-pi/webflo-server/ServerSideCookies.js +19 -0
- package/src/runtime-pi/webflo-server/ServerSideSession.js +38 -0
- package/src/runtime-pi/webflo-server/WebfloServer.js +937 -0
- package/src/runtime-pi/webflo-server/index.js +11 -0
- package/src/runtime-pi/webflo-server/messaging/Client.js +27 -0
- package/src/runtime-pi/webflo-server/messaging/ClientRequestRealtime.js +50 -0
- package/src/runtime-pi/webflo-server/messaging/Clients.js +25 -0
- package/src/runtime-pi/webflo-server/webflo-devmode.js +326 -0
- package/src/runtime-pi/{client → webflo-url}/Url.js +27 -76
- package/src/runtime-pi/webflo-url/index.js +1 -0
- package/src/runtime-pi/webflo-url/urlpattern.js +38 -0
- package/src/runtime-pi/{util-url.js → webflo-url/util.js} +5 -43
- package/src/runtime-pi/webflo-url/xURL.js +94 -0
- package/src/runtime-pi/webflo-worker/WebfloWorker.js +234 -0
- package/src/runtime-pi/webflo-worker/WorkerSideCookies.js +19 -0
- package/src/runtime-pi/webflo-worker/WorkerSideWorkport.js +18 -0
- package/src/runtime-pi/webflo-worker/index.js +11 -0
- package/src/services-pi/index.js +2 -0
- package/src/services-pi/push/index.js +23 -0
- package/src/util.js +10 -0
- package/src/{webflo.js → webflo-cli.js} +4 -4
- package/src/runtime-pi/Application.js +0 -29
- package/src/runtime-pi/Cookies.js +0 -82
- package/src/runtime-pi/HttpEvent.js +0 -107
- package/src/runtime-pi/Router.js +0 -130
- package/src/runtime-pi/Runtime.js +0 -21
- package/src/runtime-pi/client/Application.js +0 -76
- package/src/runtime-pi/client/Context.js +0 -7
- package/src/runtime-pi/client/Router.js +0 -48
- package/src/runtime-pi/client/Runtime.js +0 -525
- package/src/runtime-pi/client/Workport.js +0 -190
- package/src/runtime-pi/client/createStorage.js +0 -58
- package/src/runtime-pi/client/generate.js +0 -481
- package/src/runtime-pi/client/index.js +0 -21
- package/src/runtime-pi/client/worker/Application.js +0 -44
- package/src/runtime-pi/client/worker/Context.js +0 -7
- package/src/runtime-pi/client/worker/Runtime.js +0 -275
- package/src/runtime-pi/client/worker/Workport.js +0 -78
- package/src/runtime-pi/client/worker/index.js +0 -21
- package/src/runtime-pi/server/Application.js +0 -101
- package/src/runtime-pi/server/Context.js +0 -16
- package/src/runtime-pi/server/Router.js +0 -159
- package/src/runtime-pi/server/Runtime.js +0 -558
- package/src/runtime-pi/server/index.js +0 -21
- package/src/runtime-pi/util-http.js +0 -86
- package/src/runtime-pi/xFormData.js +0 -24
- package/src/runtime-pi/xHeaders.js +0 -146
- package/src/runtime-pi/xRequest.js +0 -46
- package/src/runtime-pi/xRequestHeaders.js +0 -109
- package/src/runtime-pi/xResponse.js +0 -33
- package/src/runtime-pi/xResponseHeaders.js +0 -117
- package/src/runtime-pi/xURL.js +0 -105
- package/src/runtime-pi/xfetch.js +0 -23
- package/src/runtime-pi/xxHttpMessage.js +0 -102
- package/src/static-pi/index.js +0 -11
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# State Management
|
|
2
|
+
|
|
3
|
+
Webflo’s approach to state is refreshingly simple: your UI state is just a plain JavaScript object. When your server handler returns data, it becomes available as `document.bindings.data` for your templates and UI. No special syntax, no framework-specific magic—just JavaScript you already know.
|
|
4
|
+
|
|
5
|
+
## How State Flows
|
|
6
|
+
|
|
7
|
+
When a request comes in:
|
|
8
|
+
1. Your handler fetches or computes data.
|
|
9
|
+
2. That data is returned in the response.
|
|
10
|
+
3. Webflo assigns it to `document.bindings.data` on the client.
|
|
11
|
+
4. Your templates and UI render based on this state.
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
// In your handler
|
|
15
|
+
return new Response(renderToHtml({ todos: ["Buy milk", "Read docs"] }));
|
|
16
|
+
|
|
17
|
+
// In the browser
|
|
18
|
+
console.log(document.bindings.data.todos); // ["Buy milk", "Read docs"]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Reactivity with the Observer API
|
|
22
|
+
|
|
23
|
+
Want your UI to update automatically when state changes? Webflo’s Observer API lets you observe mutations on your state object and react to them—no new syntax or learning curve required.
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
Observer(document.bindings.data, () => {
|
|
27
|
+
// This runs whenever data changes
|
|
28
|
+
renderUI();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
document.bindings.data.todos.push("Write code"); // UI updates!
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> **Why it matters:** This “back to basics” approach means you can use all your JavaScript skills, with reactivity as an opt-in superpower. No hidden magic—just objects and events.
|
|
35
|
+
|
|
36
|
+
## When to Use Observer
|
|
37
|
+
- For live-updating UI (counters, lists, dashboards)
|
|
38
|
+
- For collaborative or realtime features
|
|
39
|
+
- For any case where you want the UI to reflect state changes instantly
|
|
40
|
+
|
|
41
|
+
## Learn More
|
|
42
|
+
- [Rendering](./rendering.md)
|
|
43
|
+
- [Realtime](./realtime.md)
|
|
44
|
+
- [API: Observer](../api/observer.md)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Templates
|
|
2
|
+
|
|
3
|
+
Templates let you compose, reuse, and organize HTML in your Webflo app using modern standards.
|
|
4
|
+
|
|
5
|
+
## The Mental Model
|
|
6
|
+
|
|
7
|
+
- Use HTML modules and imports to break your UI into reusable pieces.
|
|
8
|
+
- Bundle templates for efficient delivery and maintainability.
|
|
9
|
+
- Mix and match layouts: Multi Page, Single Page, or Multi SPA.
|
|
10
|
+
|
|
11
|
+
## Example: HTML Modules & Imports
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<!-- public/header.html -->
|
|
15
|
+
<header>Header Area</header>
|
|
16
|
+
|
|
17
|
+
<!-- public/index.html -->
|
|
18
|
+
<!DOCTYPE html>
|
|
19
|
+
<html>
|
|
20
|
+
<head>
|
|
21
|
+
<template def="app" src="/bundle.html"></template>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<import ref="app#header.html"></import>
|
|
25
|
+
<main>Welcome!</main>
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Bundling Templates
|
|
31
|
+
|
|
32
|
+
Use [oohtml-cli](https://github.com/webqit/oohtml-cli):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g @webqit/oohtml-cli
|
|
36
|
+
oohtml bundle --recursive --auto-embed=app
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Layout Patterns
|
|
40
|
+
|
|
41
|
+
- **Multi Page:** Each route has its own `index.html`.
|
|
42
|
+
- **Single Page:** One `index.html`, dynamic content via imports.
|
|
43
|
+
- **Multi SPA:** Hybrid; multiple roots, each with SPA subroutes.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
- [See Rendering →](./rendering.md)
|
|
48
|
+
- [See Lifecycle →](./lifecycle.md)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# Core Concepts
|
|
4
|
+
|
|
5
|
+
Welcome to the heart of Webflo. If you’ve ever wondered how modern web apps can feel so seamless—navigating between pages without reloads, updating in real time, and blending server and client logic—this is where the magic happens.
|
|
6
|
+
|
|
7
|
+
This page is your map to the core ideas that power every Webflo app. We’ll walk through the big concepts, show you how they fit together, and help you build the mental models you’ll need to create robust, maintainable, and delightful web experiences.
|
|
8
|
+
|
|
9
|
+
## Routing: How URLs Map to App Structure
|
|
10
|
+
|
|
11
|
+
Routing in Webflo is filesystem-based. Add a folder in the `app/` directory, and you’ve added a route. Each folder maps to a segment in your application’s URL structure; each with route handlers that run either server-side, client-side, or even service-worker-side. Webflo lets all these routes talk to each other to handle an incoming request.
|
|
12
|
+
|
|
13
|
+
**How it works:**
|
|
14
|
+
- `/` → `app/handler.server.js`
|
|
15
|
+
- `/about` → `app/about/handler.server.js`
|
|
16
|
+
- `/api/hello` → `app/api/hello/handler.server.js`
|
|
17
|
+
|
|
18
|
+
We'll meet this in [Routing →](./concepts/routing.md)
|
|
19
|
+
|
|
20
|
+
## Rendering: How Data Becomes UI
|
|
21
|
+
|
|
22
|
+
Rendering turns handler responses into visible UI. In Webflo, data from each request is automatically bound to the document — exposed at `document.bindings.data`, and automatically reflected in the UI. The flow goes as:<br>handler → data → `document.bindings.data` → UI<br> — whether rendering on the server or the client.
|
|
23
|
+
|
|
24
|
+
**How it works:**
|
|
25
|
+
- Handler returns data: `return { title, greeting };`
|
|
26
|
+
- You find it in the page at: `document.bindings.data`
|
|
27
|
+
- UI binds to it declaratively: `<h1><?{ data.greeting }?></h1>`
|
|
28
|
+
- It's rendered: `<h1>Hello!</h1>`
|
|
29
|
+
|
|
30
|
+
We'll meet this in [Rendering →](./concepts/rendering.md)
|
|
31
|
+
|
|
32
|
+
## Templates: Reusable HTML, Modern Standards
|
|
33
|
+
|
|
34
|
+
Templates come into play when you move beyond a single HTML file (`public/index.html`) to a dynamically composed UI. They’re just standard HTML templates — extended _just enough_ for data binding and composition. You define reusable markup via `<template def>`; you reuse anywhere via `<import ref>`. These form the building blocks of Webflo’s dynamic UI.
|
|
35
|
+
|
|
36
|
+
**How it works:**
|
|
37
|
+
|
|
38
|
+
- You define markup once and reuse everywhere.
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<template def="temp">
|
|
42
|
+
<h1><?{ data.greeting }?></h1>
|
|
43
|
+
</template>
|
|
44
|
+
```
|
|
45
|
+
```html
|
|
46
|
+
<import ref="temp"></import>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
We'll meet this in [Templates →](./concepts/templates.md)
|
|
50
|
+
|
|
51
|
+
## State, Mutation, & Reactivity: Webflo's First-Class Support for Mutation-Based Reactivity
|
|
52
|
+
|
|
53
|
+
Reactivity is intrinsic to Webflo — and the magic is no magic at all.<br>
|
|
54
|
+
Global state in a Webflo app lives at `document.bindings`. It's a *plain* JavaScript object that invites direct mutation — just like any object. The different parts of the app — including the UI — observe those mutations via the [Observer](https://github.com/webqit/observer) API. Everyone reacts as state changes.
|
|
55
|
+
|
|
56
|
+
**How it works:**
|
|
57
|
+
- `document.bindings` serves as the app’s central state
|
|
58
|
+
- The UI and other parts of the app bind to it
|
|
59
|
+
- State updates — either through direct mutation or in response to navigation events
|
|
60
|
+
- Mutation triggers reactivity across the app
|
|
61
|
+
|
|
62
|
+
We'll meet this in [State & Reactivity →](./concepts/state.md)
|
|
63
|
+
|
|
64
|
+
## Request/Response Lifecycle: The Web’s Communication Model
|
|
65
|
+
|
|
66
|
+
Every interaction on the web is a conversation: a request goes out, a response comes back, and the UI updates. Webflo lets you hook into every stage of that conversation — from interception to streaming — so you can orchestrate logic across the full lifecycle.
|
|
67
|
+
|
|
68
|
+
**How it works:**
|
|
69
|
+
- The browser sends a request to the server.
|
|
70
|
+
- The server responds with data (and/or HTML).
|
|
71
|
+
- The browser renders the UI based on the response.
|
|
72
|
+
|
|
73
|
+
We'll meet this in [Request/Response Lifecycle →](./concepts/lifecycle.md)
|
|
74
|
+
|
|
75
|
+
## Realtime: Keeping Everyone in Sync
|
|
76
|
+
|
|
77
|
+
Most apps need to stay live, connected, and consistent across all clients. Webflo apps work that way out of the box — via background messaging. A route handler can opt into background mode where it keeps a two-way communication channel with the client. Webflo keeps this connection open until the conversation is complete — extending the request/response lifecycle into a realtime stream. App works in realtime, with zero wiring.
|
|
78
|
+
|
|
79
|
+
**How it works:**
|
|
80
|
+
- Route handler receives a request and opts into background communication
|
|
81
|
+
- Webflo extends the connection into a realtime, two-way channel.
|
|
82
|
+
- Handler and client stay in sync; app works live.
|
|
83
|
+
|
|
84
|
+
We'll meet this in [Realtime features →](./concepts/realtime.md)
|
|
85
|
+
|
|
86
|
+
## Next Steps
|
|
87
|
+
|
|
88
|
+
You’ve just walked through Webflo’s conceptual arc — from **Routing → UI → State → Continuity**.
|
|
89
|
+
|
|
90
|
+
Next is to explore each concept in detail, in the same order. Together they form the foundation for everything you’ll build with Webflo.
|
|
91
|
+
|
|
92
|
+
* [Routing](./concepts/routing.md): How URLs map to your app’s logic and structure.
|
|
93
|
+
* [Rendering](./concepts/rendering.md): How data becomes interactive UI.
|
|
94
|
+
* [Templates](./concepts/templates.md): How markup becomes composable and reusable.
|
|
95
|
+
* [State & Reactivity](./concepts/state.md): How mutation and reactivity unify server and client.
|
|
96
|
+
* [Request/Response Lifecycle](./concepts/lifecycle.md): How every interaction flows through Webflo.
|
|
97
|
+
* [Realtime](./concepts/realtime.md): How the cycle extends into continuous connection.
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# Getting Started with Webflo
|
|
2
|
+
|
|
3
|
+
Welcome! This guide will help you build your first Webflo app from scratch and get it running in minutes, even if you’ve never used the framework before. You’ll learn not just the “how,” but the “why”—and see your results live in the browser.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- **Node.js** 18+ installed
|
|
8
|
+
- Basic knowledge of HTML, CSS, and JavaScript
|
|
9
|
+
- A terminal/command line interface
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
### Option 1: Global Installation (Recommended)
|
|
14
|
+
|
|
15
|
+
Install Webflo globally to use the CLI from anywhere:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @webqit/webflo
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Option 2: Local Installation
|
|
22
|
+
|
|
23
|
+
Install Webflo as a dependency in your project:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @webqit/webflo
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The scope you choose will determine how you run Webflo commands. The Webflo commands in the rest of this page will show in both `global` and `local` styles.
|
|
30
|
+
|
|
31
|
+
## Creating a New Project
|
|
32
|
+
|
|
33
|
+
Webflo provides a CLI command to scaffold new projects:
|
|
34
|
+
|
|
35
|
+
::: code-group
|
|
36
|
+
|
|
37
|
+
```bash [global]
|
|
38
|
+
webflo init my-webflo-app
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```bash [local]
|
|
42
|
+
npx webflo init my-webflo-app
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
:::
|
|
46
|
+
|
|
47
|
+
This will create a new directory called `my-webflo-app` with a basic Webflo project structure.
|
|
48
|
+
|
|
49
|
+
::: tip What happens?
|
|
50
|
+
- A starter project is scaffolded from the selected template
|
|
51
|
+
- Minimal scripts are added to `package.json`
|
|
52
|
+
- Public assets and the `app/` directory are created
|
|
53
|
+
:::
|
|
54
|
+
|
|
55
|
+
### Create Options
|
|
56
|
+
|
|
57
|
+
The above command could take a project title and project description too:
|
|
58
|
+
|
|
59
|
+
::: code-group
|
|
60
|
+
|
|
61
|
+
```bash [global]
|
|
62
|
+
webflo init my-webflo-app "My Webflo App" "My first ever Webflo app"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```bash [local]
|
|
66
|
+
npx webflo init my-webflo-app "My Webflo App" "My first ever Webflo app"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
:::
|
|
70
|
+
|
|
71
|
+
And you can specify a template to use:
|
|
72
|
+
|
|
73
|
+
::: code-group
|
|
74
|
+
|
|
75
|
+
```bash [global]
|
|
76
|
+
webflo init my-webflo-app --template=web
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```bash [local]
|
|
80
|
+
npx webflo init my-webflo-app --template=web
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
:::
|
|
84
|
+
|
|
85
|
+
The default is: `web`.
|
|
86
|
+
|
|
87
|
+
### Available Templates
|
|
88
|
+
|
|
89
|
+
Webflo comes with built-in templates:
|
|
90
|
+
|
|
91
|
+
- **web** - Standard web application template.<br>Choose for a minimal, conventional web app
|
|
92
|
+
- **pwa** - Progressive Web App template with service worker.<br>Choose if you want service worker and offline features from the start
|
|
93
|
+
|
|
94
|
+
Templates are just starting points — they can evolve and expand freely as your project grows.
|
|
95
|
+
|
|
96
|
+
### Project Structure
|
|
97
|
+
|
|
98
|
+
After initialization, your project will have the following structure:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
my-webflo-app/
|
|
102
|
+
├── app/
|
|
103
|
+
│ ├── handler.server.js # Server-side route handlers
|
|
104
|
+
│ └── page.html # Page template
|
|
105
|
+
├── public/
|
|
106
|
+
│ ├── assets/
|
|
107
|
+
│ │ └── app.css # Styles
|
|
108
|
+
│ ├── index.html # Entry point
|
|
109
|
+
│ └── manifest.json # PWA manifest (if using PWA template)
|
|
110
|
+
├── package.json
|
|
111
|
+
└── .webflo/ # Webflo configuration (generated)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Note that this is only typical. A few things will vary depending on your chosen template.
|
|
115
|
+
|
|
116
|
+
### Example `package.json` Structure
|
|
117
|
+
|
|
118
|
+
The generated `package.json` for your project will include scripts like `dev`, `build`, `start`, among others:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"scripts": {
|
|
123
|
+
"dev": "webflo start --dev",
|
|
124
|
+
"build": "webflo build",
|
|
125
|
+
"start": "webflo start"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
<details><summary>Click here to see a more typical <code>package.json</code> that may be generated for you.</summary>
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
{
|
|
134
|
+
"title": "My Webflo App", // Human-readable title; set during init, auto-derived from name if omitted; used in templates/UI
|
|
135
|
+
"name": "my-webflo-app", // npm package name; set during init
|
|
136
|
+
"description": "My first ever Webflo app", // Shown in package managers and can be surfaced in UI
|
|
137
|
+
"version": "1.0.0", // Your app version; semver recommended
|
|
138
|
+
"type": "module", // Use ES modules; Webflo tooling expects ESM
|
|
139
|
+
"scripts": {
|
|
140
|
+
// Builds HTML templates and client bundles into public/assets
|
|
141
|
+
"build:html": "oohtml bundle --recursive --outdir=public/assets --auto-embed=app",
|
|
142
|
+
"build:js": "webflo generate::client --recursive --outdir=public/assets --auto-embed",
|
|
143
|
+
// Production build: runs both steps
|
|
144
|
+
"build": "npm run build:html && npm run build:js",
|
|
145
|
+
// Development server with auto-rebuilds and fine-grained HMR
|
|
146
|
+
"dev": "webflo start --dev --build-sensitivity=2",
|
|
147
|
+
// Production server
|
|
148
|
+
"start": "webflo start"
|
|
149
|
+
},
|
|
150
|
+
"dependencies": {
|
|
151
|
+
// Use a semver range for stability in standalone apps
|
|
152
|
+
"@webqit/webflo": "^1"
|
|
153
|
+
},
|
|
154
|
+
"devDependencies": {
|
|
155
|
+
// CLI used to bundle HTML templates; semver range preferred over "latest"
|
|
156
|
+
"@webqit/oohtml-cli": "^2"
|
|
157
|
+
},
|
|
158
|
+
// Optional: constrain Node.js versions used to run your app
|
|
159
|
+
// "engines": { "node": ">=18" }
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> Note that this is only typical. A few things will vary depending on your chosen template.
|
|
164
|
+
|
|
165
|
+
</details>
|
|
166
|
+
|
|
167
|
+
You can customize as necessary.
|
|
168
|
+
|
|
169
|
+
::: info Scripts & customization
|
|
170
|
+
- You can customize `build:html` or `build:js` scripts if you need finer control
|
|
171
|
+
- Add a `build:css` script if your CSS requires a build step; it'll be called in dev mode as necessary on CSS file changes
|
|
172
|
+
- Adjust dev mode's rebuild frequency for assets with `--build-sensitivity` (e.g., `--build-sensitivity=2` — to defer rebuild until page reload; `0` — to turn off)
|
|
173
|
+
:::
|
|
174
|
+
|
|
175
|
+
## Running Your Application
|
|
176
|
+
|
|
177
|
+
Your Webflo app will run in either *dev* mode or *production* mode.
|
|
178
|
+
|
|
179
|
+
### Development Mode
|
|
180
|
+
|
|
181
|
+
Start the development server:
|
|
182
|
+
|
|
183
|
+
::: code-group
|
|
184
|
+
|
|
185
|
+
```bash [global]
|
|
186
|
+
webflo start --dev
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash [npm]
|
|
190
|
+
npm run dev
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
:::
|
|
194
|
+
|
|
195
|
+
The server starts on `http://localhost:3000` by default.
|
|
196
|
+
|
|
197
|
+
::: tip What happens? (dev)
|
|
198
|
+
- Webflo runs in development mode (with smart, incremental rebuilds on relevant file changes)
|
|
199
|
+
- Fine-grained HMR applies updates without full page reloads when possible
|
|
200
|
+
- Static assets are served from `public/`; routes resolve from `app/`
|
|
201
|
+
- Logs and errors appear in your terminal
|
|
202
|
+
:::
|
|
203
|
+
|
|
204
|
+
### Development Options
|
|
205
|
+
|
|
206
|
+
- `--open` - Automatically open the browser
|
|
207
|
+
- `--port <port>` - Specify a different port
|
|
208
|
+
|
|
209
|
+
::: code-group
|
|
210
|
+
|
|
211
|
+
```bash [global]
|
|
212
|
+
webflo start --dev --open --port 8080
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```bash [npm]
|
|
216
|
+
npm run dev -- --open --port 8080
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
:::
|
|
220
|
+
|
|
221
|
+
### Webflo Build
|
|
222
|
+
|
|
223
|
+
Build your application's client-side assets — `.js`, `.html`, and optionally `.css` (if `build:css` is configured above in `package.json`):
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm run build
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
This generates optimized static assets and bundles for the client-side of your app.
|
|
230
|
+
|
|
231
|
+
::: tip What happens? (build)
|
|
232
|
+
- Client bundles are generated — `.js`→`public/app.js`, `.html`→`public/app.html`
|
|
233
|
+
- Asset references are injected into `public/index.html`
|
|
234
|
+
- Output is optimized for production
|
|
235
|
+
:::
|
|
236
|
+
|
|
237
|
+
In *dev* mode, this is not required as Webflo already kicks in Hot Module Replacement (HMR) as you make changes to JS, HTML, and CSS files. But feel free to build as you deem fit.
|
|
238
|
+
|
|
239
|
+
### Production Mode
|
|
240
|
+
|
|
241
|
+
Start the production server when ready:
|
|
242
|
+
|
|
243
|
+
::: code-group
|
|
244
|
+
|
|
245
|
+
```bash [global]
|
|
246
|
+
webflo start
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```bash [npm]
|
|
250
|
+
npm start
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Your app runs in production mode. Production can be in any filesystem-enabled JavaScript runtime.
|
|
254
|
+
|
|
255
|
+
::: warning Production differences
|
|
256
|
+
- No HMR; assets are cached aggressively by browsers/CDNs
|
|
257
|
+
- Ensure environment variables are set (e.g., via `.env` or host config)
|
|
258
|
+
- Re-run `webflo build` after code changes intended for production
|
|
259
|
+
:::
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
::: tip Good Progress
|
|
264
|
+
At this point, your app is open in the browser — time to actually build what we'll see!
|
|
265
|
+
:::
|
|
266
|
+
|
|
267
|
+
## Your First Route Handler
|
|
268
|
+
|
|
269
|
+
Open `app/handler.server.js` — the default handler file generated for you. You’ll see something like:
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
export default async function (event, next, fetch) {
|
|
273
|
+
if (next.stepname) return await next();
|
|
274
|
+
return {
|
|
275
|
+
title: 'Webflo Web',
|
|
276
|
+
greeting: 'Hello World!',
|
|
277
|
+
menu: [{ title: 'Home', href: '/' }],
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**What’s it doing?**
|
|
283
|
+
|
|
284
|
+
- This function handles requests to `/` (the root URL).
|
|
285
|
+
- If there’s a deeper route, it delegates to a sub-handler with `next()`.
|
|
286
|
+
- Otherwise, it returns data for the root page.
|
|
287
|
+
|
|
288
|
+
You can build from here — and make it your own:
|
|
289
|
+
|
|
290
|
+
```js
|
|
291
|
+
export default async function (event, next, fetch) {
|
|
292
|
+
if (next.stepname) return await next();
|
|
293
|
+
const name = event.url.searchParams.get('name') || 'World';
|
|
294
|
+
return {
|
|
295
|
+
title: 'Webflo Web',
|
|
296
|
+
greeting: `Hello ${name}!`,
|
|
297
|
+
menu: [{ title: 'Home', href: '/' }],
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Visit `http://localhost:3000/?name=Webflo` to see the response.
|
|
303
|
+
|
|
304
|
+
If that worked, then we're ready to build! 🚀 We'll build on this foundation incrementally.
|
|
305
|
+
|
|
306
|
+
## Working with Static Files
|
|
307
|
+
|
|
308
|
+
Place static files in the `public/` directory. They'll be served automatically by Webflo's static file server. Directory stucture automatically maps to URL paths:
|
|
309
|
+
|
|
310
|
+
- `public/index.html` → `http://localhost:3000/index.html`
|
|
311
|
+
- `public/assets/logo.png` → `http://localhost:3000/assets/logo.png`
|
|
312
|
+
- `public/style.css` → `http://localhost:3000/style.css`
|
|
313
|
+
|
|
314
|
+
Webflo automatically adds appropriate content and caching headers depending on the request. Not found files generate a `404` response.
|
|
315
|
+
|
|
316
|
+
::: warning Static file handoff
|
|
317
|
+
- To leverage Webflo's static file serving, ensure that route handlers are appropriately delegating incoming requests that they're not specifically designed to handle
|
|
318
|
+
- This is the handoff line — `if (next.stepname) return next()` — you see in our handler above
|
|
319
|
+
- This design, however, ensures route handlers are first in control
|
|
320
|
+
:::
|
|
321
|
+
|
|
322
|
+
## Next Steps
|
|
323
|
+
|
|
324
|
+
You’ve:
|
|
325
|
+
|
|
326
|
+
- Scaffolded a project
|
|
327
|
+
- Started the dev server
|
|
328
|
+
- Written your first handler
|
|
329
|
+
- Rendered data in the UI
|
|
330
|
+
|
|
331
|
+
**Where to go from here?**
|
|
332
|
+
|
|
333
|
+
- [Core Concepts](/docs/concepts) — Mental model for how everything fits together
|
|
334
|
+
- [Routing](/docs/concepts/routing) — How URLs map to files and handlers
|
|
335
|
+
- [Rendering](/docs/concepts/rendering) — How data becomes UI
|
|
336
|
+
- [Templates](/docs/concepts/templates) — Composing and reusing HTML
|
|
337
|
+
- [API Reference](/api/webflo-routing/handler) — Formal handler contract
|
|
338
|
+
|
|
339
|
+
## Common Commands
|
|
340
|
+
|
|
341
|
+
<details><summary>Here's a quick reference (Click to show)</summary>
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# Initialize a new project
|
|
345
|
+
webflo init <project-name>
|
|
346
|
+
|
|
347
|
+
# Start development server
|
|
348
|
+
webflo start --dev
|
|
349
|
+
|
|
350
|
+
# Start production server
|
|
351
|
+
webflo start
|
|
352
|
+
|
|
353
|
+
# Build for production
|
|
354
|
+
webflo build
|
|
355
|
+
|
|
356
|
+
# Configure Webflo
|
|
357
|
+
webflo config
|
|
358
|
+
|
|
359
|
+
# View help
|
|
360
|
+
webflo --help
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
</details>
|
|
364
|
+
|
|
365
|
+
## Troubleshooting
|
|
366
|
+
|
|
367
|
+
- Port already in use?: pass `--port <port>` (e.g., `webflo start --dev --port 8080`)
|
|
368
|
+
- Global install issues?: use local CLI via `npx webflo ...` or `npm run` scripts
|
|
369
|
+
- Permission problems on Unix?: try `corepack enable` or use a node version manager (nvm)
|
|
370
|
+
- Edits not reflecting?: ensure you reloaded or are running dev mode; for production, run `webflo build` again
|
|
371
|
+
|
|
372
|
+
## Getting Help
|
|
373
|
+
|
|
374
|
+
- Browse the [Documentation](/docs)
|
|
375
|
+
- Visit [GitHub Issues](https://github.com/webqit/webflo/issues)
|
|
376
|
+
- Review the [API Reference](/api)
|
|
377
|
+
|
|
378
|
+
Happy coding with Webflo! 🚀
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# The Technology Stack
|
|
2
|
+
|
|
3
|
+
This part covers the technologies that make up the Webflo stack.
|
|
4
|
+
|
|
5
|
+
## Platform APIs
|
|
6
|
+
|
|
7
|
+
Webflo is *deeply* integrated with how the web already works. It leans on standard web platform APIs so your code stays portable and predictable. Key platform APIs used by Webflo include:
|
|
8
|
+
|
|
9
|
+
| Feature | Why it matters | Link |
|
|
10
|
+
|:---|:---|:---|
|
|
11
|
+
| Request | Network primitive for making outgoing requests. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Request) |
|
|
12
|
+
| Response | Representation of responses returned from network requests. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response) |
|
|
13
|
+
| Headers | Structured metadata for requests and responses. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Headers) |
|
|
14
|
+
| Streams | Enables streaming bodies for incremental rendering and transfer. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) |
|
|
15
|
+
| URL | Robust URL parsing for canonicalization and routing. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/URL) |
|
|
16
|
+
| URLPattern | Route pattern matching for routing logic. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) |
|
|
17
|
+
| DOM | Native markup primitives for composing and rendering UI. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) |
|
|
18
|
+
| \<template\> element | Reusable template primitive for composition and SSR/CSR. | [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) |
|
|
19
|
+
| ReadableStream | Incremental consumption of streaming data. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) |
|
|
20
|
+
| WritableStream | Incremental production of streaming data. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream) |
|
|
21
|
+
| Service Worker API | Background routing, caching, and offline capabilities. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) |
|
|
22
|
+
| MessageChannel | Bidirectional messaging for realtime/background features. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel) |
|
|
23
|
+
| FormData | Native type for multipart form uploads and form handling. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/FormData) |
|
|
24
|
+
| Blob | Binary data container for transfers and file blobs. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Blob) |
|
|
25
|
+
| File | Represents filesystem-backed file uploads. | [MDN](https://developer.mozilla.org/en-US/docs/Web/API/File) |
|
|
26
|
+
|
|
27
|
+
## The Observer API
|
|
28
|
+
|
|
29
|
+
Reactivity in Webflo is powered by the [Observer API](https://github.com/webqit/observer)
|
|
30
|
+
— a lightweight, general-purpose API for observing JavaScript objects and arrays.
|
|
31
|
+
|
|
32
|
+
With the Observer API unlocking observability at the object and array level, no special interfaces or wrappers are needed for reactivity anywhere in the stack. Webflo simply runs on bare objects, bare arrays, and the concept of mutation — all plain JavaScript primitives. For a framework, this sets a new benchmark in _just using the language_ — one we intend to preserve.
|
|
33
|
+
|
|
34
|
+
As a developer, you get a clean technology stack that's all just plain objects and arrays too - stripped of special programming interfaces like WebfloStore, WebfloReduxAdapter, WebfloReactiveProxyThingAdapter, etc. Often these exist in other frameworks as a means to reactivity, guarded with measures against mutability since that breaks their reactive model.
|
|
35
|
+
|
|
36
|
+
By making mutation a first-class concept, as it is in JavaScript itself, Webflo helps you see the world as it is — dynamic, mutable, powerful, free.
|
|
37
|
+
|
|
38
|
+
Meet the [Observer API →](https://github.com/webqit/observer)
|
|
39
|
+
|
|
40
|
+
## OOHTML
|
|
41
|
+
|
|
42
|
+
OOHTML is the lightweight, buildless markup layer Webflo uses for composing UI. Its role in the stack is simple and decisive: make HTML modular, importable, and data-aware so authors can ship interactive apps without a heavy toolchain.
|
|
43
|
+
|
|
44
|
+
How it simplifies everything:
|
|
45
|
+
- Buildless composition: authors write plain HTML (templates + imports) instead of compiling a new component language — fewer build steps, fewer surprises.
|
|
46
|
+
- Portable markup: the same template files work for SSR and CSR, so your UI source is the single truth.
|
|
47
|
+
- Low cognitive load: conventional HTML authoring, with a few additive conventions (imports, `def`/`ref`, scoped styles/scripts) instead of an entire framework DSL.
|
|
48
|
+
- First-class data plumbing: OOHTML directly binds to your app's `document.bindings` and the Observer API for hydration and reactive updates.
|
|
49
|
+
|
|
50
|
+
What OOHTML gives you (at a glance):
|
|
51
|
+
- Declarative HTML imports and modular templates — reuse without build tooling.
|
|
52
|
+
- Namespacing, and style and script scoping to avoid global collisions.
|
|
53
|
+
- Comment-based and inline data binding that degrades cleanly in SSR.
|
|
54
|
+
- Imperative import APIs for dynamic or lazy module loading.
|
|
55
|
+
|
|
56
|
+
Meet [OOHTML →](https://github.com/webqit/oohtml)
|