@async/framework 0.10.2 → 0.11.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +23 -7
  3. package/browser.d.ts +4 -7
  4. package/browser.js +17 -66
  5. package/browser.min.js +1 -1
  6. package/browser.ts +17 -66
  7. package/browser.umd.js +17 -66
  8. package/browser.umd.min.js +1 -1
  9. package/{server.d.ts → framework.d.ts} +4 -7
  10. package/framework.ts +5946 -0
  11. package/package.json +25 -17
  12. package/server.js +5945 -0
  13. package/examples/cache/index.html +0 -16
  14. package/examples/cache/main.js +0 -47
  15. package/examples/components/index.html +0 -11
  16. package/examples/components/main.js +0 -26
  17. package/examples/counter/index.html +0 -15
  18. package/examples/counter/main.js +0 -17
  19. package/examples/partials/index.html +0 -15
  20. package/examples/partials/main.js +0 -43
  21. package/examples/product/index.html +0 -32
  22. package/examples/product/main.js +0 -24
  23. package/examples/router/index.html +0 -18
  24. package/examples/router/main.js +0 -52
  25. package/examples/server-call/index.html +0 -21
  26. package/examples/server-call/main.js +0 -22
  27. package/examples/ssr/index.html +0 -12
  28. package/examples/ssr/main.js +0 -89
  29. package/examples/streaming/index.html +0 -16
  30. package/examples/streaming/main.js +0 -30
  31. package/src/app.js +0 -802
  32. package/src/async-signal.js +0 -277
  33. package/src/attributes.js +0 -52
  34. package/src/boundary-receiver.js +0 -302
  35. package/src/browser.js +0 -18
  36. package/src/cache.js +0 -193
  37. package/src/component.js +0 -373
  38. package/src/delay.js +0 -30
  39. package/src/elements.js +0 -63
  40. package/src/handlers.js +0 -219
  41. package/src/html.js +0 -158
  42. package/src/index.js +0 -20
  43. package/src/lazy-registry.js +0 -218
  44. package/src/loader.js +0 -772
  45. package/src/partials.js +0 -133
  46. package/src/registry-store.js +0 -267
  47. package/src/request-context.js +0 -40
  48. package/src/router.js +0 -617
  49. package/src/scheduler.js +0 -300
  50. package/src/server-entry.js +0 -20
  51. package/src/server-registry.js +0 -97
  52. package/src/server.js +0 -362
  53. package/src/signals.js +0 -592
@@ -1,16 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Async Loader Cache</title>
7
- </head>
8
- <body>
9
- <main async:container>
10
- <button type="button" on:click="cacheDemo.loadProduct">Load product</button>
11
- <p>Product: <strong signal:text="cacheDemo.title"></strong></p>
12
- <p>Server calls: <strong signal:text="cacheDemo.calls"></strong></p>
13
- </main>
14
- <script type="module" src="./main.js"></script>
15
- </body>
16
- </html>
@@ -1,47 +0,0 @@
1
- import {
2
- Async,
3
- createSignal,
4
- defineCache
5
- } from "../../src/index.js";
6
-
7
- Async.use({
8
- signal: {
9
- cacheDemo: createSignal({
10
- productId: "sku-1",
11
- title: "",
12
- calls: 0
13
- })
14
- },
15
- cache: {
16
- browser: {
17
- "cacheDemo.product": defineCache({ ttl: 60_000 })
18
- },
19
- server: {
20
- "cacheDemo.products.get": defineCache({ ttl: 30_000 })
21
- }
22
- },
23
- server: {
24
- async "cacheDemo.products.get"(id) {
25
- return this.cache.getOrSet(`cacheDemo.products:${id}`, () => {
26
- return {
27
- id,
28
- title: "Cached Keyboard",
29
- calls: this.signals.get("cacheDemo.calls") + 1
30
- };
31
- }, { cache: "cacheDemo.products.get" });
32
- }
33
- },
34
- handler: {
35
- async "cacheDemo.loadProduct"() {
36
- const id = this.signals.get("cacheDemo.productId");
37
- const product = await this.cache.getOrSet(`cacheDemo.product:${id}`, () => {
38
- return this.server.cacheDemo.products.get(id);
39
- }, { cache: "cacheDemo.product" });
40
-
41
- this.signals.set("cacheDemo.title", product.title);
42
- this.signals.set("cacheDemo.calls", product.calls);
43
- }
44
- }
45
- });
46
-
47
- Async.start({ root: document, router: false });
@@ -1,11 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Async Loader Components</title>
6
- </head>
7
- <body>
8
- <main id="app"></main>
9
- <script type="module" src="./main.js"></script>
10
- </body>
11
- </html>
@@ -1,26 +0,0 @@
1
- import { Loader, defineComponent, html } from "../../src/index.js";
2
-
3
- const Toggle = defineComponent(function Toggle() {
4
- const selected = this.signal(false);
5
- const attach = this.handler("attach", function ({ element }) {
6
- element.dataset.attached = "true";
7
- });
8
-
9
- return html`
10
- <button
11
- type="button"
12
- on:attach="${attach}"
13
- on:click="${this.handler(function () {
14
- selected.update((value) => !value);
15
- })}"
16
- class:selected="${selected}"
17
- signal:class="${["toggle", { active: selected }]}"
18
- signal:attr:aria-pressed="${selected}"
19
- >
20
- Toggle
21
- </button>
22
- `;
23
- });
24
-
25
- const loader = Loader({ root: document });
26
- loader.mount(document.querySelector("#app"), Toggle);
@@ -1,15 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Async Loader Counter</title>
6
- </head>
7
- <body async:container>
8
- <main>
9
- <p>Count: <strong signal:text="counter.count"></strong></p>
10
- <button type="button" on:click="counter.decrement">-</button>
11
- <button type="button" on:click="counter.increment">+</button>
12
- </main>
13
- <script type="module" src="./main.js"></script>
14
- </body>
15
- </html>
@@ -1,17 +0,0 @@
1
- import { Async, createSignal } from "../../src/index.js";
2
-
3
- Async.use({
4
- signal: {
5
- counter: createSignal({ count: 0 })
6
- },
7
- handler: {
8
- "counter.increment"() {
9
- this.signals.update("counter.count", (count) => count + 1);
10
- },
11
- "counter.decrement"() {
12
- this.signals.update("counter.count", (count) => count - 1);
13
- }
14
- }
15
- });
16
-
17
- Async.start({ root: document.body, router: false });
@@ -1,15 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Async Loader Partials</title>
7
- </head>
8
- <body>
9
- <main async:container>
10
- <button type="button" on:click="partialsDemo.loadProduct">Load product</button>
11
- <section async:boundary="product"></section>
12
- </main>
13
- <script type="module" src="./main.js"></script>
14
- </body>
15
- </html>
@@ -1,43 +0,0 @@
1
- import {
2
- Async,
3
- html
4
- } from "../../src/index.js";
5
-
6
- let runtime;
7
-
8
- Async.use({
9
- server: {
10
- "partialsDemo.products.get"(id) {
11
- return {
12
- value: {
13
- id,
14
- title: "Keyboard"
15
- }
16
- };
17
- }
18
- },
19
- partial: {
20
- "partialsDemo.product.card": async function ({ id }) {
21
- const product = await this.server.partialsDemo.products.get(id);
22
- return html`
23
- <article>
24
- <h1>${product.title}</h1>
25
- <p>${product.id}</p>
26
- </article>
27
- `;
28
- }
29
- },
30
- handler: {
31
- async "partialsDemo.loadProduct"() {
32
- const result = await runtime.partials.render("partialsDemo.product.card", { id: "sku-1" }, {
33
- cache: this.cache,
34
- loader: this.loader,
35
- server: this.server,
36
- signals: this.signals
37
- });
38
- this.loader.swap("product", result.html);
39
- }
40
- }
41
- });
42
-
43
- runtime = Async.start({ root: document, router: false });
@@ -1,32 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Async Loader Product</title>
6
- </head>
7
- <body async:container>
8
- <main>
9
- <label>
10
- Product
11
- <select signal:value="productId">
12
- <option value="sku-1">Mechanical Keyboard</option>
13
- <option value="sku-2">Studio Headphones</option>
14
- </select>
15
- </label>
16
-
17
- <section async:boundary="product">
18
- <template async:loading="product">
19
- <p>Loading product...</p>
20
- </template>
21
- <template async:ready="product">
22
- <h1 signal:text="product.title"></h1>
23
- <p signal:text="product.description"></p>
24
- </template>
25
- <template async:error="product">
26
- <p signal:text="product.$error.message"></p>
27
- </template>
28
- </section>
29
- </main>
30
- <script type="module" src="./main.js"></script>
31
- </body>
32
- </html>
@@ -1,24 +0,0 @@
1
- import { Loader, createSignal, createSignalRegistry, delay } from "../../src/index.js";
2
-
3
- const products = {
4
- "sku-1": {
5
- title: "Mechanical Keyboard",
6
- description: "A compact keyboard loaded through an async signal."
7
- },
8
- "sku-2": {
9
- title: "Studio Headphones",
10
- description: "Closed-back headphones loaded through the same boundary."
11
- }
12
- };
13
-
14
- const signals = createSignalRegistry({
15
- productId: createSignal("sku-1")
16
- });
17
-
18
- signals.asyncSignal("product", async function () {
19
- const id = this.signals.get("productId");
20
- await delay(150, this.abort);
21
- return products[id];
22
- });
23
-
24
- Loader({ root: document.body, signals }).start();
@@ -1,18 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Async Loader CSR Router</title>
7
- </head>
8
- <body>
9
- <main async:container>
10
- <nav>
11
- <a href="/">Home</a>
12
- <a href="/products/sku-1">Product</a>
13
- </nav>
14
- <section async:boundary="route"></section>
15
- </main>
16
- <script type="module" src="./main.js"></script>
17
- </body>
18
- </html>
@@ -1,52 +0,0 @@
1
- import {
2
- Async,
3
- createSignal,
4
- defineRoute,
5
- html
6
- } from "../../src/index.js";
7
-
8
- Async.use({
9
- signal: {
10
- routerDemo: createSignal({
11
- productId: "sku-1",
12
- cartCount: 0
13
- })
14
- },
15
- server: {
16
- "routerDemo.cart.add"(productId) {
17
- return {
18
- value: { productId },
19
- signals: {
20
- "routerDemo.cartCount": 1
21
- }
22
- };
23
- }
24
- },
25
- partial: {
26
- "routerDemo.home"() {
27
- return html`
28
- <h1>Home</h1>
29
- <p>Cart: <strong signal:text="routerDemo.cartCount"></strong></p>
30
- `;
31
- },
32
- "routerDemo.product.page"({ id }) {
33
- return html`
34
- <article>
35
- <h1>Product ${id}</h1>
36
- <p>Cart: <strong signal:text="routerDemo.cartCount"></strong></p>
37
- <button type="button" on:click="server.routerDemo.cart.add(routerDemo.productId)">Add</button>
38
- </article>
39
- `;
40
- }
41
- },
42
- route: {
43
- "/": defineRoute("routerDemo.home"),
44
- "/products/:id": defineRoute("routerDemo.product.page")
45
- }
46
- });
47
-
48
- Async.start({
49
- mode: "csr",
50
- root: document,
51
- boundary: "route"
52
- });
@@ -1,21 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Async Loader Server Call</title>
7
- </head>
8
- <body>
9
- <main async:container>
10
- <form on:submit="preventDefault; server.serverCall.products.save(serverCall.productId, $form)">
11
- <label>
12
- Title
13
- <input name="title" value="Keyboard">
14
- </label>
15
- <button type="submit">Save</button>
16
- </form>
17
- <p>Saved: <strong signal:text="serverCall.savedTitle"></strong></p>
18
- </main>
19
- <script type="module" src="./main.js"></script>
20
- </body>
21
- </html>
@@ -1,22 +0,0 @@
1
- import { Async, createSignal } from "../../src/index.js";
2
-
3
- Async.use({
4
- signal: {
5
- serverCall: createSignal({
6
- productId: "sku-1",
7
- savedTitle: ""
8
- })
9
- },
10
- server: {
11
- "serverCall.products.save"(productId, form) {
12
- return {
13
- value: { id: productId, ...form },
14
- signals: {
15
- "serverCall.savedTitle": form.title
16
- }
17
- };
18
- }
19
- }
20
- });
21
-
22
- Async.start({ root: document, router: false });
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Async Loader SSR Activation</title>
7
- </head>
8
- <body>
9
- <main id="app" async:container></main>
10
- <script type="module" src="./main.js"></script>
11
- </body>
12
- </html>
@@ -1,89 +0,0 @@
1
- import {
2
- createApp,
3
- createSignal,
4
- defineApp,
5
- defineCache,
6
- defineRoute,
7
- html
8
- } from "../../src/index.js";
9
-
10
- function sharedDefinition() {
11
- return {
12
- signal: {
13
- ssrDemo: createSignal({
14
- productId: null,
15
- selected: false
16
- })
17
- },
18
- cache: {
19
- browser: {
20
- "ssrDemo.product": defineCache({ ttl: 60_000 })
21
- }
22
- },
23
- handler: {
24
- "ssrDemo.selectProduct"() {
25
- this.signals.set("ssrDemo.selected", true);
26
- }
27
- },
28
- route: {
29
- "/ssr/:id": defineRoute("ssrDemo.product.page")
30
- }
31
- };
32
- }
33
-
34
- const serverApp = defineApp(sharedDefinition());
35
- serverApp.use({
36
- cache: {
37
- server: {
38
- "ssrDemo.products.get": defineCache({ ttl: 30_000 })
39
- }
40
- },
41
- server: {
42
- async "ssrDemo.products.get"(id) {
43
- return this.cache.getOrSet(`ssrDemo.products:${id}`, () => {
44
- return {
45
- id,
46
- title: "SSR Keyboard"
47
- };
48
- }, { cache: "ssrDemo.products.get" });
49
- }
50
- },
51
- partial: {
52
- async "ssrDemo.product.page"({ id }) {
53
- const product = await this.server.ssrDemo.products.get(id);
54
- return {
55
- html: html`
56
- <article>
57
- <h1>${product.title}</h1>
58
- <p>${product.id}</p>
59
- <button type="button" on:click="ssrDemo.selectProduct" class:selected="ssrDemo.selected">
60
- Select
61
- </button>
62
- </article>
63
- `,
64
- signals: {
65
- "ssrDemo.productId": id
66
- },
67
- cache: {
68
- browser: {
69
- [`ssrDemo.product:${id}`]: product
70
- }
71
- }
72
- };
73
- }
74
- }
75
- });
76
-
77
- const serverRuntime = createApp(serverApp, { target: "server" });
78
- const response = await serverRuntime.render("/ssr/sku-1");
79
- serverRuntime.destroy();
80
-
81
- document.querySelector("#app").innerHTML = response.html;
82
-
83
- const snapshot = JSON.parse(document.querySelector("[async\\:snapshot]").textContent);
84
- const browserApp = defineApp(sharedDefinition());
85
- createApp(browserApp, {
86
- root: document,
87
- router: false,
88
- snapshot
89
- }).start();
@@ -1,16 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Async Loader Streaming</title>
6
- </head>
7
- <body async:container>
8
- <main>
9
- <button type="button" on:click="streamingDemo.streamProduct">Stream product</button>
10
- <section async:boundary="product">
11
- <p>Waiting for streamed HTML...</p>
12
- </section>
13
- </main>
14
- <script type="module" src="./main.js"></script>
15
- </body>
16
- </html>
@@ -1,30 +0,0 @@
1
- import { Async, createSignal } from "../../src/index.js";
2
-
3
- Async.use({
4
- signal: {
5
- streamingDemo: createSignal({
6
- title: "Streamed Keyboard",
7
- selected: false
8
- })
9
- },
10
- handler: {
11
- "streamingDemo.streamProduct"() {
12
- this.loader.swap(
13
- "product",
14
- `
15
- <article>
16
- <h1 signal:text="streamingDemo.title"></h1>
17
- <button type="button" on:click="streamingDemo.select" class:selected="streamingDemo.selected">
18
- Select
19
- </button>
20
- </article>
21
- `
22
- );
23
- },
24
- "streamingDemo.select"() {
25
- this.signals.set("streamingDemo.selected", true);
26
- }
27
- }
28
- });
29
-
30
- Async.start({ root: document.body, router: false });