@absolutejs/absolute 0.19.0-beta.1114 → 0.19.0-beta.1116

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 (90) hide show
  1. package/dist/angular/browser.js +53 -47
  2. package/dist/angular/browser.js.map +5 -5
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  4. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  5. package/dist/angular/hmrPreserveCore.ts +73 -34
  6. package/dist/angular/index.js +63 -58
  7. package/dist/angular/index.js.map +10 -10
  8. package/dist/angular/server.js +20 -38
  9. package/dist/angular/server.js.map +8 -8
  10. package/dist/build.js +601 -547
  11. package/dist/build.js.map +32 -32
  12. package/dist/cli/config/client.js +8 -8
  13. package/dist/cli/config/server.js +87 -75
  14. package/dist/cli/index.js +146 -127
  15. package/dist/client/index.js +1 -19
  16. package/dist/client/index.js.map +3 -3
  17. package/dist/core/streamingSlotRegistrar.js +1 -19
  18. package/dist/core/streamingSlotRegistrar.js.map +2 -2
  19. package/dist/core/streamingSlotRegistry.js +1 -19
  20. package/dist/core/streamingSlotRegistry.js.map +2 -2
  21. package/dist/dev/client/errorOverlay.ts +11 -10
  22. package/dist/dev/client/handlers/angularHmrShim.ts +6 -6
  23. package/dist/dev/client/handlers/angularRemount.ts +64 -44
  24. package/dist/dev/client/hmrClient.ts +31 -26
  25. package/dist/dev/client/hmrToast.ts +2 -4
  26. package/dist/dev/serverBootstrap.js +36 -0
  27. package/dist/index.js +742 -615
  28. package/dist/index.js.map +39 -38
  29. package/dist/islands/browser.js +1 -19
  30. package/dist/islands/browser.js.map +2 -2
  31. package/dist/islands/index.js +1 -19
  32. package/dist/islands/index.js.map +3 -3
  33. package/dist/react/browser.js +1 -19
  34. package/dist/react/browser.js.map +2 -2
  35. package/dist/react/components/index.js +1 -19
  36. package/dist/react/components/index.js.map +2 -2
  37. package/dist/react/hooks/index.js +1 -19
  38. package/dist/react/hooks/index.js.map +2 -2
  39. package/dist/react/index.js +15 -37
  40. package/dist/react/index.js.map +7 -7
  41. package/dist/react/jsxDevRuntimeCompat.js +1 -19
  42. package/dist/react/jsxDevRuntimeCompat.js.map +2 -2
  43. package/dist/react/router/browser.js +1 -19
  44. package/dist/react/router/browser.js.map +2 -2
  45. package/dist/react/router/index.js +1 -19
  46. package/dist/react/router/index.js.map +2 -2
  47. package/dist/react/server.js +15 -37
  48. package/dist/react/server.js.map +6 -6
  49. package/dist/src/angular/hmrPreserveCore.d.ts +2 -2
  50. package/dist/src/cli/config/absolute/resolveAbsoluteConfig.d.ts +1 -1
  51. package/dist/src/cli/config/auth/resolveAuthSettings.d.ts +1 -1
  52. package/dist/src/cli/config/packageJson/resolvePackageJson.d.ts +1 -2
  53. package/dist/src/cli/config/schema/fromType.d.ts +1 -2
  54. package/dist/src/cli/config/server.d.ts +2 -2
  55. package/dist/src/core/build.d.ts +3 -2
  56. package/dist/src/core/prepare.d.ts +1 -0
  57. package/dist/src/dev/angular/fastHmrCompiler.d.ts +4 -2
  58. package/dist/src/dev/serverBootstrap.d.ts +1 -0
  59. package/dist/src/dev/serverEntryWatcher.d.ts +3 -3
  60. package/dist/src/dev/webSocket.d.ts +1 -1
  61. package/dist/src/plugins/hmr.d.ts +1 -0
  62. package/dist/src/svelte/router/matchPath.d.ts +2 -2
  63. package/dist/src/utils/defineConvention.d.ts +2 -2
  64. package/dist/src/utils/inlinePageCss.d.ts +1 -1
  65. package/dist/src/utils/isTestSourcePath.d.ts +1 -0
  66. package/dist/svelte/browser.js +1 -19
  67. package/dist/svelte/browser.js.map +2 -2
  68. package/dist/svelte/index.js +15 -36
  69. package/dist/svelte/index.js.map +8 -8
  70. package/dist/svelte/router/Link.svelte.d.ts +3 -3
  71. package/dist/svelte/router/Route.svelte.d.ts +5 -5
  72. package/dist/svelte/router/Router.svelte.d.ts +3 -3
  73. package/dist/svelte/router/matchPath.ts +25 -20
  74. package/dist/svelte/router/prefetchCache.ts +6 -4
  75. package/dist/svelte/router/viewTransitions.ts +22 -12
  76. package/dist/svelte/server.js +15 -36
  77. package/dist/svelte/server.js.map +7 -7
  78. package/dist/types/angular.d.ts +1 -1
  79. package/dist/types/globals.d.ts +5 -0
  80. package/dist/vue/browser.js +1 -19
  81. package/dist/vue/browser.js.map +2 -2
  82. package/dist/vue/components/Image.js +1 -19
  83. package/dist/vue/components/Image.js.map +2 -2
  84. package/dist/vue/components/index.js +1 -19
  85. package/dist/vue/components/index.js.map +2 -2
  86. package/dist/vue/index.js +41 -55
  87. package/dist/vue/index.js.map +10 -10
  88. package/dist/vue/server.js +32 -48
  89. package/dist/vue/server.js.map +8 -8
  90. package/package.json +285 -19
@@ -76,6 +76,19 @@ type LiveInstance = {
76
76
  tNode: TNode;
77
77
  };
78
78
 
79
+ const isComponentClass = (value: unknown): value is ComponentClass =>
80
+ typeof value === 'function';
81
+
82
+ const isTNode = (value: unknown): value is TNode =>
83
+ typeof value === 'object' &&
84
+ value !== null &&
85
+ typeof Reflect.get(value, 'index') === 'number';
86
+
87
+ const isTView = (value: unknown): value is TView =>
88
+ typeof value === 'object' &&
89
+ value !== null &&
90
+ typeof Reflect.get(value, 'bindingStartIndex') === 'number';
91
+
79
92
  /* Walk the DOM looking for elements whose component instance is of
80
93
  * `Class`. Each match resolves to its parent LView + slot index via
81
94
  * the LContext stored on the host element under `__ngContext__`.
@@ -86,31 +99,31 @@ type LiveInstance = {
86
99
  const findLiveInstances = (Class: ComponentClass) => {
87
100
  const results: LiveInstance[] = [];
88
101
  const elements = document.querySelectorAll('*');
89
- for (const el of Array.from(elements)) {
90
- const ctx = (el as unknown as Record<string, unknown>).__ngContext__;
102
+ for (const element of Array.from(elements)) {
103
+ const ctx = Reflect.get(element, '__ngContext__');
91
104
  if (typeof ctx !== 'object' || ctx === null) continue;
92
- const lContext = ctx as { lView?: LView; nodeIndex?: number };
93
- if (!lContext.lView || lContext.nodeIndex === undefined) continue;
105
+ const lView = Reflect.get(ctx, 'lView');
106
+ const nodeIndex = Reflect.get(ctx, 'nodeIndex');
107
+ if (!isLView(lView) || typeof nodeIndex !== 'number') continue;
94
108
 
95
- const slot = lContext.lView[lContext.nodeIndex];
109
+ const slot = lView[nodeIndex];
96
110
  if (!isLView(slot)) continue;
97
- const ownLView = slot;
98
- const instance = ownLView[CONTEXT];
111
+ const instance = slot[CONTEXT];
99
112
  if (!(instance instanceof Class)) continue;
100
113
 
101
- const tNode = ownLView[T_HOST] as TNode | null;
102
- const host = ownLView[HOST] as Element | null;
103
- if (!tNode || !host) continue;
114
+ const tNode = slot[T_HOST];
115
+ const host = slot[HOST];
116
+ if (!isTNode(tNode) || !(host instanceof Element)) continue;
104
117
 
105
118
  // Avoid double-recording the same LView (multiple DOM elements
106
119
  // can land in the same component, all sharing __ngContext__)
107
- if (results.some((r) => r.oldLView === ownLView)) continue;
120
+ if (results.some((result) => result.oldLView === slot)) continue;
108
121
 
109
122
  results.push({
110
123
  host,
111
- oldLView: ownLView,
112
- parentLView: lContext.lView,
113
- slotIndex: lContext.nodeIndex,
124
+ oldLView: slot,
125
+ parentLView: lView,
126
+ slotIndex: nodeIndex,
114
127
  tNode
115
128
  });
116
129
  }
@@ -130,10 +143,9 @@ const createFreshAt = (
130
143
  newLView: LView;
131
144
  componentRef: ReturnType<AngularCoreNamespace['createComponent']>;
132
145
  } | null => {
133
- const w = window as unknown as {
134
- __ANGULAR_APP__?: { injector: unknown };
135
- };
136
- const envInjector = w.__ANGULAR_APP__?.injector;
146
+ const envInjector = window.__ANGULAR_APP__
147
+ ? Reflect.get(window.__ANGULAR_APP__, 'injector')
148
+ : undefined;
137
149
  if (!envInjector) return null;
138
150
 
139
151
  const ref = core.createComponent(Class, {
@@ -177,16 +189,12 @@ const spliceLViewIntoParent = (
177
189
  newLView[T_HOST] = tNode;
178
190
 
179
191
  const oldInstance = oldLView[CONTEXT];
180
- const tNodeWithDirectiveRange = tNode as TNode & {
181
- directiveStart?: number;
182
- directiveEnd?: number;
183
- };
184
- const start = tNodeWithDirectiveRange.directiveStart;
185
- const end = tNodeWithDirectiveRange.directiveEnd;
192
+ const start = Reflect.get(tNode, 'directiveStart');
193
+ const end = Reflect.get(tNode, 'directiveEnd');
186
194
  if (typeof start === 'number' && typeof end === 'number') {
187
- for (let i = start; i < end; i++) {
188
- if (parentLView[i] === oldInstance) {
189
- parentLView[i] = newInstance;
195
+ for (let index = start; index < end; index++) {
196
+ if (parentLView[index] === oldInstance) {
197
+ parentLView[index] = newInstance;
190
198
  }
191
199
  }
192
200
  }
@@ -197,8 +205,8 @@ const spliceLViewIntoParent = (
197
205
  * fire. Then mark the LView as destroyed so any subsequent
198
206
  * tree-walk skips it. */
199
207
  const teardownOldLView = (oldLView: LView) => {
200
- const oldTView = oldLView[TVIEW] as TView | null;
201
- if (oldTView) {
208
+ const oldTView = oldLView[TVIEW];
209
+ if (isTView(oldTView)) {
202
210
  executeOnDestroys(oldTView, oldLView);
203
211
  processCleanups(oldTView, oldLView);
204
212
  }
@@ -225,20 +233,33 @@ const teardownOldLView = (oldLView: LView) => {
225
233
  * - `{ propName: ['publicName', 'classFieldName', transformFn?] }` */
226
234
  const copyInputsFromOldToNew = (oldInstance: unknown, newInstance: unknown) => {
227
235
  if (!oldInstance || !newInstance) return;
228
- const def = (newInstance as { constructor?: { ɵcmp?: unknown } })
229
- .constructor?.ɵcmp as { inputs?: Record<string, unknown> } | undefined;
230
- const inputs = def?.inputs;
231
- if (!inputs) return;
236
+ if (
237
+ (typeof oldInstance !== 'object' &&
238
+ typeof oldInstance !== 'function') ||
239
+ (typeof newInstance !== 'object' && typeof newInstance !== 'function')
240
+ ) {
241
+ return;
242
+ }
243
+ const constructor = Reflect.get(newInstance, 'constructor');
244
+ const definition =
245
+ typeof constructor === 'function'
246
+ ? Reflect.get(constructor, 'ɵcmp')
247
+ : undefined;
248
+ if (typeof definition !== 'object' || definition === null) return;
249
+ const inputs = Reflect.get(definition, 'inputs');
250
+ if (typeof inputs !== 'object' || inputs === null) return;
232
251
 
233
252
  // Modern Angular inputs format (since v17ish): the OBJECT KEY is
234
253
  // the class property name; the value is either a string (binding
235
254
  // name) or `[bindingName, flags, transformFn?]`. So the class
236
255
  // field name is just `Object.keys(inputs)`.
237
256
  for (const classField of Object.keys(inputs)) {
238
- const oldRec = oldInstance as Record<string, unknown>;
239
- const newRec = newInstance as Record<string, unknown>;
240
- if (classField in oldRec) {
241
- newRec[classField] = oldRec[classField];
257
+ if (classField in oldInstance) {
258
+ Reflect.set(
259
+ newInstance,
260
+ classField,
261
+ Reflect.get(oldInstance, classField)
262
+ );
242
263
  }
243
264
  }
244
265
  };
@@ -288,13 +309,15 @@ export const remountComponentClass = async (
288
309
  namespaces,
289
310
  ...locals
290
311
  ]);
291
- if (typeof returned === 'function') {
292
- FreshClass = returned as ComponentClass;
312
+ if (isComponentClass(returned)) {
313
+ FreshClass = returned;
293
314
  }
294
315
  } catch (err) {
295
316
  return {
296
317
  className,
297
- error: `applyMetadata threw: ${(err as Error).message}`,
318
+ error: `applyMetadata threw: ${
319
+ err instanceof Error ? err.message : String(err)
320
+ }`,
298
321
  remounted: 0,
299
322
  skipped: 0
300
323
  };
@@ -342,11 +365,8 @@ export const remountComponentClass = async (
342
365
  // fresh creation. Without this tick, a remounted component
343
366
  // shows default field values until the user interacts and
344
367
  // triggers a stray CD elsewhere.
345
- const w = window as unknown as {
346
- __ANGULAR_APP__?: { tick?: () => void };
347
- };
348
368
  try {
349
- w.__ANGULAR_APP__?.tick?.();
369
+ window.__ANGULAR_APP__?.tick();
350
370
  } catch (err) {
351
371
  console.error(
352
372
  '[absolutejs] post-remount tick threw — partial state',
@@ -32,6 +32,13 @@ import {
32
32
  handleRebuildError
33
33
  } from './handlers/rebuild';
34
34
 
35
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
36
+ typeof value === 'object' && value !== null;
37
+
38
+ const isStringRecord = (value: unknown): value is Record<string, string> =>
39
+ isRecord(value) &&
40
+ Object.values(value).every((entry) => typeof entry === 'string');
41
+
35
42
  /* Lightweight "server disconnected" banner. When the dev server is
36
43
  * genuinely down (process restarting or crashed) the browser would
37
44
  * otherwise show its own blank "site can't be reached" page — this keeps
@@ -198,16 +205,15 @@ const handleHMRMessage = (message: HMRMessage) => {
198
205
  // `__ng_hmr_load` blocks (see hmrInjectionPlugin.ts)
199
206
  // listen here and re-fetch the applyMetadata module.
200
207
  hideErrorOverlay();
201
- const data = message.data as
202
- | { id?: string; timestamp?: number }
203
- | undefined;
204
- if (data && typeof data.id === 'string') {
208
+ const { data } = message;
209
+ if (isRecord(data)) {
210
+ const id = Reflect.get(data, 'id');
211
+ const timestamp = Reflect.get(data, 'timestamp');
212
+ if (typeof id !== 'string') break;
205
213
  dispatchAngularComponentUpdate({
206
- id: data.id,
214
+ id,
207
215
  timestamp:
208
- typeof data.timestamp === 'number'
209
- ? data.timestamp
210
- : Date.now()
216
+ typeof timestamp === 'number' ? timestamp : Date.now()
211
217
  });
212
218
  }
213
219
  break;
@@ -221,16 +227,15 @@ const handleHMRMessage = (message: HMRMessage) => {
221
227
  // `__absAngularRemount` global wired in
222
228
  // `installAngularRemountGlobal`.
223
229
  hideErrorOverlay();
224
- const data = message.data as
225
- | { id?: string; timestamp?: number }
226
- | undefined;
227
- if (data && typeof data.id === 'string') {
230
+ const { data } = message;
231
+ if (isRecord(data)) {
232
+ const id = Reflect.get(data, 'id');
233
+ const timestamp = Reflect.get(data, 'timestamp');
234
+ if (typeof id !== 'string') break;
228
235
  dispatchAngularComponentRemount({
229
- id: data.id,
236
+ id,
230
237
  timestamp:
231
- typeof data.timestamp === 'number'
232
- ? data.timestamp
233
- : Date.now()
238
+ typeof timestamp === 'number' ? timestamp : Date.now()
234
239
  });
235
240
  }
236
241
  break;
@@ -245,17 +250,17 @@ const handleHMRMessage = (message: HMRMessage) => {
245
250
  // to dynamic-import the fresh bundle URL — re-importing
246
251
  // re-runs the destroy + bootstrapApplication block.
247
252
  hideErrorOverlay();
248
- const data = message.data as
249
- | { manifest?: Record<string, string>; reason?: string }
250
- | undefined;
251
- if (data?.manifest) {
252
- window.__HMR_MANIFEST__ = data.manifest;
253
+ const { data } = message;
254
+ if (isRecord(data) && isStringRecord(data.manifest)) {
255
+ const { manifest } = data;
256
+ window.__HMR_MANIFEST__ = manifest;
253
257
  }
254
- const w = window as Window & {
255
- __ABS_ANGULAR_REBOOTSTRAP__?: () => Promise<void>;
256
- };
257
- if (typeof w.__ABS_ANGULAR_REBOOTSTRAP__ === 'function') {
258
- w.__ABS_ANGULAR_REBOOTSTRAP__().catch((err) => {
258
+ const rebootstrap = Reflect.get(
259
+ window,
260
+ '__ABS_ANGULAR_REBOOTSTRAP__'
261
+ );
262
+ if (typeof rebootstrap === 'function') {
263
+ Promise.resolve(rebootstrap()).catch((err) => {
259
264
  console.error(
260
265
  '[absolutejs] angular:rebootstrap failed',
261
266
  err
@@ -16,10 +16,8 @@ const VISIBLE_DURATION_MS = 2500;
16
16
  const FADE_MS = 220;
17
17
 
18
18
  const ensureContainer = () => {
19
- const existing = document.getElementById(
20
- CONTAINER_ID
21
- ) as HTMLDivElement | null;
22
- if (existing) return existing;
19
+ const existing = document.getElementById(CONTAINER_ID);
20
+ if (existing instanceof HTMLDivElement) return existing;
23
21
 
24
22
  const container = document.createElement('div');
25
23
  container.id = CONTAINER_ID;
@@ -0,0 +1,36 @@
1
+ // @bun
2
+ // src/dev/serverBootstrap.ts
3
+ import { copyFileSync, existsSync, readdirSync, unlinkSync } from "fs";
4
+ import { dirname, extname, join, resolve } from "path";
5
+ var originalEntry = process.env.ABSOLUTE_SERVER_ENTRY;
6
+ if (!originalEntry) {
7
+ throw new Error("ABSOLUTE_SERVER_ENTRY is required by the AbsoluteJS dev bootstrap");
8
+ }
9
+ var entryPath = resolve(originalEntry);
10
+ if (!existsSync(entryPath)) {
11
+ throw new Error(`AbsoluteJS server entry does not exist: ${entryPath}`);
12
+ }
13
+ var entryDir = dirname(entryPath);
14
+ var entryExtension = extname(entryPath) || ".ts";
15
+ var copyPrefix = ".absolutejs-hmr-";
16
+ var removeEntryCopy = (path) => {
17
+ try {
18
+ unlinkSync(path);
19
+ } catch {}
20
+ };
21
+ for (const name of readdirSync(entryDir)) {
22
+ if (!name.startsWith(copyPrefix) || !name.endsWith(entryExtension)) {
23
+ continue;
24
+ }
25
+ removeEntryCopy(join(entryDir, name));
26
+ }
27
+ var bootstrapCopy = join(entryDir, `${copyPrefix}${process.pid}-bootstrap${entryExtension}`);
28
+ copyFileSync(entryPath, bootstrapCopy);
29
+ var entryCopies = new Set([bootstrapCopy]);
30
+ globalThis.__absoluteEntryCopies = entryCopies;
31
+ process.on("exit", () => {
32
+ for (const path of entryCopies) {
33
+ removeEntryCopy(path);
34
+ }
35
+ });
36
+ await import(bootstrapCopy);