@absolutejs/absolute 0.19.0-beta.231 → 0.19.0-beta.232

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 (42) hide show
  1. package/.absolutejs/vue-tsc.tsbuildinfo +1 -1
  2. package/dist/ai-client/angular/ai/index.js +5 -9
  3. package/dist/ai-client/react/ai/index.js +5 -9
  4. package/dist/ai-client/vue/ai/index.js +5 -9
  5. package/dist/angular/ai/index.js +6 -10
  6. package/dist/angular/ai/index.js.map +3 -3
  7. package/dist/react/ai/index.js +6 -10
  8. package/dist/react/ai/index.js.map +3 -3
  9. package/dist/svelte/ai/index.js +6 -10
  10. package/dist/svelte/ai/index.js.map +3 -3
  11. package/dist/vue/ai/index.js +6 -10
  12. package/dist/vue/ai/index.js.map +3 -3
  13. package/package.json +1 -1
  14. package/dist/angular/components/image.component.js +0 -202
  15. package/dist/angular/components/index.js +0 -1
  16. package/dist/dev/client/constants.ts +0 -25
  17. package/dist/dev/client/cssUtils.ts +0 -305
  18. package/dist/dev/client/domDiff.ts +0 -225
  19. package/dist/dev/client/domState.ts +0 -420
  20. package/dist/dev/client/domTracker.ts +0 -60
  21. package/dist/dev/client/errorOverlay.ts +0 -183
  22. package/dist/dev/client/frameworkDetect.ts +0 -62
  23. package/dist/dev/client/handlers/angular.ts +0 -551
  24. package/dist/dev/client/handlers/angularRuntime.ts +0 -205
  25. package/dist/dev/client/handlers/html.ts +0 -361
  26. package/dist/dev/client/handlers/htmx.ts +0 -274
  27. package/dist/dev/client/handlers/react.ts +0 -107
  28. package/dist/dev/client/handlers/rebuild.ts +0 -152
  29. package/dist/dev/client/handlers/svelte.ts +0 -331
  30. package/dist/dev/client/handlers/vue.ts +0 -291
  31. package/dist/dev/client/headPatch.ts +0 -232
  32. package/dist/dev/client/hmrClient.ts +0 -250
  33. package/dist/dev/client/moduleVersions.ts +0 -61
  34. package/dist/dev/client/reactRefreshSetup.ts +0 -32
  35. package/dist/svelte/components/Head.svelte +0 -147
  36. package/dist/svelte/components/Head.svelte.d.ts +0 -5
  37. package/dist/svelte/components/Image.svelte +0 -161
  38. package/dist/svelte/components/Image.svelte.d.ts +0 -5
  39. package/dist/svelte/components/JsonLd.svelte +0 -20
  40. package/dist/svelte/components/JsonLd.svelte.d.ts +0 -2
  41. package/dist/vue/components/Image.vue +0 -186
  42. package/dist/vue/components/Image.vue.d.ts +0 -4
@@ -1,331 +0,0 @@
1
- /* Svelte HMR update handler */
2
-
3
- import { SVELTE_CSS_LOAD_TIMEOUT_MS } from '../constants';
4
- import {
5
- saveDOMState,
6
- restoreDOMState,
7
- saveScrollState,
8
- restoreScrollState
9
- } from '../domState';
10
- import { detectCurrentFramework, findIndexPath } from '../frameworkDetect';
11
-
12
- /* Swap a stylesheet link by matching cssBaseName or framework name */
13
- const swapStylesheet = (
14
- cssUrl: string,
15
- cssBaseName: string,
16
- framework: string
17
- ) => {
18
- let existingLink: HTMLLinkElement | null = null;
19
- document
20
- .querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]')
21
- .forEach((link) => {
22
- const href = link.getAttribute('href') ?? '';
23
- if (href.includes(cssBaseName) || href.includes(framework)) {
24
- existingLink = link;
25
- }
26
- });
27
-
28
- if (!existingLink) {
29
- return;
30
- }
31
-
32
- const capturedExisting: HTMLLinkElement = existingLink;
33
- const newLink = document.createElement('link');
34
- newLink.rel = 'stylesheet';
35
- newLink.href = `${cssUrl}?t=${Date.now()}`;
36
- newLink.onload = () => {
37
- if (capturedExisting && capturedExisting.parentNode) {
38
- capturedExisting.remove();
39
- }
40
- };
41
- document.head.appendChild(newLink);
42
- };
43
-
44
- const extractCountFromDOM = () => {
45
- const countButton = document.querySelector('button');
46
- if (!countButton || !countButton.textContent) {
47
- return {};
48
- }
49
-
50
- const countMatch = countButton.textContent.match(/(\d+)/);
51
- if (!countMatch) {
52
- return {};
53
- }
54
-
55
- return { initialCount: parseInt(countMatch[1] ?? '0', 10) };
56
- };
57
-
58
- const loadStateFromSession = () => {
59
- try {
60
- const stored = sessionStorage.getItem('__SVELTE_HMR_STATE__');
61
- if (!stored) {
62
- return {};
63
- }
64
-
65
- const parsed: Record<string, unknown> = JSON.parse(stored);
66
- if (parsed && Object.keys(parsed).length > 0) {
67
- return parsed;
68
- }
69
-
70
- return {};
71
- } catch {
72
- return {};
73
- }
74
- };
75
-
76
- const saveStateToSession = (preservedState: Record<string, unknown>) => {
77
- if (Object.keys(preservedState).length === 0) {
78
- return;
79
- }
80
-
81
- try {
82
- sessionStorage.setItem(
83
- '__SVELTE_HMR_STATE__',
84
- JSON.stringify(preservedState)
85
- );
86
- } catch {
87
- /* ignore */
88
- }
89
- };
90
-
91
- const collectCssRules = (sheet: CSSStyleSheet) => {
92
- let rules = '';
93
- for (let idx = 0; idx < sheet.cssRules.length; idx++) {
94
- const rule = sheet.cssRules[idx];
95
- if (!rule) continue;
96
- rules += `${rule.cssText}\n`;
97
- }
98
-
99
- return rules;
100
- };
101
-
102
- const preserveLinkAsInlineStyle = (link: HTMLLinkElement) => {
103
- try {
104
- const { sheet } = link;
105
- if (!sheet || sheet.cssRules.length === 0) {
106
- return null;
107
- }
108
-
109
- const style = document.createElement('style');
110
- style.dataset.hmrPreserved = 'true';
111
- style.textContent = collectCssRules(sheet);
112
- document.head.appendChild(style);
113
-
114
- return style;
115
- } catch {
116
- /* Cross-origin sheets (e.g. Google Fonts) — clone as fallback */
117
- const clone = document.createElement('link');
118
- clone.rel = link.rel;
119
- clone.href = link.href;
120
- clone.dataset.hmrPreserved = 'true';
121
- document.head.appendChild(clone);
122
-
123
- return null;
124
- }
125
- };
126
-
127
- const preserveAllStylesheets = () => {
128
- const preservedStyles: HTMLStyleElement[] = [];
129
- document
130
- .querySelectorAll<HTMLLinkElement>('head link[rel="stylesheet"]')
131
- .forEach((link) => {
132
- const style = preserveLinkAsInlineStyle(link);
133
- if (style) {
134
- preservedStyles.push(style);
135
- }
136
- });
137
-
138
- /* Also preserve Svelte injected <style> tags (css: 'injected' mode) */
139
- document
140
- .querySelectorAll<HTMLStyleElement>(
141
- 'head style:not([data-hmr-preserved])'
142
- )
143
- .forEach((style) => {
144
- const clone = document.createElement('style');
145
- clone.dataset.hmrPreserved = 'true';
146
- clone.textContent = style.textContent;
147
- document.head.appendChild(clone);
148
- });
149
-
150
- return preservedStyles;
151
- };
152
-
153
- const buildLinkLoadPromise = (link: HTMLLinkElement) => {
154
- if (link.sheet && link.sheet.cssRules.length > 0) {
155
- return null;
156
- }
157
-
158
- // eslint-disable-next-line promise/avoid-new -- wrapping DOM event callbacks requires a new Promise
159
- return new Promise<void>((resolve) => {
160
- link.onload = () => {
161
- resolve();
162
- };
163
- link.onerror = () => {
164
- resolve();
165
- };
166
- setTimeout(resolve, SVELTE_CSS_LOAD_TIMEOUT_MS);
167
- });
168
- };
169
-
170
- const cleanupAfterImport = (
171
- domState: ReturnType<typeof saveDOMState>,
172
- scrollState: ReturnType<typeof saveScrollState>
173
- ) => {
174
- document
175
- .querySelectorAll('[data-hmr-preserved="true"]')
176
- .forEach((element) => {
177
- element.remove();
178
- });
179
- restoreDOMState(document.body, domState);
180
- restoreScrollState(scrollState);
181
- };
182
-
183
- const waitForStylesAndCleanup = (
184
- domState: ReturnType<typeof saveDOMState>,
185
- scrollState: ReturnType<typeof saveScrollState>
186
- ) => {
187
- const newLinks = document.querySelectorAll<HTMLLinkElement>(
188
- 'head link[rel="stylesheet"]:not([data-hmr-preserved])'
189
- );
190
- const loadPromises: Promise<void>[] = [];
191
- newLinks.forEach((link) => {
192
- const promise = buildLinkLoadPromise(link);
193
- if (promise) {
194
- loadPromises.push(promise);
195
- }
196
- });
197
-
198
- const cleanup = () => {
199
- cleanupAfterImport(domState, scrollState);
200
- };
201
-
202
- if (loadPromises.length > 0) {
203
- void Promise.all(loadPromises).then(cleanup);
204
- } else {
205
- cleanup();
206
- }
207
- };
208
-
209
- export const handleSvelteUpdate = (message: {
210
- data: {
211
- cssBaseName?: string;
212
- cssUrl?: string;
213
- html?: string;
214
- manifest?: Record<string, string>;
215
- pageModuleUrl?: string;
216
- serverDuration?: number;
217
- sourceFile?: string;
218
- updateType?: string;
219
- };
220
- }) => {
221
- const svelteFrameworkCheck = detectCurrentFramework();
222
- if (svelteFrameworkCheck !== 'svelte') return;
223
-
224
- /* CSS-only update: hot-swap stylesheet, no remount needed */
225
- if (message.data.updateType === 'css-only' && message.data.cssUrl) {
226
- swapStylesheet(
227
- message.data.cssUrl,
228
- message.data.cssBaseName || '',
229
- 'svelte'
230
- );
231
-
232
- return;
233
- }
234
-
235
- /* Component update: preserve state, re-import (bootstrap handles unmount + mount) */
236
-
237
- /* Save DOM state and scroll position */
238
- const domState = saveDOMState(document.body);
239
- const scrollState = saveScrollState();
240
-
241
- let preservedState: Record<string, unknown> = extractCountFromDOM();
242
-
243
- if (Object.keys(preservedState).length === 0) {
244
- preservedState = loadStateFromSession();
245
- }
246
-
247
- /* Set preserved state on window + backup to sessionStorage */
248
- window.__HMR_PRESERVED_STATE__ = preservedState;
249
- saveStateToSession(preservedState);
250
-
251
- /* CSS pre-update: swap stylesheet BEFORE importing to prevent FOUC */
252
- if (message.data.cssUrl) {
253
- swapStylesheet(
254
- message.data.cssUrl,
255
- message.data.cssBaseName || '',
256
- 'svelte'
257
- );
258
- }
259
-
260
- // O(1) Svelte 5 HMR: import the changed module, then call its
261
- // accept callback. Svelte's $.hmr() reactive wrapper swaps the
262
- // component in place — parent state and DOM survive untouched.
263
- const { pageModuleUrl } = message.data;
264
- if (pageModuleUrl) {
265
- const clientStart = performance.now();
266
- const modulePath = `${pageModuleUrl}?t=${Date.now()}`;
267
-
268
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
269
- const acceptRegistry = (window as any).__SVELTE_HMR_ACCEPT__ as
270
- | Record<string, (mod: unknown) => void>
271
- | undefined;
272
-
273
- // Save the OLD module's accept callback BEFORE importing.
274
- const acceptFn = acceptRegistry?.[pageModuleUrl];
275
-
276
- import(modulePath)
277
- .then((newModule) => {
278
- if (acceptFn) {
279
- acceptFn(newModule);
280
- }
281
-
282
- if (
283
- window.__HMR_WS__ &&
284
- message.data.serverDuration !== undefined
285
- ) {
286
- const clientMs = Math.round(
287
- performance.now() - clientStart
288
- );
289
- const total = (message.data.serverDuration ?? 0) + clientMs;
290
- window.__HMR_WS__.send(
291
- JSON.stringify({ duration: total, type: 'hmr-timing' })
292
- );
293
- }
294
-
295
- return undefined;
296
- })
297
- .catch((err: unknown) => {
298
- console.warn('[HMR] Svelte HMR failed, reloading:', err);
299
- window.location.reload();
300
- });
301
-
302
- return;
303
- }
304
-
305
- // Bundled fallback: re-import the index file
306
- const indexPath = findIndexPath(
307
- message.data.manifest,
308
- message.data.sourceFile,
309
- 'svelte'
310
- );
311
- if (!indexPath) {
312
- console.warn('[HMR] Svelte index path not found, reloading');
313
- window.location.reload();
314
-
315
- return;
316
- }
317
-
318
- preserveAllStylesheets();
319
-
320
- const modulePath = `${indexPath}?t=${Date.now()}`;
321
- import(modulePath)
322
- .then(() => {
323
- waitForStylesAndCleanup(domState, scrollState);
324
-
325
- return undefined;
326
- })
327
- .catch((err: unknown) => {
328
- console.warn('[HMR] Svelte import failed, reloading:', err);
329
- window.location.reload();
330
- });
331
- };
@@ -1,291 +0,0 @@
1
- /* Vue HMR update handler */
2
-
3
- import type { VueComponentInstance, VueVNode } from '../../../../types/vue';
4
- import { saveDOMState, restoreDOMState } from '../domState';
5
- import { detectCurrentFramework, findIndexPath } from '../frameworkDetect';
6
-
7
- /* Collect reactive value from a setup state entry into the target record */
8
- const collectSetupValue = (
9
- target: Record<string, unknown>,
10
- key: string,
11
- value: unknown
12
- ) => {
13
- if (value && typeof value === 'object' && 'value' in value) {
14
- target[key] = value.value;
15
-
16
- return;
17
- }
18
-
19
- if (typeof value !== 'function') {
20
- target[key] = value;
21
- }
22
- };
23
-
24
- /* Copy all setup state entries from a record into the target */
25
- const collectSetupState = (
26
- target: Record<string, unknown>,
27
- setupState: Record<string, unknown>
28
- ) => {
29
- const keys = Object.keys(setupState);
30
- for (let idx = 0; idx < keys.length; idx++) {
31
- const key = keys[idx];
32
- if (key === undefined) continue;
33
- collectSetupValue(target, key, setupState[key]);
34
- }
35
- };
36
-
37
- /* Walk a VNode tree and collect setup state from all child components */
38
- const walkVNode = (
39
- vnode: VueVNode | undefined,
40
- state: Record<string, unknown>
41
- ) => {
42
- if (!vnode) return;
43
-
44
- if (vnode.component && vnode.component.setupState) {
45
- collectSetupState(state, vnode.component.setupState);
46
- }
47
-
48
- if (vnode.children && Array.isArray(vnode.children)) {
49
- vnode.children.forEach((child) => {
50
- walkVNode(child, state);
51
- });
52
- }
53
-
54
- if (vnode.component && vnode.component.subTree) {
55
- walkVNode(vnode.component.subTree, state);
56
- }
57
- };
58
-
59
- /* Extract state from child Vue component instances recursively */
60
- const extractChildComponentState = (
61
- instance: VueComponentInstance,
62
- state: Record<string, unknown>
63
- ) => {
64
- if (!instance || !instance.subTree) return;
65
-
66
- walkVNode(instance.subTree, state);
67
- };
68
-
69
- /* Find an existing stylesheet link matching the given base name */
70
- const findMatchingStylesheetLink = (cssBaseName: string) => {
71
- let found: HTMLLinkElement | null = null;
72
- document
73
- .querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]')
74
- .forEach((link) => {
75
- const href = link.getAttribute('href') ?? '';
76
- if (cssBaseName && href.includes(cssBaseName)) {
77
- found = link;
78
- }
79
- });
80
-
81
- return found;
82
- };
83
-
84
- /* Swap a stylesheet link with a new one, removing the old on load */
85
- const swapStylesheet = (cssUrl: string, cssBaseName: string) => {
86
- const existingLink = findMatchingStylesheetLink(cssBaseName);
87
- if (!existingLink) return;
88
-
89
- const capturedExisting: HTMLLinkElement = existingLink;
90
- const newLink = document.createElement('link');
91
- newLink.rel = 'stylesheet';
92
- newLink.href = `${cssUrl}?t=${Date.now()}`;
93
- newLink.onload = function () {
94
- if (capturedExisting && capturedExisting.parentNode) {
95
- capturedExisting.remove();
96
- }
97
- };
98
- document.head.appendChild(newLink);
99
- };
100
-
101
- /* Extract Vue reactive state from app instance */
102
- const extractVueAppState = (vuePreservedState: Record<string, unknown>) => {
103
- if (!window.__VUE_APP__ || !window.__VUE_APP__._instance) return;
104
-
105
- const instance = window.__VUE_APP__._instance;
106
-
107
- if (instance.setupState) {
108
- collectSetupState(vuePreservedState, instance.setupState);
109
- }
110
-
111
- extractChildComponentState(instance, vuePreservedState);
112
- };
113
-
114
- /* DOM fallback: extract count from button text when app instance is unavailable */
115
- const extractCountFromDOM = (vuePreservedState: Record<string, unknown>) => {
116
- if (Object.keys(vuePreservedState).length > 0) return;
117
-
118
- const countButton = document.querySelector('button');
119
- if (!countButton || !countButton.textContent) return;
120
-
121
- const countMatch = countButton.textContent.match(/count is (\d+)/i);
122
- if (!countMatch) return;
123
-
124
- vuePreservedState.initialCount = parseInt(countMatch[1] ?? '0', 10);
125
- };
126
-
127
- /* Handle completion of Vue module reimport */
128
- const handleVueImportSuccess = (
129
- vueRoot: HTMLElement | null,
130
- vueDomState: ReturnType<typeof saveDOMState> | null
131
- ) => {
132
- if (vueRoot && vueDomState) {
133
- restoreDOMState(vueRoot, vueDomState);
134
- }
135
- sessionStorage.removeItem('__HMR_ACTIVE__');
136
- };
137
-
138
- /* Force-reload a Vue component via HMR runtime when setup() must re-run */
139
- const forceReloadVueComponent = (mod: Record<string, unknown>) => {
140
- const hmrRuntime = window.__VUE_HMR_RUNTIME__;
141
- if (!hmrRuntime) return;
142
-
143
- const component = mod?.default ?? Object.values(mod ?? {})[0];
144
- if (!component || typeof component !== 'object') return;
145
- if (!('__hmrId' in component)) return;
146
-
147
- const { __hmrId: hmrId } = component;
148
- if (typeof hmrId === 'string') {
149
- hmrRuntime.reload(hmrId, component);
150
- }
151
- };
152
-
153
- export const handleVueUpdate = (message: {
154
- data: {
155
- cssBaseName?: string;
156
- cssUrl?: string;
157
- forceReload?: boolean;
158
- html?: string;
159
- manifest?: Record<string, string>;
160
- pageModuleUrl?: string;
161
- serverDuration?: number;
162
- sourceFile?: string;
163
- updateType?: string;
164
- };
165
- }) => {
166
- const vueFrameworkCheck = detectCurrentFramework();
167
- if (vueFrameworkCheck !== 'vue') return;
168
-
169
- if (message.data.updateType === 'css-only' && message.data.cssUrl) {
170
- swapStylesheet(message.data.cssUrl, message.data.cssBaseName || '');
171
-
172
- return;
173
- }
174
-
175
- sessionStorage.setItem('__HMR_ACTIVE__', 'true');
176
-
177
- const vueRoot = document.getElementById('root');
178
- const vueDomState = vueRoot ? saveDOMState(vueRoot) : null;
179
-
180
- /* Extract Vue reactive state from app instance (not DOM) */
181
- const vuePreservedState: Record<string, unknown> = {};
182
-
183
- extractVueAppState(vuePreservedState);
184
-
185
- /* DOM fallback if app instance not available */
186
- extractCountFromDOM(vuePreservedState);
187
-
188
- /* Map count -> initialCount for prop-based state (used by CountButton) */
189
- if (
190
- vuePreservedState.count !== undefined &&
191
- vuePreservedState.initialCount === undefined
192
- ) {
193
- vuePreservedState.initialCount = vuePreservedState.count;
194
- }
195
-
196
- /* Backup to sessionStorage for resilience */
197
- try {
198
- sessionStorage.setItem(
199
- '__VUE_HMR_STATE__',
200
- JSON.stringify(vuePreservedState)
201
- );
202
- } catch {
203
- /* ignore */
204
- }
205
-
206
- window.__HMR_PRESERVED_STATE__ = vuePreservedState;
207
-
208
- // O(1) Vue HMR: import the changed module directly.
209
- // __VUE_HMR_RUNTIME__.reload() inside the module hot-swaps the
210
- // component in place — same pattern as React Fast Refresh.
211
- const { pageModuleUrl } = message.data;
212
- if (pageModuleUrl) {
213
- const clientStart = performance.now();
214
- const modulePath = `${pageModuleUrl}?t=${Date.now()}`;
215
-
216
- import(modulePath)
217
- .then((mod) => {
218
- // When a composable/utility file changed (not the .vue file itself),
219
- // force reload via __VUE_HMR_RUNTIME__ so setup() re-runs.
220
- // Vue's rerender only swaps the template, not the setup closure.
221
- if (message.data.forceReload) {
222
- forceReloadVueComponent(mod);
223
- }
224
- sessionStorage.removeItem('__HMR_ACTIVE__');
225
-
226
- if (
227
- window.__HMR_WS__ &&
228
- message.data.serverDuration !== undefined
229
- ) {
230
- const clientMs = Math.round(
231
- performance.now() - clientStart
232
- );
233
- const total = (message.data.serverDuration ?? 0) + clientMs;
234
- window.__HMR_WS__.send(
235
- JSON.stringify({ duration: total, type: 'hmr-timing' })
236
- );
237
- }
238
-
239
- return undefined;
240
- })
241
- .catch((err: unknown) => {
242
- console.warn('[HMR] Vue HMR failed, reloading:', err);
243
- sessionStorage.removeItem('__HMR_ACTIVE__');
244
- window.location.reload();
245
- });
246
-
247
- return;
248
- }
249
-
250
- /* CSS pre-update: swap stylesheet BEFORE unmounting to prevent FOUC */
251
- if (message.data.cssUrl) {
252
- swapStylesheet(message.data.cssUrl, message.data.cssBaseName || '');
253
- }
254
-
255
- /* Unmount old Vue app but keep DOM visually intact during async import.
256
- unmount() clears the container — snapshot and restore synchronously. */
257
- const savedHTML = vueRoot ? vueRoot.innerHTML : '';
258
- if (window.__VUE_APP__) {
259
- window.__VUE_APP__.unmount();
260
- window.__VUE_APP__ = null;
261
- }
262
- if (vueRoot) {
263
- vueRoot.innerHTML = savedHTML;
264
- }
265
-
266
- // Bundled fallback: re-import the index file
267
- const indexPath = findIndexPath(
268
- message.data.manifest,
269
- message.data.sourceFile,
270
- 'vue'
271
- );
272
- if (!indexPath) {
273
- console.warn('[HMR] Vue index path not found, reloading');
274
- window.location.reload();
275
-
276
- return;
277
- }
278
-
279
- const modulePath = `${indexPath}?t=${Date.now()}`;
280
- import(modulePath)
281
- .then(() => {
282
- handleVueImportSuccess(vueRoot, vueDomState);
283
-
284
- return undefined;
285
- })
286
- .catch((err: unknown) => {
287
- console.warn('[HMR] Vue import failed:', err);
288
- sessionStorage.removeItem('__HMR_ACTIVE__');
289
- window.location.reload();
290
- });
291
- };