@absolutejs/absolute 0.19.0-beta.1065 → 0.19.0-beta.1067

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.
@@ -179,14 +179,19 @@ const updateHTMLBody = (
179
179
  const domSnapshot = snapshotDOMChanges(container);
180
180
 
181
181
  const existingScripts = collectScripts(container);
182
+ const oldInlineScripts = collectInlineScripts(container);
182
183
  const hmrScript = container.querySelector('script[data-hmr-client]');
183
184
  const tempDiv = document.createElement('div');
184
185
  tempDiv.innerHTML = htmlBody;
185
186
  const newScripts = collectScriptsFromElement(tempDiv);
187
+ const newInlineScripts = collectInlineScripts(tempDiv);
186
188
 
187
189
  const htmlStructureChanged = didHTMLStructureChange(container, tempDiv);
190
+ const scriptsChanged =
191
+ didScriptsChange(existingScripts, newScripts) ||
192
+ didInlineScriptsChange(oldInlineScripts, newInlineScripts);
188
193
 
189
- if (htmlStructureChanged || didScriptsChange(existingScripts, newScripts)) {
194
+ if (htmlStructureChanged || scriptsChanged) {
190
195
  patchDOMInPlace(container, htmlBody);
191
196
  restoreDOMChanges(container, domSnapshot, htmlBody);
192
197
  }
@@ -198,12 +203,12 @@ const updateHTMLBody = (
198
203
  restoreFormState(savedState.forms);
199
204
  restoreScrollState(savedState.scroll);
200
205
 
201
- if (
202
- didScriptsChange(existingScripts, newScripts) ||
203
- htmlStructureChanged
204
- ) {
206
+ // Only touch scripts/interactive elements when a script actually
207
+ // changed. A pure markup edit (e.g. a heading) leaves inline-script
208
+ // state and `addEventListener` handlers intact.
209
+ if (scriptsChanged) {
205
210
  cloneInteractiveElements(container);
206
- reExecuteScripts(container, newScripts);
211
+ reExecuteScripts(container, newScripts, oldInlineScripts);
207
212
  }
208
213
  });
209
214
  sessionStorage.removeItem('__HMR_ACTIVE__');
@@ -245,6 +250,7 @@ const updateHTMLBodyDirect = (
245
250
  const savedState = saveHTMLState();
246
251
  const domSnapshot = snapshotDOMChanges(container);
247
252
 
253
+ const oldInlineScripts = collectInlineScripts(container);
248
254
  const tempDiv = document.createElement('div');
249
255
  tempDiv.innerHTML = htmlBody;
250
256
  const newScripts = collectScriptsFromElement(tempDiv);
@@ -271,8 +277,7 @@ const updateHTMLBodyDirect = (
271
277
  container.appendChild(newScript);
272
278
  });
273
279
 
274
- const inlineScripts = container.querySelectorAll('script:not([src])');
275
- inlineScripts.forEach(replaceInlineScript);
280
+ reExecuteInlineScripts(container, oldInlineScripts);
276
281
  });
277
282
  sessionStorage.removeItem('__HMR_ACTIVE__');
278
283
  };
@@ -291,6 +296,21 @@ const collectScriptsFromElement = (elem: HTMLElement) =>
291
296
  type: script.getAttribute('type') || 'text/javascript'
292
297
  }));
293
298
 
299
+ /* Inline (non-src) scripts, excluding the HMR client. Captured by ordinal so
300
+ * an unchanged inline script can be skipped on re-execution — re-running it
301
+ * would reset its module/global state (e.g. `let count = 0`) on every edit. */
302
+ const collectInlineScripts = (elem: HTMLElement) =>
303
+ Array.from(
304
+ elem.querySelectorAll('script:not([src]):not([data-hmr-client])')
305
+ ).map((script) => script.textContent || '');
306
+
307
+ const didInlineScriptsChange = (
308
+ oldInline: string[],
309
+ newInline: string[]
310
+ ) =>
311
+ oldInline.length !== newInline.length ||
312
+ oldInline.some((content, idx) => content !== newInline[idx]);
313
+
294
314
  const didScriptsChange = (oldScripts: ScriptInfo[], newScripts: ScriptInfo[]) =>
295
315
  oldScripts.length !== newScripts.length ||
296
316
  oldScripts.some((oldScript, idx) => {
@@ -348,7 +368,11 @@ const removeOldScripts = (container: HTMLElement) => {
348
368
  });
349
369
  };
350
370
 
351
- const reExecuteScripts = (container: HTMLElement, newScripts: ScriptInfo[]) => {
371
+ const reExecuteScripts = (
372
+ container: HTMLElement,
373
+ newScripts: ScriptInfo[],
374
+ oldInlineScripts: string[]
375
+ ) => {
352
376
  removeOldScripts(container);
353
377
 
354
378
  newScripts.forEach((scriptInfo) => {
@@ -359,6 +383,24 @@ const reExecuteScripts = (container: HTMLElement, newScripts: ScriptInfo[]) => {
359
383
  container.appendChild(newScript);
360
384
  });
361
385
 
362
- const inlineScripts = container.querySelectorAll('script:not([src])');
363
- inlineScripts.forEach(replaceInlineScript);
386
+ reExecuteInlineScripts(container, oldInlineScripts);
387
+ };
388
+
389
+ /* Re-execute inline scripts by replacing them with fresh nodes, but skip any
390
+ * whose textContent is byte-identical to its previous counterpart (matched by
391
+ * ordinal). Skipping leaves the original execution's global bindings intact,
392
+ * so unrelated edits don't reset inline-script state. */
393
+ const reExecuteInlineScripts = (
394
+ container: HTMLElement,
395
+ oldInlineScripts: string[]
396
+ ) => {
397
+ const inlineScripts = container.querySelectorAll(
398
+ 'script:not([src]):not([data-hmr-client])'
399
+ );
400
+ inlineScripts.forEach((script, idx) => {
401
+ if (oldInlineScripts[idx] === (script.textContent || '')) {
402
+ return;
403
+ }
404
+ replaceInlineScript(script);
405
+ });
364
406
  };
@@ -282,6 +282,26 @@ export const handleSvelteUpdate = (message: {
282
282
  acceptFn(newModule);
283
283
  }
284
284
 
285
+ /* $.hmr_accept swaps component code in place but re-runs
286
+ * the <script> body with the original mount props, so any
287
+ * state seeded from a prop (e.g. a composable doing
288
+ * $state(initialCount)) resets. Remount with the preserved
289
+ * state merged into props — mirroring the bundled-fallback
290
+ * bootstrap — so that state carries across (issue #41). */
291
+ const preserved = window.__HMR_PRESERVED_STATE__;
292
+ const remount = window.__SVELTE_REMOUNT__;
293
+ if (
294
+ typeof remount === 'function' &&
295
+ preserved &&
296
+ Object.keys(preserved).length > 0
297
+ ) {
298
+ remount({
299
+ ...(window.__INITIAL_PROPS__ ?? {}),
300
+ ...preserved
301
+ });
302
+ }
303
+ window.__HMR_PRESERVED_STATE__ = undefined;
304
+
285
305
  if (
286
306
  window.__HMR_WS__ &&
287
307
  message.data.serverDuration !== undefined
package/dist/index.js CHANGED
@@ -23061,6 +23061,14 @@ if (isHMR) {
23061
23061
  if (typeof window !== "undefined") {
23062
23062
  window.__SVELTE_COMPONENT__ = component;
23063
23063
  window.__SVELTE_UNMOUNT__ = function() { if (component) { unmount(component); } };
23064
+ window.__SVELTE_REMOUNT__ = function(props) {
23065
+ if (typeof window.__SVELTE_UNMOUNT__ === "function") {
23066
+ try { window.__SVELTE_UNMOUNT__(); } catch (err) { /* ignore */ }
23067
+ }
23068
+ component = mount(Component, { target, props });
23069
+ window.__SVELTE_COMPONENT__ = component;
23070
+ window.__SVELTE_UNMOUNT__ = function() { if (component) { unmount(component); } };
23071
+ };
23064
23072
  window.__ABS_SLOT_HYDRATION_PENDING__ = shouldHydrate;
23065
23073
  var releaseStreamingSlots = function() {
23066
23074
  window.__ABS_SLOT_HYDRATION_PENDING__ = false;
@@ -35465,6 +35473,11 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
35465
35473
  for (const file5 of svelteFiles) {
35466
35474
  state.fileHashes.set(resolve41(file5), computeFileHash(file5));
35467
35475
  }
35476
+ const surgicallyHandled = state.svelteSurgicallyHandled ?? new Set;
35477
+ for (const file5 of svelteFiles) {
35478
+ surgicallyHandled.add(resolve41(file5));
35479
+ }
35480
+ state.svelteSurgicallyHandled = surgicallyHandled;
35468
35481
  const serverDuration = Date.now() - startTime;
35469
35482
  await runSequentially(svelteFiles, (changedFile) => broadcastSvelteModuleUpdate(state, changedFile, svelteFiles, serverDuration));
35470
35483
  scheduleSvelteBundleRebuild(state, svelteFiles, config2)();
@@ -36234,7 +36247,8 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
36234
36247
  if (isCssOnlyChange && svelteCssFiles.length > 0) {
36235
36248
  handleSvelteCssOnlyUpdate(state, svelteCssFiles, manifest, duration3);
36236
36249
  }
36237
- pagesToUpdate.forEach((sveltePagePath) => {
36250
+ const surgicallyHandled = state.svelteSurgicallyHandled;
36251
+ pagesToUpdate.filter((sveltePagePath) => !surgicallyHandled?.has(resolve41(sveltePagePath))).forEach((sveltePagePath) => {
36238
36252
  broadcastSveltePageUpdate(state, sveltePagePath, manifest, duration3);
36239
36253
  });
36240
36254
  }, handleAngularCssOnlyUpdate = (state, angularCssFiles, manifest, duration3) => {
@@ -36520,6 +36534,7 @@ var moduleServerPromise, getModuleServer = () => moduleServerPromise, runSequent
36520
36534
  });
36521
36535
  return files.every((f2) => handled.has(f2));
36522
36536
  }, performFullRebuild = async (state, config2, affectedFrameworks, filesToRebuild, startTime, onRebuildComplete) => {
36537
+ state.svelteSurgicallyHandled = undefined;
36523
36538
  const hasManifest = Object.keys(state.manifest).length > 0;
36524
36539
  const files = filesToRebuild ?? [];
36525
36540
  let allHandled = files.length > 0 && hasManifest;
@@ -46592,5 +46607,5 @@ export {
46592
46607
  ANGULAR_INIT_TIMEOUT_MS
46593
46608
  };
46594
46609
 
46595
- //# debugId=21D861916A6FEEBD64756E2164756E21
46610
+ //# debugId=CBC02BD79E05A41764756E2164756E21
46596
46611
  //# sourceMappingURL=index.js.map