@async/framework 0.5.0 → 0.6.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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 - 2026-06-17
4
+
5
+ - Added `Loader` as the canonical public loader factory, including
6
+ `Async.Loader(...)` for UMD script-tag usage, while keeping `AsyncLoader` as
7
+ a compatibility alias.
8
+ - Added generated root CDN artifacts: `framework.min.js`, `framework.umd.js`,
9
+ `framework.umd.min.js`, `framework.ts`, and `framework.d.ts`.
10
+ - Added package exports and docs for ESM, compact ESM, UMD, compact UMD, and
11
+ TypeScript source/types entrypoints.
12
+ - Added exported helpers to the UMD-only `globalThis.Async` object for
13
+ script-tag CDN usage while keeping ESM `Async` as the app hub export.
14
+ - Added UMD namespace conflict checks so generated helpers cannot silently
15
+ overwrite app-hub fields such as `use`, `start`, or `registry`.
16
+ - Added `registry:lint`, a cached package linter that emits a local registry
17
+ manifest and detects conflicting signal, handler, server, partial, route, or
18
+ component declarations while skipping generated root bundles.
19
+
3
20
  ## 0.5.0 - 2026-06-17
4
21
 
5
22
  - 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 a root `framework.js` ESM bundle for UNPKG and can be loaded
94
- without a build step. Use `@latest` for quick prototypes, and pin an exact
95
- version in production:
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` | TypeScript source facade | 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,
@@ -188,6 +220,9 @@ import {
188
220
  } from "@async/framework";
189
221
  ```
190
222
 
223
+ `Loader` is the canonical loader factory. `AsyncLoader` remains as a
224
+ compatibility alias for older code.
225
+
191
226
  ### App Hub
192
227
 
193
228
  `Async` is an exported app hub singleton. It is not installed on `globalThis`
@@ -378,7 +413,7 @@ reruns and the previous run is aborted.
378
413
 
379
414
  ## HTML Protocol
380
415
 
381
- AsyncLoader scans regular HTML attributes:
416
+ Loader scans regular HTML attributes:
382
417
 
383
418
  | Attribute | Behavior |
384
419
  | --- | --- |
@@ -792,7 +827,7 @@ createApp(browserApp, {
792
827
  ## Components
793
828
 
794
829
  Components are scoped fragment functions. They return strings or `html`
795
- templates; AsyncLoader inserts and scans the result. There is no virtual node
830
+ templates; Loader inserts and scans the result. There is no virtual node
796
831
  type and no rerender loop.
797
832
 
798
833
  ```js
@@ -822,7 +857,7 @@ const Toggle = defineComponent(function Toggle() {
822
857
  `;
823
858
  });
824
859
 
825
- const loader = AsyncLoader({ root: document });
860
+ const loader = Loader({ root: document });
826
861
  loader.mount(document.querySelector("#app"), Toggle);
827
862
  ```
828
863
 
@@ -845,7 +880,7 @@ Component helpers:
845
880
  | `this.onMount(fn)` | Compatibility alias for `this.on("attach", fn)` |
846
881
  | `this.onVisible(fn)` | Compatibility alias for `this.on("visible", fn)` |
847
882
 
848
- `this.suspense(...)` is sugar for AsyncLoader boundaries:
883
+ `this.suspense(...)` is sugar for Loader boundaries:
849
884
  `asyncSignal + async:boundary + async:* templates`. It emits only templates. The
850
885
  caller owns the boundary element, and the loader chooses the loading, ready, or
851
886
  error template from the async signal status.
@@ -967,10 +1002,19 @@ Useful commands:
967
1002
  ```bash
968
1003
  pnpm run pipeline:verify
969
1004
  pnpm run pipeline:pages
1005
+ pnpm run registry:lint
970
1006
  pnpm run pipeline:release:doctor
971
1007
  pnpm run release:check
972
1008
  ```
973
1009
 
1010
+ `registry:lint` scans package source and examples for declared registry ids
1011
+ such as signals, handlers, server functions, partials, routes, and components.
1012
+ It writes `.async/registry-manifest.json` plus a per-file cache at
1013
+ `.async/registry-lint-cache.json`, skips generated root bundles such as
1014
+ `framework.umd.min.js`, and fails only when the same registry type and id are
1015
+ declared with different normalized content. Duplicate declarations with the
1016
+ same content are reported as dedupe candidates, not errors.
1017
+
974
1018
  GitHub Pages builds through the generated `pages` job. This private repository
975
1019
  needs GitHub Pages support enabled before the generated job can deploy.
976
1020
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>AsyncLoader Cache</title>
6
+ <title>Async Loader Cache</title>
7
7
  </head>
8
8
  <body>
9
9
  <main async:container>
@@ -2,7 +2,7 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>AsyncLoader Components</title>
5
+ <title>Async Loader Components</title>
6
6
  </head>
7
7
  <body>
8
8
  <main id="app"></main>
@@ -1,4 +1,4 @@
1
- import { AsyncLoader, defineComponent, html } from "../../src/index.js";
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 = AsyncLoader({ root: document });
25
+ const loader = Loader({ root: document });
26
26
  loader.mount(document.querySelector("#app"), Toggle);
@@ -2,7 +2,7 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>AsyncLoader Counter</title>
5
+ <title>Async Loader Counter</title>
6
6
  </head>
7
7
  <body async:container>
8
8
  <main>
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>AsyncLoader Partials</title>
6
+ <title>Async Loader Partials</title>
7
7
  </head>
8
8
  <body>
9
9
  <main async:container>
@@ -2,7 +2,7 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>AsyncLoader Product</title>
5
+ <title>Async Loader Product</title>
6
6
  </head>
7
7
  <body async:container>
8
8
  <main>
@@ -1,4 +1,4 @@
1
- import { AsyncLoader, createSignal, createSignalRegistry, delay } from "../../src/index.js";
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
- AsyncLoader({ root: document.body, signals }).start();
24
+ Loader({ root: document.body, signals }).start();
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>AsyncLoader CSR Router</title>
6
+ <title>Async Loader CSR Router</title>
7
7
  </head>
8
8
  <body>
9
9
  <main async:container>
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>AsyncLoader Server Call</title>
6
+ <title>Async Loader Server Call</title>
7
7
  </head>
8
8
  <body>
9
9
  <main async:container>
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>AsyncLoader SSR Activation</title>
6
+ <title>Async Loader SSR Activation</title>
7
7
  </head>
8
8
  <body>
9
9
  <main id="app" async:container></main>
@@ -2,7 +2,7 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>AsyncLoader Streaming</title>
5
+ <title>Async Loader Streaming</title>
6
6
  </head>
7
7
  <body async:container>
8
8
  <main>