@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,205 +0,0 @@
1
- /* Angular HMR — Zoneless Runtime Preservation
2
- DEV MODE ONLY — never included in production builds.
3
-
4
- Runtime component patching via prototype swap and ɵcmp metadata swap.
5
- State persists naturally via instance continuity — NO serialization.
6
-
7
- Why state serialization was removed:
8
- Angular component + service state lives on JS object instances.
9
- Prototype swapping replaces method implementations without destroying
10
- instances, so all state (properties, injected services, etc.) survives.
11
- Serializing and reassigning state is fragile, lossy, and unnecessary.
12
-
13
- Why zoneless requires manual tick():
14
- With provideZonelessChangeDetection(), there is no Zone.js to
15
- auto-trigger change detection. After swapping prototypes or templates,
16
- we must explicitly call ApplicationRef.tick() to re-render.
17
-
18
- Why this is safe in a multi-framework environment:
19
- This module only touches Angular-specific globals (__ANGULAR_APP__,
20
- __ANGULAR_HMR__). It never modifies document.body, React roots,
21
- Vue instances, or Svelte components. The registry is keyed by
22
- source file path, so name collisions across frameworks are impossible. */
23
-
24
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- type ComponentCtor = any;
26
-
27
- type RegistryEntry = {
28
- liveCtor: ComponentCtor;
29
- id: string;
30
- registeredAt: number;
31
- updateCount: number;
32
- };
33
-
34
- const componentRegistry = new Map<string, RegistryEntry>();
35
- let globalUpdateCount = 0;
36
-
37
- const hasInjectorProviderChanges = (
38
- oldCtor: ComponentCtor,
39
- newCtor: ComponentCtor
40
- ) => {
41
- if (oldCtor.ɵinj === undefined || newCtor.ɵinj === undefined) return false;
42
- const oldP = oldCtor.ɵinj?.providers;
43
- const newP = newCtor.ɵinj?.providers;
44
- if (!Array.isArray(oldP) || !Array.isArray(newP)) return false;
45
-
46
- return oldP.length !== newP.length;
47
- };
48
-
49
- const hasComponentProviderChanges = (
50
- oldCtor: ComponentCtor,
51
- newCtor: ComponentCtor
52
- ) => {
53
- if (!oldCtor.ɵcmp || !newCtor.ɵcmp) return false;
54
- const oldResolver = oldCtor.ɵcmp.providersResolver;
55
- const newResolver = newCtor.ɵcmp.providersResolver;
56
-
57
- return (oldResolver === undefined) !== (newResolver === undefined);
58
- };
59
-
60
- const hasProviderChanges = (oldCtor: ComponentCtor, newCtor: ComponentCtor) => {
61
- if (hasInjectorProviderChanges(oldCtor, newCtor)) return true;
62
- if (hasComponentProviderChanges(oldCtor, newCtor)) return true;
63
-
64
- return false;
65
- };
66
-
67
- const register = (id: string, ctor: ComponentCtor) => {
68
- if (!id || typeof ctor !== 'function') return;
69
- if (!componentRegistry.has(id)) {
70
- componentRegistry.set(id, {
71
- id,
72
- liveCtor: ctor,
73
- registeredAt: Date.now(),
74
- updateCount: 0
75
- });
76
- }
77
- };
78
-
79
- const SKIP_STATIC_PROPS = [
80
- 'prototype',
81
- 'length',
82
- 'name',
83
- 'caller',
84
- 'arguments'
85
- ];
86
-
87
- const swapPrototypeProp = (
88
- liveCtor: ComponentCtor,
89
- newProto: ComponentCtor,
90
- prop: string
91
- ) => {
92
- if (prop === 'constructor') return;
93
- try {
94
- const desc = Object.getOwnPropertyDescriptor(newProto, prop);
95
- if (desc) Object.defineProperty(liveCtor.prototype, prop, desc);
96
- } catch {
97
- /* non-configurable */
98
- }
99
- };
100
-
101
- const swapStaticProp = (
102
- liveCtor: ComponentCtor,
103
- newCtor: ComponentCtor,
104
- prop: string
105
- ) => {
106
- if (SKIP_STATIC_PROPS.includes(prop)) return true;
107
- try {
108
- const desc = Object.getOwnPropertyDescriptor(newCtor, prop);
109
- if (!desc) return true;
110
- if (!desc.configurable) return prop !== 'ɵcmp' && prop !== 'ɵfac';
111
- Object.defineProperty(liveCtor, prop, desc);
112
-
113
- return true;
114
- } catch {
115
- return prop !== 'ɵcmp' && prop !== 'ɵfac';
116
- }
117
- };
118
-
119
- const patchConstructor = (entry: RegistryEntry, newCtor: ComponentCtor) => {
120
- const { liveCtor } = entry;
121
-
122
- const newProto = newCtor.prototype;
123
- Object.getOwnPropertyNames(newProto).forEach((prop) => {
124
- swapPrototypeProp(liveCtor, newProto, prop);
125
- });
126
-
127
- const allPatched = Object.getOwnPropertyNames(newCtor).every((prop) =>
128
- swapStaticProp(liveCtor, newCtor, prop)
129
- );
130
-
131
- if (!allPatched) {
132
- throw new Error('Cannot patch non-configurable Angular metadata');
133
- }
134
-
135
- globalUpdateCount++;
136
- entry.updateCount++;
137
- entry.registeredAt = Date.now();
138
- };
139
-
140
- const applyUpdate = (id: string, newCtor: ComponentCtor) => {
141
- const entry = componentRegistry.get(id);
142
- if (!entry) {
143
- register(id, newCtor);
144
-
145
- return true;
146
- }
147
-
148
- const { liveCtor } = entry;
149
- if (liveCtor === newCtor) return true;
150
-
151
- if (hasProviderChanges(liveCtor, newCtor)) {
152
- console.warn(
153
- '[HMR] Angular provider change detected for',
154
- id,
155
- '→ full reload'
156
- );
157
-
158
- return false;
159
- }
160
- if (newCtor.ɵcmp === undefined && liveCtor.ɵcmp !== undefined) {
161
- console.warn(
162
- '[HMR] New constructor missing ɵcmp for',
163
- id,
164
- '→ full reload'
165
- );
166
-
167
- return false;
168
- }
169
-
170
- try {
171
- patchConstructor(entry, newCtor);
172
-
173
- return true;
174
- } catch (err) {
175
- console.error('[HMR] Angular runtime patch failed for', id, ':', err);
176
-
177
- return false;
178
- }
179
- };
180
-
181
- const refresh = () => {
182
- if (!window.__ANGULAR_APP__) return;
183
- try {
184
- window.__ANGULAR_APP__.tick();
185
- } catch (err) {
186
- console.warn('[HMR] Angular tick() failed after patch:', err);
187
- }
188
- };
189
-
190
- export const installAngularHMRRuntime = () => {
191
- if (typeof window === 'undefined') return;
192
- window.__ANGULAR_HMR__ = {
193
- applyUpdate,
194
- refresh,
195
- register,
196
- getRegistry: () => componentRegistry,
197
- // eslint-disable-next-line absolute/no-useless-function -- must be a callable method on the HMR API
198
- getStats: () => ({
199
- componentCount: componentRegistry.size,
200
- updateCount: globalUpdateCount
201
- })
202
- };
203
- };
204
-
205
- installAngularHMRRuntime();
@@ -1,361 +0,0 @@
1
- /* HTML + script HMR update handlers */
2
-
3
- import { DOM_UPDATE_DELAY_MS } from '../constants';
4
- import { patchDOMInPlace } from '../domDiff';
5
- import {
6
- saveDOMState,
7
- restoreDOMState,
8
- saveFormState,
9
- restoreFormState,
10
- saveScrollState,
11
- restoreScrollState
12
- } from '../domState';
13
- import { processCSSLinks, waitForCSSAndUpdate } from '../cssUtils';
14
- import { patchHeadInPlace } from '../headPatch';
15
- import { detectCurrentFramework } from '../frameworkDetect';
16
- import { type ScriptInfo, hmrState } from '../.././../../types/client';
17
- import { restoreDOMChanges, snapshotDOMChanges } from '../domTracker';
18
-
19
- const parseHTMLMessage = (
20
- html: string | { body?: string; head?: string } | null | undefined
21
- ) => {
22
- let body: string | null = null;
23
- let head: string | null = null;
24
- if (typeof html === 'string') {
25
- body = html;
26
- } else if (html && typeof html === 'object') {
27
- body = html.body || null;
28
- head = html.head || null;
29
- }
30
-
31
- return { body, head };
32
- };
33
-
34
- const applyHeadPatch = (htmlHead: string | null) => {
35
- if (!htmlHead) {
36
- return;
37
- }
38
-
39
- const doPatchHead = () => {
40
- patchHeadInPlace(htmlHead);
41
- };
42
- if (hmrState.isFirstHMRUpdate) {
43
- setTimeout(doPatchHead, DOM_UPDATE_DELAY_MS);
44
- } else {
45
- doPatchHead();
46
- }
47
- };
48
-
49
- const handleHTMLBodyWithHead = (
50
- htmlBody: string,
51
- htmlHead: string,
52
- htmlDomState: ReturnType<typeof saveDOMState>
53
- ) => {
54
- applyHeadPatch(htmlHead);
55
-
56
- const cssResult = processCSSLinks(htmlHead);
57
-
58
- const updateBodyAfterCSS = () => {
59
- updateHTMLBody(htmlBody, htmlDomState, document.body);
60
- };
61
-
62
- waitForCSSAndUpdate(cssResult, updateBodyAfterCSS);
63
- };
64
-
65
- const handleHTMLBodyWithoutHead = (
66
- htmlBody: string,
67
- htmlDomState: ReturnType<typeof saveDOMState>
68
- ) => {
69
- const container = document.body;
70
- if (!container) {
71
- sessionStorage.removeItem('__HMR_ACTIVE__');
72
-
73
- return;
74
- }
75
-
76
- updateHTMLBodyDirect(htmlBody, htmlDomState, container);
77
- restoreDOMState(container, htmlDomState);
78
- };
79
-
80
- export const handleHTMLUpdate = (message: {
81
- data: {
82
- html?: string | { body?: string; head?: string } | null;
83
- };
84
- }) => {
85
- const htmlFrameworkCheck = detectCurrentFramework();
86
- if (htmlFrameworkCheck !== 'html') {
87
- return;
88
- }
89
-
90
- if (window.__REACT_ROOT__) {
91
- window.__REACT_ROOT__ = undefined;
92
- }
93
-
94
- sessionStorage.setItem('__HMR_ACTIVE__', 'true');
95
-
96
- const htmlDomState = saveDOMState(document.body);
97
- const { body: htmlBody, head: htmlHead } = parseHTMLMessage(
98
- message.data.html
99
- );
100
-
101
- if (!htmlBody) {
102
- sessionStorage.removeItem('__HMR_ACTIVE__');
103
-
104
- return;
105
- }
106
-
107
- if (htmlHead) {
108
- handleHTMLBodyWithHead(htmlBody, htmlHead, htmlDomState);
109
- } else {
110
- handleHTMLBodyWithoutHead(htmlBody, htmlDomState);
111
- }
112
- };
113
- export const handleScriptUpdate = (message: {
114
- data: { framework?: string; scriptPath?: string };
115
- }) => {
116
- const scriptFramework = message.data.framework;
117
- const currentFw = detectCurrentFramework();
118
-
119
- if (currentFw !== scriptFramework) {
120
- return;
121
- }
122
-
123
- const { scriptPath } = message.data;
124
- if (!scriptPath) {
125
- console.warn('[HMR] No script path in update');
126
-
127
- return;
128
- }
129
-
130
- const interactiveSelectors =
131
- 'button, [onclick], [onchange], [oninput], details, input, select, textarea';
132
- document.body.querySelectorAll(interactiveSelectors).forEach((elem) => {
133
- const cloned = elem.cloneNode(true);
134
- if (elem.parentNode) {
135
- elem.parentNode.replaceChild(cloned, elem);
136
- }
137
- });
138
-
139
- const cacheBustedPath = `${scriptPath}?t=${Date.now()}`;
140
- import(cacheBustedPath)
141
- .then(() => true)
142
- .catch((err: unknown) => {
143
- console.error(
144
- '[HMR] Script hot-reload failed, falling back to page reload:',
145
- err
146
- );
147
- window.location.reload();
148
- });
149
- };
150
-
151
- // eslint-disable-next-line absolute/no-useless-function -- must be called each time to capture current state
152
- const saveHTMLState = () => ({
153
- forms: saveFormState(),
154
- scroll: saveScrollState()
155
- });
156
-
157
- const preserveHmrScript = (
158
- container: HTMLElement,
159
- hmrScript: Element | null
160
- ) => {
161
- if (hmrScript && !container.querySelector('script[data-hmr-client]')) {
162
- container.appendChild(hmrScript);
163
- }
164
- };
165
-
166
- const updateHTMLBody = (
167
- htmlBody: string,
168
- htmlDomState: ReturnType<typeof saveDOMState>,
169
- container: HTMLElement
170
- ) => {
171
- if (!container) {
172
- return;
173
- }
174
-
175
- const savedState = saveHTMLState();
176
- const domSnapshot = snapshotDOMChanges(container);
177
-
178
- const existingScripts = collectScripts(container);
179
- const hmrScript = container.querySelector('script[data-hmr-client]');
180
- const tempDiv = document.createElement('div');
181
- tempDiv.innerHTML = htmlBody;
182
- const newScripts = collectScriptsFromElement(tempDiv);
183
-
184
- const htmlStructureChanged = didHTMLStructureChange(container, tempDiv);
185
-
186
- if (htmlStructureChanged || didScriptsChange(existingScripts, newScripts)) {
187
- patchDOMInPlace(container, htmlBody);
188
- restoreDOMChanges(container, domSnapshot, htmlBody);
189
- }
190
-
191
- preserveHmrScript(container, hmrScript);
192
-
193
- requestAnimationFrame(() => {
194
- restoreDOMState(container, htmlDomState);
195
- restoreFormState(savedState.forms);
196
- restoreScrollState(savedState.scroll);
197
-
198
- if (
199
- didScriptsChange(existingScripts, newScripts) ||
200
- htmlStructureChanged
201
- ) {
202
- cloneInteractiveElements(container);
203
- reExecuteScripts(container, newScripts);
204
- }
205
- });
206
- sessionStorage.removeItem('__HMR_ACTIVE__');
207
- };
208
-
209
- const cloneHmrListenerElements = (container: HTMLElement) => {
210
- container
211
- .querySelectorAll('[data-hmr-listeners-attached]')
212
- .forEach((elem) => {
213
- const cloned = elem.cloneNode(true);
214
- if (elem.parentNode) {
215
- elem.parentNode.replaceChild(cloned, elem);
216
- }
217
- if (cloned instanceof Element) {
218
- cloned.removeAttribute('data-hmr-listeners-attached');
219
- }
220
- });
221
- };
222
-
223
- const replaceInlineScript = (script: Element) => {
224
- if (script.hasAttribute('data-hmr-client')) {
225
- return;
226
- }
227
-
228
- const newScript = document.createElement('script');
229
- newScript.textContent = script.textContent || '';
230
- const scriptEl = script instanceof HTMLScriptElement ? script : null;
231
- newScript.type = scriptEl?.type || 'text/javascript';
232
- if (script.parentNode) {
233
- script.parentNode.replaceChild(newScript, script);
234
- }
235
- };
236
-
237
- const updateHTMLBodyDirect = (
238
- htmlBody: string,
239
- htmlDomState: ReturnType<typeof saveDOMState>,
240
- container: HTMLElement
241
- ) => {
242
- const savedState = saveHTMLState();
243
- const domSnapshot = snapshotDOMChanges(container);
244
-
245
- const tempDiv = document.createElement('div');
246
- tempDiv.innerHTML = htmlBody;
247
- const newScripts = collectScriptsFromElement(tempDiv);
248
- const hmrScript = container.querySelector('script[data-hmr-client]');
249
-
250
- patchDOMInPlace(container, htmlBody);
251
- restoreDOMChanges(container, domSnapshot, htmlBody);
252
-
253
- preserveHmrScript(container, hmrScript);
254
-
255
- requestAnimationFrame(() => {
256
- restoreDOMState(container, htmlDomState);
257
- restoreFormState(savedState.forms);
258
- restoreScrollState(savedState.scroll);
259
-
260
- cloneHmrListenerElements(container);
261
-
262
- removeOldScripts(container);
263
- newScripts.forEach((scriptInfo) => {
264
- const newScript = document.createElement('script');
265
- const separator = scriptInfo.src.includes('?') ? '&' : '?';
266
- newScript.src = `${scriptInfo.src + separator}t=${Date.now()}`;
267
- newScript.type = scriptInfo.type;
268
- container.appendChild(newScript);
269
- });
270
-
271
- const inlineScripts = container.querySelectorAll('script:not([src])');
272
- inlineScripts.forEach(replaceInlineScript);
273
- });
274
- sessionStorage.removeItem('__HMR_ACTIVE__');
275
- };
276
-
277
- /* Shared helpers for HTML body updates */
278
-
279
- const collectScripts = (container: HTMLElement) =>
280
- Array.from(container.querySelectorAll('script[src]')).map((script) => ({
281
- src: script.getAttribute('src') || '',
282
- type: script.getAttribute('type') || 'text/javascript'
283
- }));
284
-
285
- const collectScriptsFromElement = (elem: HTMLElement) =>
286
- Array.from(elem.querySelectorAll('script[src]')).map((script) => ({
287
- src: script.getAttribute('src') || '',
288
- type: script.getAttribute('type') || 'text/javascript'
289
- }));
290
-
291
- const didScriptsChange = (oldScripts: ScriptInfo[], newScripts: ScriptInfo[]) =>
292
- oldScripts.length !== newScripts.length ||
293
- oldScripts.some((oldScript, idx) => {
294
- const [oldSrcBase] = oldScript.src.split('?')[0]?.split('&') ?? [''];
295
- const newScript = newScripts[idx];
296
- if (!newScript) return true;
297
- const [newSrcBase] = newScript.src.split('?')[0]?.split('&') ?? [''];
298
-
299
- return oldSrcBase !== newSrcBase;
300
- });
301
-
302
- const normalizeHTMLForComparison = (element: HTMLElement) => {
303
- const clonedNode = element.cloneNode(true);
304
- if (!(clonedNode instanceof HTMLElement)) return '';
305
- const clone = clonedNode;
306
- const scripts = clone.querySelectorAll('script');
307
- scripts.forEach((script) => {
308
- if (script.parentNode) {
309
- script.parentNode.removeChild(script);
310
- }
311
- });
312
- const allElements = clone.querySelectorAll('*');
313
- allElements.forEach((elem) => {
314
- elem.removeAttribute('data-hmr-listeners-attached');
315
- });
316
- if (clone.removeAttribute) {
317
- clone.removeAttribute('data-hmr-listeners-attached');
318
- }
319
-
320
- return clone.innerHTML;
321
- };
322
-
323
- const didHTMLStructureChange = (container: HTMLElement, tempDiv: HTMLElement) =>
324
- normalizeHTMLForComparison(container) !==
325
- normalizeHTMLForComparison(tempDiv);
326
-
327
- const cloneInteractiveElements = (container: HTMLElement) => {
328
- const interactiveSelectors =
329
- 'button, [onclick], [onchange], [oninput], [onsubmit], ' +
330
- 'details, input[type="button"], input[type="submit"], input[type="reset"]';
331
- container.querySelectorAll(interactiveSelectors).forEach((elem) => {
332
- const cloned = elem.cloneNode(true);
333
- if (elem.parentNode) {
334
- elem.parentNode.replaceChild(cloned, elem);
335
- }
336
- });
337
- };
338
-
339
- const removeOldScripts = (container: HTMLElement) => {
340
- const scriptsInNewHTML = container.querySelectorAll('script[src]');
341
- scriptsInNewHTML.forEach((script) => {
342
- if (!script.hasAttribute('data-hmr-client')) {
343
- script.remove();
344
- }
345
- });
346
- };
347
-
348
- const reExecuteScripts = (container: HTMLElement, newScripts: ScriptInfo[]) => {
349
- removeOldScripts(container);
350
-
351
- newScripts.forEach((scriptInfo) => {
352
- const newScript = document.createElement('script');
353
- const separator = scriptInfo.src.includes('?') ? '&' : '?';
354
- newScript.src = `${scriptInfo.src + separator}t=${Date.now()}`;
355
- newScript.type = scriptInfo.type;
356
- container.appendChild(newScript);
357
- });
358
-
359
- const inlineScripts = container.querySelectorAll('script:not([src])');
360
- inlineScripts.forEach(replaceInlineScript);
361
- };