@async/framework 0.5.0 → 0.7.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/CHANGELOG.md +32 -0
- package/README.md +64 -9
- package/examples/cache/index.html +1 -1
- package/examples/components/index.html +1 -1
- package/examples/components/main.js +2 -2
- package/examples/counter/index.html +1 -1
- package/examples/partials/index.html +1 -1
- package/examples/product/index.html +1 -1
- package/examples/product/main.js +2 -2
- package/examples/router/index.html +1 -1
- package/examples/server-call/index.html +1 -1
- package/examples/ssr/index.html +1 -1
- package/examples/streaming/index.html +1 -1
- package/framework.d.ts +572 -0
- package/framework.js +216 -29
- package/framework.min.js +3820 -0
- package/framework.ts +4321 -0
- package/framework.umd.js +4342 -0
- package/framework.umd.min.js +3843 -0
- package/package.json +34 -5
- package/src/app.js +35 -3
- package/src/cache.js +27 -3
- package/src/component.js +1 -1
- package/src/index.js +2 -2
- package/src/loader.js +4 -2
- package/src/router.js +100 -16
- package/src/server.js +44 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0 - 2026-06-17
|
|
4
|
+
|
|
5
|
+
- Added router navigation abort/version guards so stale route partials cannot
|
|
6
|
+
clobber newer navigations, and route partial contexts receive `this.abort`.
|
|
7
|
+
- Added ranked route matching so static and dynamic routes win over wildcard
|
|
8
|
+
fallbacks regardless of registration order.
|
|
9
|
+
- Added `readSnapshot(...)` and automatic browser activation from SSR snapshot
|
|
10
|
+
scripts.
|
|
11
|
+
- Fixed repeated server result application when proxy/server envelopes pass
|
|
12
|
+
through namespace or handler callers.
|
|
13
|
+
- Added in-flight `cache.getOrSet(...)` deduplication and clear proxy errors for
|
|
14
|
+
`File`, `Blob`, and `FormData` values that the JSON transport cannot send.
|
|
15
|
+
- Changed `framework.ts` from a source facade to a bundled TypeScript source
|
|
16
|
+
entrypoint.
|
|
17
|
+
|
|
18
|
+
## 0.6.0 - 2026-06-17
|
|
19
|
+
|
|
20
|
+
- Added `Loader` as the canonical public loader factory, including
|
|
21
|
+
`Async.Loader(...)` for UMD script-tag usage, while keeping `AsyncLoader` as
|
|
22
|
+
a compatibility alias.
|
|
23
|
+
- Added generated root CDN artifacts: `framework.min.js`, `framework.umd.js`,
|
|
24
|
+
`framework.umd.min.js`, `framework.ts`, and `framework.d.ts`.
|
|
25
|
+
- Added package exports and docs for ESM, compact ESM, UMD, compact UMD, and
|
|
26
|
+
TypeScript source/types entrypoints.
|
|
27
|
+
- Added exported helpers to the UMD-only `globalThis.Async` object for
|
|
28
|
+
script-tag CDN usage while keeping ESM `Async` as the app hub export.
|
|
29
|
+
- Added UMD namespace conflict checks so generated helpers cannot silently
|
|
30
|
+
overwrite app-hub fields such as `use`, `start`, or `registry`.
|
|
31
|
+
- Added `registry:lint`, a cached package linter that emits a local registry
|
|
32
|
+
manifest and detects conflicting signal, handler, server, partial, route, or
|
|
33
|
+
component declarations while skipping generated root bundles.
|
|
34
|
+
|
|
3
35
|
## 0.5.0 - 2026-06-17
|
|
4
36
|
|
|
5
37
|
- Added `this.suspense(signalRef, views)` for component-owned async boundary
|
package/README.md
CHANGED
|
@@ -90,9 +90,18 @@ and package lifecycle tooling. Browser consumers import ESM directly.
|
|
|
90
90
|
|
|
91
91
|
## CDN
|
|
92
92
|
|
|
93
|
-
The package ships
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
The package ships root CDN artifacts for UNPKG and can be loaded without a
|
|
94
|
+
build step. Use `@latest` for quick prototypes, and pin an exact version in
|
|
95
|
+
production:
|
|
96
|
+
|
|
97
|
+
| File | Format | Use |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| `framework.js` | ESM | Readable browser module bundle |
|
|
100
|
+
| `framework.min.js` | ESM | Compact browser module bundle |
|
|
101
|
+
| `framework.umd.js` | UMD | Readable script-tag/CommonJS-style bundle |
|
|
102
|
+
| `framework.umd.min.js` | UMD | Compact script-tag/CommonJS-style bundle and default CDN file |
|
|
103
|
+
| `framework.ts` | Bundled TypeScript source | TS-aware runtimes and higher-layer tooling |
|
|
104
|
+
| `framework.d.ts` | Type declarations | TypeScript declarations for the public API |
|
|
96
105
|
|
|
97
106
|
```html
|
|
98
107
|
<main async:container>
|
|
@@ -121,6 +130,29 @@ version in production:
|
|
|
121
130
|
</script>
|
|
122
131
|
```
|
|
123
132
|
|
|
133
|
+
For a plain script tag, use the UMD bundle. In this UMD-only global form,
|
|
134
|
+
`globalThis.Async` is the app hub plus the exported helper functions, with
|
|
135
|
+
`globalThis.AsyncFramework` kept as an alias. Lower-level bootloader code can
|
|
136
|
+
call `Async.Loader(...)` directly.
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<script src="https://unpkg.com/@async/framework@latest/framework.umd.min.js"></script>
|
|
140
|
+
<script>
|
|
141
|
+
Async.use({
|
|
142
|
+
signal: {
|
|
143
|
+
count: Async.createSignal(0)
|
|
144
|
+
},
|
|
145
|
+
handler: {
|
|
146
|
+
increment() {
|
|
147
|
+
this.signals.update("count", (count) => count + 1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
Async.start({ root: document });
|
|
153
|
+
</script>
|
|
154
|
+
```
|
|
155
|
+
|
|
124
156
|
You can also use an import map so app code imports `@async/framework` by name:
|
|
125
157
|
|
|
126
158
|
```html
|
|
@@ -157,8 +189,8 @@ You can also use an import map so app code imports `@async/framework` by name:
|
|
|
157
189
|
|
|
158
190
|
```js
|
|
159
191
|
import {
|
|
160
|
-
AsyncLoader,
|
|
161
192
|
Async,
|
|
193
|
+
Loader,
|
|
162
194
|
attributeName,
|
|
163
195
|
asyncSignal,
|
|
164
196
|
createApp,
|
|
@@ -183,11 +215,15 @@ import {
|
|
|
183
215
|
delay,
|
|
184
216
|
effect,
|
|
185
217
|
html,
|
|
218
|
+
readSnapshot,
|
|
186
219
|
route,
|
|
187
220
|
signal
|
|
188
221
|
} from "@async/framework";
|
|
189
222
|
```
|
|
190
223
|
|
|
224
|
+
`Loader` is the canonical loader factory. `AsyncLoader` remains as a
|
|
225
|
+
compatibility alias for older code.
|
|
226
|
+
|
|
191
227
|
### App Hub
|
|
192
228
|
|
|
193
229
|
`Async` is an exported app hub singleton. It is not installed on `globalThis`
|
|
@@ -376,9 +412,13 @@ await delay(250, this.abort);
|
|
|
376
412
|
If a dependency read through `this.signals.get(...)` changes, the async signal
|
|
377
413
|
reruns and the previous run is aborted.
|
|
378
414
|
|
|
415
|
+
Dependency reads are captured while the async signal function starts running.
|
|
416
|
+
Read signal dependencies before the first `await`; reads that happen later are
|
|
417
|
+
ordinary reads and do not create refresh subscriptions.
|
|
418
|
+
|
|
379
419
|
## HTML Protocol
|
|
380
420
|
|
|
381
|
-
|
|
421
|
+
Loader scans regular HTML attributes:
|
|
382
422
|
|
|
383
423
|
| Attribute | Behavior |
|
|
384
424
|
| --- | --- |
|
|
@@ -784,15 +824,21 @@ hydrate, diff, patch, or rerender:
|
|
|
784
824
|
```js
|
|
785
825
|
createApp(browserApp, {
|
|
786
826
|
root: document,
|
|
787
|
-
snapshot,
|
|
788
827
|
server: createServerProxy({ endpoint: "/__async/server" })
|
|
789
828
|
}).start();
|
|
790
829
|
```
|
|
791
830
|
|
|
831
|
+
If an `async:snapshot` script is present under the root or document,
|
|
832
|
+
`createApp(...)` reads it automatically. You can also inspect it directly:
|
|
833
|
+
|
|
834
|
+
```js
|
|
835
|
+
const snapshot = readSnapshot(document);
|
|
836
|
+
```
|
|
837
|
+
|
|
792
838
|
## Components
|
|
793
839
|
|
|
794
840
|
Components are scoped fragment functions. They return strings or `html`
|
|
795
|
-
templates;
|
|
841
|
+
templates; Loader inserts and scans the result. There is no virtual node
|
|
796
842
|
type and no rerender loop.
|
|
797
843
|
|
|
798
844
|
```js
|
|
@@ -822,7 +868,7 @@ const Toggle = defineComponent(function Toggle() {
|
|
|
822
868
|
`;
|
|
823
869
|
});
|
|
824
870
|
|
|
825
|
-
const loader =
|
|
871
|
+
const loader = Loader({ root: document });
|
|
826
872
|
loader.mount(document.querySelector("#app"), Toggle);
|
|
827
873
|
```
|
|
828
874
|
|
|
@@ -845,7 +891,7 @@ Component helpers:
|
|
|
845
891
|
| `this.onMount(fn)` | Compatibility alias for `this.on("attach", fn)` |
|
|
846
892
|
| `this.onVisible(fn)` | Compatibility alias for `this.on("visible", fn)` |
|
|
847
893
|
|
|
848
|
-
`this.suspense(...)` is sugar for
|
|
894
|
+
`this.suspense(...)` is sugar for Loader boundaries:
|
|
849
895
|
`asyncSignal + async:boundary + async:* templates`. It emits only templates. The
|
|
850
896
|
caller owns the boundary element, and the loader chooses the loading, ready, or
|
|
851
897
|
error template from the async signal status.
|
|
@@ -967,10 +1013,19 @@ Useful commands:
|
|
|
967
1013
|
```bash
|
|
968
1014
|
pnpm run pipeline:verify
|
|
969
1015
|
pnpm run pipeline:pages
|
|
1016
|
+
pnpm run registry:lint
|
|
970
1017
|
pnpm run pipeline:release:doctor
|
|
971
1018
|
pnpm run release:check
|
|
972
1019
|
```
|
|
973
1020
|
|
|
1021
|
+
`registry:lint` scans package source and examples for declared registry ids
|
|
1022
|
+
such as signals, handlers, server functions, partials, routes, and components.
|
|
1023
|
+
It writes `.async/registry-manifest.json` plus a per-file cache at
|
|
1024
|
+
`.async/registry-lint-cache.json`, skips generated root bundles such as
|
|
1025
|
+
`framework.umd.min.js`, and fails only when the same registry type and id are
|
|
1026
|
+
declared with different normalized content. Duplicate declarations with the
|
|
1027
|
+
same content are reported as dedupe candidates, not errors.
|
|
1028
|
+
|
|
974
1029
|
GitHub Pages builds through the generated `pages` job. This private repository
|
|
975
1030
|
needs GitHub Pages support enabled before the generated job can deploy.
|
|
976
1031
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Loader, defineComponent, html } from "../../src/index.js";
|
|
2
2
|
|
|
3
3
|
const Toggle = defineComponent(function Toggle() {
|
|
4
4
|
const selected = this.signal(false);
|
|
@@ -22,5 +22,5 @@ const Toggle = defineComponent(function Toggle() {
|
|
|
22
22
|
`;
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
const loader =
|
|
25
|
+
const loader = Loader({ root: document });
|
|
26
26
|
loader.mount(document.querySelector("#app"), Toggle);
|
package/examples/product/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Loader, createSignal, createSignalRegistry, delay } from "../../src/index.js";
|
|
2
2
|
|
|
3
3
|
const products = {
|
|
4
4
|
"sku-1": {
|
|
@@ -21,4 +21,4 @@ signals.asyncSignal("product", async function () {
|
|
|
21
21
|
return products[id];
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Loader({ root: document.body, signals }).start();
|
package/examples/ssr/index.html
CHANGED