hyperclayjs 1.24.0 → 1.24.1

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.
package/README.md CHANGED
@@ -79,7 +79,7 @@ import 'hyperclayjs/presets/standard.js';
79
79
  | input-helpers | 3.9KB | [prevent-enter], [autosize] for textareas |
80
80
  | movable | 2.5KB | Free-positioning drag with [movable] and [movable-handle], edit mode only |
81
81
  | onaftersave | 1KB | [onaftersave] attribute - run JS when save status changes |
82
- | save-freeze | 1.9KB | [save-freeze] attribute - freeze element innerHTML for saves, live DOM changes freely |
82
+ | save-freeze | 2.8KB | [save-freeze] attribute - freeze element innerHTML for saves, live DOM changes freely |
83
83
  | sortable | 3.4KB | Drag-drop sorting with [sortable], lazy-loads ~118KB Sortable.js in edit mode |
84
84
 
85
85
  ### UI Components (User interface elements)
@@ -144,7 +144,7 @@ Standard feature set for most use cases
144
144
 
145
145
  **Modules:** `save-core`, `snapshot`, `save-system`, `unsaved-warning`, `edit-mode-helpers`, `persist`, `option-visibility`, `event-attrs`, `dom-helpers`, `toast`, `save-toast`, `export-to-window`, `view-mode-excludes-edit-modules`
146
146
 
147
- ### Everything (~219.6KB)
147
+ ### Everything (~220.5KB)
148
148
  All available features
149
149
 
150
150
  Includes all available modules across all categories.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperclayjs",
3
- "version": "1.24.0",
3
+ "version": "1.24.1",
4
4
  "description": "Modular JavaScript library for building interactive malleable HTML files with Hyperclay",
5
5
  "type": "module",
6
6
  "main": "src/hyperclay.js",
@@ -16,24 +16,54 @@
16
16
  * Changes inside [save-freeze] elements do not trigger autosave dirty checks.
17
17
  */
18
18
 
19
- import { onPrepareForSave } from "../core/snapshot.js";
19
+ import { onSnapshot, onPrepareForSave } from "../core/snapshot.js";
20
20
  import { isEditMode } from "../core/isAdminOfCurrentResource.js";
21
21
 
22
22
  const originals = new WeakMap();
23
23
 
24
+ const saveFreeze = { debug: false };
25
+
26
+ function log(...args) {
27
+ if (saveFreeze.debug) console.log('[save-freeze]', ...args);
28
+ }
29
+
24
30
  function capture(el) {
25
31
  if (!originals.has(el)) {
26
32
  originals.set(el, el.innerHTML);
33
+ log('captured original', el.innerHTML.substring(0, 80) + '...');
27
34
  }
28
35
  }
29
36
 
30
37
  function captureAll() {
31
- for (const el of document.querySelectorAll('[save-freeze]')) {
38
+ const els = document.querySelectorAll('[save-freeze]');
39
+ log('captureAll found', els.length, 'elements');
40
+ for (const el of els) {
32
41
  capture(el);
33
42
  }
34
43
  }
35
44
 
45
+ function freezeClone(clone) {
46
+ const liveElements = document.querySelectorAll('[save-freeze]');
47
+ const cloneElements = clone.querySelectorAll('[save-freeze]');
48
+
49
+ log('freezing clone — live:', liveElements.length, 'clone:', cloneElements.length);
50
+
51
+ for (let i = 0; i < cloneElements.length; i++) {
52
+ const liveEl = liveElements[i];
53
+ const hasOriginal = liveEl && originals.has(liveEl);
54
+ if (hasOriginal) {
55
+ const original = originals.get(liveEl);
56
+ const current = cloneElements[i].innerHTML;
57
+ if (original !== current) {
58
+ log('element', i, '— restoring original');
59
+ cloneElements[i].innerHTML = original;
60
+ }
61
+ }
62
+ }
63
+ }
64
+
36
65
  function init() {
66
+ log('init, isEditMode:', isEditMode);
37
67
  if (!isEditMode) return;
38
68
 
39
69
  captureAll();
@@ -51,19 +81,15 @@ function init() {
51
81
  });
52
82
  observer.observe(document.documentElement, { childList: true, subtree: true });
53
83
 
54
- onPrepareForSave(clone => {
55
- const liveElements = document.querySelectorAll('[save-freeze]');
56
- const cloneElements = clone.querySelectorAll('[save-freeze]');
84
+ // Phase 2: Freeze in snapshot — before snapshot-ready fires.
85
+ // This prevents live-sync from writing unfrozen content to disk.
86
+ onSnapshot(freezeClone);
57
87
 
58
- for (let i = 0; i < cloneElements.length; i++) {
59
- const liveEl = liveElements[i];
60
- if (liveEl && originals.has(liveEl)) {
61
- cloneElements[i].innerHTML = originals.get(liveEl);
62
- }
63
- }
64
- });
88
+ // Phase 3a: Freeze again in prepare — belt-and-suspenders.
89
+ // Catches any modifications made between phase 2 and 3a (e.g., onbeforesave handlers).
90
+ onPrepareForSave(freezeClone);
65
91
  }
66
92
 
67
93
  init();
68
94
 
69
- export default init;
95
+ export default saveFreeze;
package/src/hyperclay.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * DO NOT EDIT THIS FILE DIRECTLY — it is generated from build/hyperclay.template.js
3
3
  *
4
- * HyperclayJS v1.24.0 - Minimal Browser-Native Loader
4
+ * HyperclayJS v1.24.1 - Minimal Browser-Native Loader
5
5
  *
6
6
  * Modules auto-init when imported (no separate init call needed).
7
7
  * Include `export-to-window` feature to export to window.hyperclay.