@absolutejs/absolute 0.19.0-beta.705 → 0.19.0-beta.707

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 (41) hide show
  1. package/dist/angular/browser.js +6 -4
  2. package/dist/angular/browser.js.map +3 -3
  3. package/dist/angular/components/constants.js +1 -0
  4. package/dist/angular/index.js +17 -10
  5. package/dist/angular/index.js.map +5 -5
  6. package/dist/angular/server.js +17 -10
  7. package/dist/angular/server.js.map +5 -5
  8. package/dist/build.js +126 -66
  9. package/dist/build.js.map +12 -12
  10. package/dist/cli/index.js +186 -126
  11. package/dist/dev/client/cssUtils.ts +47 -47
  12. package/dist/dev/client/handlers/angular.ts +40 -19
  13. package/dist/dev/client/handlers/angularRuntime.ts +28 -8
  14. package/dist/dev/client/handlers/html.ts +6 -5
  15. package/dist/dev/client/handlers/htmx.ts +8 -2
  16. package/dist/dev/client/handlers/svelte.ts +16 -14
  17. package/dist/dev/client/hmrClient.ts +25 -3
  18. package/dist/dev/client/reactRefreshSetup.ts +2 -3
  19. package/dist/index.js +151 -79
  20. package/dist/index.js.map +14 -14
  21. package/dist/islands/index.js +4 -4
  22. package/dist/islands/index.js.map +4 -4
  23. package/dist/react/index.js +17 -10
  24. package/dist/react/index.js.map +5 -5
  25. package/dist/react/server.js +15 -8
  26. package/dist/react/server.js.map +4 -4
  27. package/dist/src/angular/components/constants.d.ts +1 -0
  28. package/dist/src/build/buildAngularVendor.d.ts +3 -4
  29. package/dist/src/constants.d.ts +1 -0
  30. package/dist/src/utils/imageProcessing.d.ts +1 -1
  31. package/dist/src/vue/components/Image.d.ts +1 -1
  32. package/dist/svelte/index.js +17 -10
  33. package/dist/svelte/index.js.map +5 -5
  34. package/dist/svelte/server.js +15 -8
  35. package/dist/svelte/server.js.map +4 -4
  36. package/dist/types/globals.d.ts +1 -0
  37. package/dist/vue/index.js +17 -10
  38. package/dist/vue/index.js.map +5 -5
  39. package/dist/vue/server.js +15 -8
  40. package/dist/vue/server.js.map +4 -4
  41. package/package.json +1 -1
@@ -37,8 +37,35 @@ type HMRMessage = {
37
37
  };
38
38
  };
39
39
 
40
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- type NgApi = any;
40
+ type NgApi = {
41
+ applyChanges?: (component: unknown) => void;
42
+ getComponent?: (element: Element) => unknown;
43
+ };
44
+
45
+ type AngularClientWindow = Window & {
46
+ ng?: NgApi;
47
+ };
48
+
49
+ type AngularHmrApi = {
50
+ applyUpdate: (id: string, newCtor: unknown) => boolean;
51
+ getRegistry?: () => Map<string, unknown>;
52
+ refresh: () => void;
53
+ };
54
+
55
+ type ViewTransitionDocument = Document & {
56
+ startViewTransition?: (updateCallback: () => Promise<void>) => {
57
+ finished: Promise<void>;
58
+ };
59
+ };
60
+
61
+ type AngularComponentExport = ((...args: unknown[]) => unknown) & {
62
+ ɵcmp?: unknown;
63
+ };
64
+
65
+ const isAngularComponentExport = (
66
+ value: unknown
67
+ ): value is AngularComponentExport =>
68
+ typeof value === 'function' && Boolean(value.ɵcmp);
42
69
 
43
70
  const swapStylesheet = (
44
71
  cssUrl: string,
@@ -122,8 +149,8 @@ const captureInstanceProperties = (
122
149
  const captureComponentState = () => {
123
150
  const snapshots: StateSnapshot[] = [];
124
151
  const selectorCounts = new Map<string, number>();
125
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
126
- const ngApi: NgApi = (window as any).ng;
152
+ const angularWindow: AngularClientWindow = window;
153
+ const ngApi = angularWindow.ng;
127
154
 
128
155
  document.querySelectorAll('*').forEach((elem) => {
129
156
  const tagName = elem.tagName.toLowerCase();
@@ -208,8 +235,8 @@ const restoreDomFallback = (element: Element, snap: StateSnapshot) => {
208
235
  };
209
236
 
210
237
  const restoreComponentState = (snapshots: StateSnapshot[]) => {
211
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
212
- const ngApi: NgApi = (window as any).ng;
238
+ const angularWindow: AngularClientWindow = window;
239
+ const ngApi = angularWindow.ng;
213
240
  if (snapshots.length === 0) return;
214
241
 
215
242
  const bySelector = new Map<string, StateSnapshot[]>();
@@ -282,15 +309,13 @@ const suppressNg0912 = () => {
282
309
 
283
310
  const tryPatchExport = (
284
311
  exportName: string,
285
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
286
- newModule: Record<string, any>,
312
+ newModule: Record<string, unknown>,
287
313
  registry: Map<string, unknown>,
288
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
289
- hmr: any,
314
+ hmr: AngularHmrApi,
290
315
  sourceFile: string
291
316
  ) => {
292
317
  const exported = newModule[exportName];
293
- if (typeof exported !== 'function' || !exported.ɵcmp) return 'skip';
318
+ if (!isAngularComponentExport(exported)) return 'skip';
294
319
 
295
320
  const registryId = `${sourceFile}#${exportName}`;
296
321
  if (!registry.has(registryId)) return 'skip';
@@ -302,11 +327,9 @@ const tryPatchExport = (
302
327
  };
303
328
 
304
329
  const patchRegisteredComponents = (
305
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
306
- newModule: Record<string, any>,
330
+ newModule: Record<string, unknown>,
307
331
  registry: Map<string, unknown>,
308
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
309
- hmr: any,
332
+ hmr: AngularHmrApi,
310
333
  sourceFile: string
311
334
  ) => {
312
335
  let patchedAny = false;
@@ -335,8 +358,7 @@ const patchRegisteredComponents = (
335
358
  const attemptFastPatch = async (
336
359
  indexPath: string,
337
360
  registry: Map<string, unknown>,
338
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
339
- hmr: any,
361
+ hmr: AngularHmrApi,
340
362
  sourceFile: string,
341
363
  origWarn: typeof console.warn
342
364
  ) => {
@@ -484,8 +506,7 @@ const tickAngularApp = () => {
484
506
  };
485
507
 
486
508
  const runWithViewTransition = (updateFn: () => Promise<void>) => {
487
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
488
- const doc = document as any;
509
+ const doc: ViewTransitionDocument = document;
489
510
  if (typeof doc.startViewTransition !== 'function') {
490
511
  updateFn().catch((err: unknown) => {
491
512
  console.warn('[HMR] Angular update failed (non-fatal):', err);
@@ -22,8 +22,16 @@ import type {} from '../../../types/globals';
22
22
  Vue instances, or Svelte components. The registry is keyed by
23
23
  source file path, so name collisions across frameworks are impossible. */
24
24
 
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- type ComponentCtor = any;
25
+ type AngularComponentDefinition = {
26
+ providers?: unknown;
27
+ providersResolver?: unknown;
28
+ };
29
+
30
+ type ComponentCtor = (abstract new (...args: never[]) => unknown) & {
31
+ ɵcmp?: AngularComponentDefinition;
32
+ ɵfac?: unknown;
33
+ ɵinj?: AngularComponentDefinition;
34
+ };
27
35
 
28
36
  type RegistryEntry = {
29
37
  liveCtor: ComponentCtor;
@@ -32,6 +40,11 @@ type RegistryEntry = {
32
40
  updateCount: number;
33
41
  };
34
42
 
43
+ type AngularHmrStats = {
44
+ readonly componentCount: number;
45
+ readonly updateCount: number;
46
+ };
47
+
35
48
  const componentRegistry = new Map<string, RegistryEntry>();
36
49
  let globalUpdateCount = 0;
37
50
 
@@ -188,18 +201,25 @@ const refresh = () => {
188
201
  }
189
202
  };
190
203
 
204
+ const angularHmrStats: AngularHmrStats = {
205
+ get componentCount() {
206
+ return componentRegistry.size;
207
+ },
208
+ get updateCount() {
209
+ return globalUpdateCount;
210
+ }
211
+ };
212
+
213
+ const getAngularHmrStats = () => angularHmrStats;
214
+
191
215
  export const installAngularHMRRuntime = () => {
192
216
  if (typeof window === 'undefined') return;
193
217
  window.__ANGULAR_HMR__ = {
194
218
  applyUpdate,
219
+ getStats: getAngularHmrStats,
195
220
  refresh,
196
221
  register,
197
- getRegistry: () => componentRegistry,
198
- // eslint-disable-next-line absolute/no-useless-function -- must be a callable method on the HMR API
199
- getStats: () => ({
200
- componentCount: componentRegistry.size,
201
- updateCount: globalUpdateCount
202
- })
222
+ getRegistry: () => componentRegistry
203
223
  };
204
224
  };
205
225
 
@@ -150,11 +150,12 @@ export const handleScriptUpdate = (message: {
150
150
  });
151
151
  };
152
152
 
153
- // eslint-disable-next-line absolute/no-useless-function -- must be called each time to capture current state
154
- const saveHTMLState = () => ({
155
- forms: saveFormState(),
156
- scroll: saveScrollState()
157
- });
153
+ const saveHTMLState = () => {
154
+ const forms = saveFormState();
155
+ const scroll = saveScrollState();
156
+
157
+ return { forms, scroll };
158
+ };
158
159
 
159
160
  const preserveHmrScript = (
160
161
  container: HTMLElement,
@@ -97,7 +97,8 @@ const cloneHmrListenerElements = (container: HTMLElement) => {
97
97
  container
98
98
  .querySelectorAll('[data-hmr-listeners-attached]')
99
99
  .forEach((elem) => {
100
- const cloned = elem.cloneNode(true) as Element; // eslint-disable-line @typescript-eslint/consistent-type-assertions
100
+ const cloned = elem.cloneNode(true);
101
+ if (!(cloned instanceof Element)) return;
101
102
  if (elem.parentNode) {
102
103
  elem.parentNode.replaceChild(cloned, elem);
103
104
  }
@@ -249,7 +250,12 @@ const didScriptsChange = (oldScripts: ScriptInfo[], newScripts: ScriptInfo[]) =>
249
250
  });
250
251
 
251
252
  const normalizeHTMLForComparison = (element: HTMLElement) => {
252
- const clone = element.cloneNode(true) as HTMLElement; // eslint-disable-line @typescript-eslint/consistent-type-assertions
253
+ const clonedNode = element.cloneNode(true);
254
+ if (!(clonedNode instanceof HTMLElement)) {
255
+ return element.innerHTML;
256
+ }
257
+
258
+ const clone = clonedNode;
253
259
  const scripts = clone.querySelectorAll('script');
254
260
  scripts.forEach((script) => {
255
261
  if (script.parentNode) {
@@ -10,6 +10,10 @@ import {
10
10
  } from '../domState';
11
11
  import { detectCurrentFramework, findIndexPath } from '../frameworkDetect';
12
12
 
13
+ type SvelteHmrWindow = Window & {
14
+ __SVELTE_HMR_ACCEPT__?: Record<string, (mod: unknown) => void>;
15
+ };
16
+
13
17
  /* Swap a stylesheet link by matching cssBaseName or framework name */
14
18
  const swapStylesheet = (
15
19
  cssUrl: string,
@@ -156,16 +160,16 @@ const buildLinkLoadPromise = (link: HTMLLinkElement) => {
156
160
  return null;
157
161
  }
158
162
 
159
- // eslint-disable-next-line promise/avoid-new -- wrapping DOM event callbacks requires a new Promise
160
- return new Promise<void>((resolve) => {
161
- link.onload = () => {
162
- resolve();
163
- };
164
- link.onerror = () => {
165
- resolve();
166
- };
167
- setTimeout(resolve, SVELTE_CSS_LOAD_TIMEOUT_MS);
168
- });
163
+ const { promise, resolve } = Promise.withResolvers<void>();
164
+ link.onload = () => {
165
+ resolve();
166
+ };
167
+ link.onerror = () => {
168
+ resolve();
169
+ };
170
+ setTimeout(resolve, SVELTE_CSS_LOAD_TIMEOUT_MS);
171
+
172
+ return promise;
169
173
  };
170
174
 
171
175
  const cleanupAfterImport = (
@@ -266,10 +270,8 @@ export const handleSvelteUpdate = (message: {
266
270
  const clientStart = performance.now();
267
271
  const modulePath = `${pageModuleUrl}?t=${Date.now()}`;
268
272
 
269
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
270
- const acceptRegistry = (window as any).__SVELTE_HMR_ACCEPT__ as
271
- | Record<string, (mod: unknown) => void>
272
- | undefined;
273
+ const svelteWindow: SvelteHmrWindow = window;
274
+ const acceptRegistry = svelteWindow.__SVELTE_HMR_ACCEPT__;
273
275
 
274
276
  // Save the OLD module's accept callback BEFORE importing.
275
277
  const acceptFn = acceptRegistry?.[pageModuleUrl];
@@ -81,8 +81,30 @@ const hmrUpdateTypes = new Set([
81
81
  'rebuild-start'
82
82
  ]);
83
83
 
84
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
- const handleHMRMessage = (message: any) => {
84
+ type HMRMessage = {
85
+ data: {
86
+ affectedFrameworks?: string[];
87
+ column?: number;
88
+ error?: string;
89
+ file?: string;
90
+ framework?: string;
91
+ hasCSSChanges?: boolean;
92
+ hasComponentChanges?: boolean;
93
+ html?: string | { body?: string; head?: string; html?: string };
94
+ line?: number;
95
+ lineText?: string;
96
+ manifest?: Record<string, string>;
97
+ moduleVersions?: Record<string, number>;
98
+ pageModuleUrl?: string;
99
+ primarySource?: string;
100
+ scriptUrl?: string;
101
+ serverDuration?: number;
102
+ serverVersions?: Record<string, number>;
103
+ };
104
+ type: string;
105
+ };
106
+
107
+ const handleHMRMessage = (message: HMRMessage) => {
86
108
  if (hmrUpdateTypes.has(message.type)) {
87
109
  hmrState.isHMRUpdating = true;
88
110
  setTimeout(() => {
@@ -141,7 +163,7 @@ const handleHMRMessage = (message: any) => {
141
163
  case 'pong':
142
164
  break;
143
165
  case 'style-update':
144
- reloadCSSStylesheets(message.data.manifest);
166
+ reloadCSSStylesheets(message.data.manifest ?? {});
145
167
  break;
146
168
  default:
147
169
  break;
@@ -8,9 +8,8 @@ import type {} from '../../types/globals';
8
8
  is preserved so new component registrations feed into the SAME RefreshRuntime
9
9
  instance that owns the current React tree. */
10
10
 
11
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
- // @ts-ignore react-refresh has no type declarations
13
- import RefreshRuntime from 'react-refresh/runtime';
11
+
12
+ import * as RefreshRuntime from 'react-refresh/runtime';
14
13
 
15
14
  if (!window.$RefreshRuntime$) {
16
15
  RefreshRuntime.injectIntoGlobalHook(window);