@absolutejs/absolute 0.20.0-beta.167 → 0.20.0-beta.168

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 (57) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +81 -0
  3. package/changelog.json +24 -0
  4. package/dist/angular/browser.js +3 -3
  5. package/dist/angular/browser.js.map +3 -3
  6. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  7. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  8. package/dist/angular/index.js +211 -197
  9. package/dist/angular/index.js.map +8 -8
  10. package/dist/angular/server.js +211 -197
  11. package/dist/angular/server.js.map +8 -8
  12. package/dist/build.js +1324 -998
  13. package/dist/build.js.map +12 -8
  14. package/dist/cli/{compile-30m09382.js → compile-ckn6epbb.js} +1 -1
  15. package/dist/cli/config/server.js +125 -112
  16. package/dist/cli/{index-vkba3289.js → index-8ez1ccm0.js} +1 -1
  17. package/dist/cli/index.js +6 -6
  18. package/dist/cli/{islands-rq6wx0kh.js → islands-8sgky9gh.js} +1 -1
  19. package/dist/cli/{mobile-41sev6v0.js → mobile-ddggpe53.js} +2 -2
  20. package/dist/cli/{start-0ebxkwga.js → start-qj7664zr.js} +2 -2
  21. package/dist/cli/{typecheck-7yhekrc0.js → typecheck-8sdrcjz8.js} +208 -42
  22. package/dist/client/index.js +8 -3
  23. package/dist/client/index.js.map +4 -4
  24. package/dist/index.js +1402 -1075
  25. package/dist/index.js.map +14 -10
  26. package/dist/islands/browser.js +3 -3
  27. package/dist/islands/browser.js.map +3 -3
  28. package/dist/islands/index.js +3 -3
  29. package/dist/islands/index.js.map +3 -3
  30. package/dist/react/browser.js +3 -3
  31. package/dist/react/browser.js.map +3 -3
  32. package/dist/react/index.js +231 -217
  33. package/dist/react/index.js.map +9 -9
  34. package/dist/react/server.js +231 -191
  35. package/dist/react/server.js.map +9 -8
  36. package/dist/src/build/islandBootstrap.d.ts +22 -0
  37. package/dist/src/build/missingClientFrameworks.d.ts +29 -0
  38. package/dist/src/build/svelteDeclarations.d.ts +27 -0
  39. package/dist/src/client/islandResolver.d.ts +3 -1
  40. package/dist/src/core/build.d.ts +1 -1
  41. package/dist/src/core/islandManifest.d.ts +10 -0
  42. package/dist/src/core/islandPageContext.d.ts +2 -0
  43. package/dist/src/dev/svelteDeclarationRefresher.d.ts +6 -0
  44. package/dist/svelte/browser.js +3 -3
  45. package/dist/svelte/browser.js.map +3 -3
  46. package/dist/svelte/index.js +211 -197
  47. package/dist/svelte/index.js.map +8 -8
  48. package/dist/svelte/server.js +211 -171
  49. package/dist/svelte/server.js.map +8 -7
  50. package/dist/vue/browser.js +3 -3
  51. package/dist/vue/browser.js.map +3 -3
  52. package/dist/vue/index.js +231 -217
  53. package/dist/vue/index.js.map +9 -9
  54. package/dist/vue/server.js +231 -191
  55. package/dist/vue/server.js.map +9 -8
  56. package/package.json +6 -1
  57. /package/dist/cli/{index-e6ysp900.js → index-z794p5qg.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,17 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.20.0-beta.168 — 2026-11-12
10
+
11
+ ### Fixed
12
+
13
+ - **Pages build without the frameworks they don't use installed**
14
+ A project with Svelte pages but no Vue or Angular installed couldn't build any Svelte page, in dev or with `absolute build`: the non-React client pass failed with `Could not resolve: "vue"`, then `@angular/core`, `@angular/platform-browser` and `@angular/compiler`. The Svelte hydration index imports `@absolutejs/absolute/client`, whose island runtime lazily imports a hydrator per framework, and only the React client pass left frameworks the project doesn't have unresolved. The non-React, island and worker client passes, and the dev rebuilds of Svelte and Vue pages, now resolve a framework the project neither configures nor installs to a stub that throws only if that framework's hydrator runs. A bare external wouldn't do: dev island bundles aren't code-split, so Bun hoists the import and the browser can't load the bundle. An installed framework is bundled as before. Verified with a Svelte-only, a Vue-only, and an HTML project with a React island, each in `absolute dev`, `absolute start` and `absolute compile`.
15
+ - **Static-page islands hydrate with only `islands.registry`, or a bootstrap file of any name** (`createIslandManifestResolver`)
16
+ Islands on HTML and HTMX pages server-rendered but never hydrated unless the islands bootstrap file happened to compile to the manifest key `BootstrapClient`, the only key the server looked for. A configured `islands.bootstrap` is now recorded under a reserved manifest key whatever its file name. With only `islands: { registry }` set, the build generates a default bootstrap that loads each island's chunk from the manifest, so no bootstrap file is needed. `createIslandManifestResolver()` defaults to the manifest the server injects. React islands now share one React vendor with the bootstrap even without a `reactDirectory`; before, a separately bundled bootstrap brought a second React and hydration failed on `useState`. A page with islands but no bootstrap now logs a warning outside production. Verified in Chromium: `load`, `idle` and `visible` hydrate, `none` doesn't, and React, Svelte and Vue islands hydrate on HTML and HTMX pages.
17
+ - **Svelte page props are type-checked in server files**
18
+ `handleSveltePageRequest<typeof Page>({ props })` accepted any props in a server file. Svelte's ambient `*.svelte` module types every import as `LegacyComponentType`, whose props are `Record<string, any>`, and svelte-check only covers the Svelte directory. `absolute typecheck` now generates a declaration per component with svelte2tsx, the engine svelte-check uses, under `.absolutejs/types/svelte/`, and resolves server imports to them through `rootDirs`. A missing prop now fails with TS2741, a wrong type with TS2322 and an unknown prop with TS2353, as for React. `absolute dev` keeps the declarations current as components change. For editor squiggles, add `"rootDirs": [".", ".absolutejs/types/svelte"]` to tsconfig.json (typecheck prints this hint when it's missing). The check needs `svelte2tsx` installed (`bun add -d svelte2tsx`), and typecheck says so when it isn't. Unchanged projects reuse the last declarations. Vue pages were already checked by vue-tsc, and Angular's `requestContext` by its `Ctx` generic.
19
+
9
20
  ## 0.20.0-beta.167 — 2026-11-09
10
21
 
11
22
  ### Fixed
package/README.md CHANGED
@@ -105,6 +105,87 @@ export const server = new Elysia()
105
105
  2. Route handlers (`handleReactPageRequest`, `handleSveltePageRequest`, …) stream HTML and inject scripts/assets based on that manifest.
106
106
  3. The static plugin serves all compiled files from `/build`.
107
107
 
108
+ ### Type-checked Svelte page props
109
+
110
+ `handleSveltePageRequest<typeof Page>({ props })` checks `props` against the
111
+ component's `$props()` type, like `handleReactPageRequest`. `absolute typecheck`
112
+ generates a declaration per Svelte component with svelte2tsx
113
+ (`bun add -d svelte2tsx`), and `absolute dev` keeps them current. To see the
114
+ same errors in your editor, add the declarations to `rootDirs`:
115
+
116
+ ```jsonc
117
+ // tsconfig.json
118
+ {
119
+ "compilerOptions": {
120
+ "rootDirs": [".", ".absolutejs/types/svelte"]
121
+ }
122
+ }
123
+ ```
124
+
125
+ ### Islands on HTML and HTMX pages
126
+
127
+ Static HTML and HTMX pages can embed components of any framework as islands.
128
+ Register the components once:
129
+
130
+ ```ts
131
+ // src/islands/registry.ts
132
+ import { defineIslandRegistry } from '@absolutejs/absolute/islands';
133
+ import { PriceChart } from './PriceChart'; // React
134
+ import Ticker from './Ticker.svelte';
135
+
136
+ export const islandRegistry = defineIslandRegistry({
137
+ react: { PriceChart },
138
+ svelte: { Ticker }
139
+ });
140
+ ```
141
+
142
+ ```ts
143
+ // absolute.config.ts
144
+ export default defineConfig({
145
+ htmlDirectory: 'src/html',
146
+ islands: { registry: 'src/islands/registry.ts' },
147
+ svelteDirectory: 'src/svelte' // needed to compile Svelte islands; same for Vue
148
+ });
149
+ ```
150
+
151
+ Then place islands in a page with `<absolute-island>` (or the `<island>` alias):
152
+
153
+ ```html
154
+ <absolute-island
155
+ framework="react"
156
+ component="PriceChart"
157
+ hydrate="idle"
158
+ props='{"symbol":"BTC"}'
159
+ ></absolute-island>
160
+ ```
161
+
162
+ Islands are server-rendered at build time. With `islands.registry` set, the
163
+ build also generates an islands bootstrap, and `handleHTMLPageRequest` /
164
+ `handleHTMXPageRequest` inject it into any page that contains islands. Each
165
+ island's code loads only when that island hydrates. `hydrate` is `load` (the
166
+ default), `idle`, `visible` (when scrolled into view) or `none` (server HTML
167
+ only, never hydrated).
168
+
169
+ To run your own client code, point `islands.bootstrap` at a file that calls
170
+ `startIslands`. The file can have any name, and it replaces the generated one:
171
+
172
+ ```ts
173
+ // src/islands/main.ts → islands: { registry: '…', bootstrap: 'src/islands/main.ts' }
174
+ import {
175
+ createIslandManifestResolver,
176
+ startIslands
177
+ } from '@absolutejs/absolute/client';
178
+
179
+ startIslands({
180
+ registry: {},
181
+ // Loads each island's chunk from the manifest the server injects.
182
+ resolveComponent: createIslandManifestResolver()
183
+ });
184
+ ```
185
+
186
+ If a page has islands but the build produced no bootstrap, the dev server logs
187
+ a warning instead of serving islands that never hydrate.
188
+
108
189
  ### Installable PWA and offline Sync
109
190
 
110
191
  Enable the web-app shell once in `absolutejs.config.ts`. AbsoluteJS generates a
package/changelog.json CHANGED
@@ -2,6 +2,30 @@
2
2
  "contract": 1,
3
3
  "name": "@absolutejs/absolute",
4
4
  "releases": [
5
+ {
6
+ "changes": [
7
+ {
8
+ "detail": "A project with Svelte pages but no Vue or Angular installed couldn't build any Svelte page, in dev or with `absolute build`: the non-React client pass failed with `Could not resolve: \"vue\"`, then `@angular/core`, `@angular/platform-browser` and `@angular/compiler`. The Svelte hydration index imports `@absolutejs/absolute/client`, whose island runtime lazily imports a hydrator per framework, and only the React client pass left frameworks the project doesn't have unresolved. The non-React, island and worker client passes, and the dev rebuilds of Svelte and Vue pages, now resolve a framework the project neither configures nor installs to a stub that throws only if that framework's hydrator runs. A bare external wouldn't do: dev island bundles aren't code-split, so Bun hoists the import and the browser can't load the bundle. An installed framework is bundled as before. Verified with a Svelte-only, a Vue-only, and an HTML project with a React island, each in `absolute dev`, `absolute start` and `absolute compile`.",
9
+ "kind": "fixed",
10
+ "summary": "Pages build without the frameworks they don't use installed"
11
+ },
12
+ {
13
+ "detail": "Islands on HTML and HTMX pages server-rendered but never hydrated unless the islands bootstrap file happened to compile to the manifest key `BootstrapClient`, the only key the server looked for. A configured `islands.bootstrap` is now recorded under a reserved manifest key whatever its file name. With only `islands: { registry }` set, the build generates a default bootstrap that loads each island's chunk from the manifest, so no bootstrap file is needed. `createIslandManifestResolver()` defaults to the manifest the server injects. React islands now share one React vendor with the bootstrap even without a `reactDirectory`; before, a separately bundled bootstrap brought a second React and hydration failed on `useState`. A page with islands but no bootstrap now logs a warning outside production. Verified in Chromium: `load`, `idle` and `visible` hydrate, `none` doesn't, and React, Svelte and Vue islands hydrate on HTML and HTMX pages.",
14
+ "kind": "fixed",
15
+ "summary": "Static-page islands hydrate with only `islands.registry`, or a bootstrap file of any name",
16
+ "symbols": [
17
+ "createIslandManifestResolver"
18
+ ]
19
+ },
20
+ {
21
+ "detail": "`handleSveltePageRequest<typeof Page>({ props })` accepted any props in a server file. Svelte's ambient `*.svelte` module types every import as `LegacyComponentType`, whose props are `Record<string, any>`, and svelte-check only covers the Svelte directory. `absolute typecheck` now generates a declaration per component with svelte2tsx, the engine svelte-check uses, under `.absolutejs/types/svelte/`, and resolves server imports to them through `rootDirs`. A missing prop now fails with TS2741, a wrong type with TS2322 and an unknown prop with TS2353, as for React. `absolute dev` keeps the declarations current as components change. For editor squiggles, add `\"rootDirs\": [\".\", \".absolutejs/types/svelte\"]` to tsconfig.json (typecheck prints this hint when it's missing). The check needs `svelte2tsx` installed (`bun add -d svelte2tsx`), and typecheck says so when it isn't. Unchanged projects reuse the last declarations. Vue pages were already checked by vue-tsc, and Angular's `requestContext` by its `Ctx` generic.",
22
+ "kind": "fixed",
23
+ "summary": "Svelte page props are type-checked in server files"
24
+ }
25
+ ],
26
+ "date": "2026-11-12",
27
+ "version": "0.20.0-beta.168"
28
+ },
5
29
  {
6
30
  "changes": [
7
31
  {
@@ -88,7 +88,7 @@ var ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER = "x-skip-transfer-cache", buildAbs
88
88
  };
89
89
 
90
90
  // src/core/islandManifest.ts
91
- var toIslandFrameworkSegment = (framework) => framework[0]?.toUpperCase() + framework.slice(1), collectFrameworkIslands = (manifest, prefix) => {
91
+ var ISLAND_BOOTSTRAP_MANIFEST_KEY = "AbsoluteIslandBootstrap", LEGACY_ISLAND_BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", toIslandFrameworkSegment = (framework) => framework[0]?.toUpperCase() + framework.slice(1), collectFrameworkIslands = (manifest, prefix) => {
92
92
  const entries = {};
93
93
  let found = false;
94
94
  for (const [key, value] of Object.entries(manifest)) {
@@ -101,7 +101,7 @@ var toIslandFrameworkSegment = (framework) => framework[0]?.toUpperCase() + fram
101
101
  found = true;
102
102
  }
103
103
  return found ? entries : undefined;
104
- }, getIslandManifestEntries = (manifest) => {
104
+ }, getIslandBootstrapPath = (manifest) => manifest[ISLAND_BOOTSTRAP_MANIFEST_KEY] ?? manifest[LEGACY_ISLAND_BOOTSTRAP_MANIFEST_KEY], getIslandManifestEntries = (manifest) => {
105
105
  const islands = {};
106
106
  const frameworks = ["react", "svelte", "vue", "angular"];
107
107
  for (const framework of frameworks) {
@@ -10358,5 +10358,5 @@ export {
10358
10358
  withPendingTask
10359
10359
  };
10360
10360
 
10361
- //# debugId=BEDC2BC3159D507E64756E2164756E21
10361
+ //# debugId=43DEF2DFD2D62F7064756E2164756E21
10362
10362
  //# sourceMappingURL=browser.js.map