hyperclayjs 1.3.0 → 1.4.0

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/LICENSE +21 -0
  2. package/README.md +77 -45
  3. package/communication/behaviorCollector.js +7 -4
  4. package/communication/sendMessage.js +7 -4
  5. package/communication/uploadFile.js +8 -5
  6. package/core/autosave.js +5 -47
  7. package/core/editmodeSystem.js +8 -5
  8. package/core/enablePersistentFormInputValues.js +7 -4
  9. package/core/exportToWindow.js +14 -0
  10. package/core/optionVisibilityRuleGenerator.js +8 -5
  11. package/core/savePage.js +47 -14
  12. package/core/savePageCore.js +10 -7
  13. package/custom-attributes/domHelpers.js +7 -4
  14. package/custom-attributes/sortable.js +23 -16
  15. package/dom-utilities/All.js +9 -6
  16. package/dom-utilities/getDataFromForm.js +8 -5
  17. package/dom-utilities/insertStyleTag.js +8 -5
  18. package/dom-utilities/onDomReady.js +7 -4
  19. package/dom-utilities/onLoad.js +7 -4
  20. package/hyperclay.js +92 -34
  21. package/module-dependency-graph.json +103 -135
  22. package/package.json +1 -1
  23. package/string-utilities/copy-to-clipboard.js +7 -4
  24. package/string-utilities/query.js +8 -5
  25. package/string-utilities/slugify.js +8 -5
  26. package/ui/prompts.js +49 -31
  27. package/ui/theModal.js +50 -6
  28. package/ui/toast-hyperclay.js +27 -11
  29. package/ui/toast.js +82 -92
  30. package/utilities/cookie.js +8 -5
  31. package/utilities/debounce.js +7 -4
  32. package/utilities/loadVendorScript.js +57 -0
  33. package/utilities/mutation.js +9 -6
  34. package/utilities/nearest.js +7 -4
  35. package/utilities/throttle.js +7 -4
  36. package/vendor/Sortable.vendor.js +2 -0
  37. package/vendor/idiomorph.min.js +8 -5
  38. package/vendor/tailwind-play.js +16 -162
  39. package/vendor/tailwind-play.vendor.js +169 -0
  40. package/string-utilities/emmet-html.js +0 -60
  41. package/ui/info.js +0 -47
  42. package/vendor/Sortable.js +0 -3351
@@ -403,9 +403,12 @@ const All = new Proxy(function (selectorOrElements, contextSelector) {
403
403
  // Install default plugins
404
404
  All.use(defaultPlugins);
405
405
 
406
- // Self-export to window and hyperclay
407
- window.All = All;
408
- window.hyperclay = window.hyperclay || {};
409
- window.hyperclay.All = All;
410
-
411
- export default All;
406
+ // Auto-export to window unless suppressed by loader
407
+ if (!window.__hyperclayNoAutoExport) {
408
+ window.All = All;
409
+ window.hyperclay = window.hyperclay || {};
410
+ window.hyperclay.All = All;
411
+ window.h = window.hyperclay;
412
+ }
413
+
414
+ export default All;
@@ -59,9 +59,12 @@ function getDataFromForm(container) {
59
59
  return formData;
60
60
  }
61
61
 
62
- // Self-export to window and hyperclay
63
- window.getDataFromForm = getDataFromForm;
64
- window.hyperclay = window.hyperclay || {};
65
- window.hyperclay.getDataFromForm = getDataFromForm;
62
+ // Auto-export to window unless suppressed by loader
63
+ if (!window.__hyperclayNoAutoExport) {
64
+ window.getDataFromForm = getDataFromForm;
65
+ window.hyperclay = window.hyperclay || {};
66
+ window.hyperclay.getDataFromForm = getDataFromForm;
67
+ window.h = window.hyperclay;
68
+ }
66
69
 
67
- export default getDataFromForm;
70
+ export default getDataFromForm;
@@ -27,9 +27,12 @@ function insertStyleTag(href) {
27
27
  document.head.appendChild(link);
28
28
  }
29
29
 
30
- // Self-export to window and hyperclay
31
- window.insertStyleTag = insertStyleTag;
32
- window.hyperclay = window.hyperclay || {};
33
- window.hyperclay.insertStyleTag = insertStyleTag;
30
+ // Auto-export to window unless suppressed by loader
31
+ if (!window.__hyperclayNoAutoExport) {
32
+ window.insertStyleTag = insertStyleTag;
33
+ window.hyperclay = window.hyperclay || {};
34
+ window.hyperclay.insertStyleTag = insertStyleTag;
35
+ window.h = window.hyperclay;
36
+ }
34
37
 
35
- export default insertStyleTag;
38
+ export default insertStyleTag;
@@ -6,8 +6,11 @@ function onDomReady (callback) {
6
6
  }
7
7
  }
8
8
 
9
- // Self-export to hyperclay only
10
- window.hyperclay = window.hyperclay || {};
11
- window.hyperclay.onDomReady = onDomReady;
9
+ // Auto-export to window unless suppressed by loader
10
+ if (!window.__hyperclayNoAutoExport) {
11
+ window.hyperclay = window.hyperclay || {};
12
+ window.hyperclay.onDomReady = onDomReady;
13
+ window.h = window.hyperclay;
14
+ }
12
15
 
13
- export default onDomReady;
16
+ export default onDomReady;
@@ -6,8 +6,11 @@ function onLoad (callback) {
6
6
  }
7
7
  }
8
8
 
9
- // Self-export to hyperclay only
10
- window.hyperclay = window.hyperclay || {};
11
- window.hyperclay.onLoad = onLoad;
9
+ // Auto-export to window unless suppressed by loader
10
+ if (!window.__hyperclayNoAutoExport) {
11
+ window.hyperclay = window.hyperclay || {};
12
+ window.hyperclay.onLoad = onLoad;
13
+ window.h = window.hyperclay;
14
+ }
12
15
 
13
- export default onLoad;
16
+ export default onLoad;
package/hyperclay.js CHANGED
@@ -1,28 +1,34 @@
1
1
  /**
2
- * HyperclayJS v1.3.0 - Minimal Browser-Native Loader
2
+ * HyperclayJS v1.4.0 - Minimal Browser-Native Loader
3
3
  *
4
- * Modules self-export to window.hyperclay when imported.
5
4
  * Modules auto-init when imported (no separate init call needed).
6
- * Uses top-level await so subsequent module scripts automatically wait.
5
+ * Include `export-to-window` feature to export to window.hyperclay.
7
6
  *
8
- * <!-- Load with a preset -->
9
- * <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=minimal" type="module"></script>
10
- * <!-- Load specific features -->
11
- * <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?features=save,admin,toast" type="module"></script>
12
- * <!-- Load preset with exclusions -->
13
- * <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=everything&exclude=tailwind-play,behavior-collector" type="module"></script>
7
+ * Usage (use await import to ensure modules finish loading):
8
+ *
9
+ * <script type="module">
10
+ * // With window.hyperclay (default presets include export-to-window):
11
+ * await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=minimal');
12
+ * const { toast, savePage } = window.hyperclay;
13
+ *
14
+ * // ES modules only (exclude export-to-window):
15
+ * const hyperclay = await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=minimal&exclude=export-to-window');
16
+ * const modules = window.hyperclayModules;
17
+ * </script>
14
18
  *
15
19
  * AUTO-GENERATED FILE - Do not edit directly
16
20
  */
17
21
 
18
- window.hyperclay = window.hyperclay || {};
19
22
  window.hyperclayModules = window.hyperclayModules || {};
20
23
 
24
+ // Suppress auto-export in modules - export-to-window will flip this to false
25
+ window.__hyperclayNoAutoExport = true;
26
+
21
27
  const MODULE_PATHS = {
22
28
  "save-core": "./core/savePageCore.js",
23
29
  "save-system": "./core/savePage.js",
24
30
  "autosave": "./core/autosave.js",
25
- "admin": "./core/adminSystem.js",
31
+ "edit-mode-helpers": "./core/adminSystem.js",
26
32
  "persist": "./core/enablePersistentFormInputValues.js",
27
33
  "option-visibility": "./core/optionVisibilityRuleGenerator.js",
28
34
  "edit-mode": "./core/editmodeSystem.js",
@@ -34,7 +40,7 @@ const MODULE_PATHS = {
34
40
  "dialogs": "./ui/prompts.js",
35
41
  "toast": "./ui/toast.js",
36
42
  "toast-hyperclay": "./ui/toast-hyperclay.js",
37
- "modal": "./ui/theModal.js",
43
+ "the-modal": "./ui/theModal.js",
38
44
  "tailwind-play": "./vendor/tailwind-play.js",
39
45
  "mutation": "./utilities/mutation.js",
40
46
  "nearest": "./utilities/nearest.js",
@@ -48,12 +54,12 @@ const MODULE_PATHS = {
48
54
  "form-data": "./dom-utilities/getDataFromForm.js",
49
55
  "idiomorph": "./vendor/idiomorph.min.js",
50
56
  "slugify": "./string-utilities/slugify.js",
51
- "emmet": "./string-utilities/emmet-html.js",
52
- "clipboard": "./string-utilities/copy-to-clipboard.js",
57
+ "copy-to-clipboard": "./string-utilities/copy-to-clipboard.js",
53
58
  "query-params": "./string-utilities/query.js",
54
59
  "behavior-collector": "./communication/behaviorCollector.js",
55
60
  "send-message": "./communication/sendMessage.js",
56
- "file-upload": "./communication/uploadFile.js"
61
+ "file-upload": "./communication/uploadFile.js",
62
+ "export-to-window": "./core/exportToWindow.js"
57
63
  };
58
64
  const PRESETS = {
59
65
  "minimal": {
@@ -62,8 +68,9 @@ const PRESETS = {
62
68
  "modules": [
63
69
  "save-core",
64
70
  "save-system",
65
- "admin",
66
- "toast"
71
+ "edit-mode-helpers",
72
+ "toast",
73
+ "export-to-window"
67
74
  ]
68
75
  },
69
76
  "standard": {
@@ -72,12 +79,13 @@ const PRESETS = {
72
79
  "modules": [
73
80
  "save-core",
74
81
  "save-system",
75
- "admin",
82
+ "edit-mode-helpers",
76
83
  "persist",
77
84
  "option-visibility",
78
85
  "event-attrs",
79
86
  "dom-helpers",
80
- "toast"
87
+ "toast",
88
+ "export-to-window"
81
89
  ]
82
90
  },
83
91
  "everything": {
@@ -87,7 +95,7 @@ const PRESETS = {
87
95
  "save-core",
88
96
  "save-system",
89
97
  "autosave",
90
- "admin",
98
+ "edit-mode-helpers",
91
99
  "persist",
92
100
  "option-visibility",
93
101
  "edit-mode",
@@ -99,7 +107,7 @@ const PRESETS = {
99
107
  "dialogs",
100
108
  "toast",
101
109
  "toast-hyperclay",
102
- "modal",
110
+ "the-modal",
103
111
  "tailwind-play",
104
112
  "mutation",
105
113
  "nearest",
@@ -113,19 +121,18 @@ const PRESETS = {
113
121
  "form-data",
114
122
  "idiomorph",
115
123
  "slugify",
116
- "emmet",
117
- "clipboard",
124
+ "copy-to-clipboard",
118
125
  "query-params",
119
126
  "behavior-collector",
120
127
  "send-message",
121
- "file-upload"
128
+ "file-upload",
129
+ "export-to-window"
122
130
  ]
123
131
  }
124
132
  };
125
133
 
126
- // Parse URL
127
- const script = document.currentScript;
128
- const url = new URL(script.src);
134
+ // Parse URL (use import.meta.url for ES modules since document.currentScript is null)
135
+ const url = new URL(import.meta.url);
129
136
  const preset = url.searchParams.get('preset');
130
137
  const features = url.searchParams.get('features');
131
138
  const exclude = url.searchParams.get('exclude');
@@ -151,6 +158,9 @@ if (exclude) {
151
158
  // Modules that extend prototypes must load before modules that execute user code
152
159
  const LOAD_FIRST = new Set(['dom-helpers', 'all-js']);
153
160
 
161
+ // export-to-window flips the flag, so it must load before other modules
162
+ const LOAD_BEFORE_ALL = 'export-to-window';
163
+
154
164
  const loadModules = (modules) => Promise.all(modules.map(async feature => {
155
165
  const path = MODULE_PATHS[feature];
156
166
  if (!path) throw new Error(`Unknown feature: ${feature}`);
@@ -161,14 +171,62 @@ const loadModules = (modules) => Promise.all(modules.map(async feature => {
161
171
 
162
172
  if (debug) console.log('HyperclayJS: Loading features:', requested);
163
173
 
164
- // Load in waves: prototype extenders first, then everything else
165
- const first = requested.filter(f => LOAD_FIRST.has(f));
166
- const rest = requested.filter(f => !LOAD_FIRST.has(f));
174
+ // Separate export-to-window - it must load FIRST to flip the flag
175
+ const shouldExportToWindow = requested.includes(LOAD_BEFORE_ALL);
176
+ const modulesToLoad = requested.filter(f => f !== LOAD_BEFORE_ALL);
167
177
 
168
- if (first.length) await loadModules(first);
169
- if (rest.length) await loadModules(rest);
178
+ // Load in waves: export-to-window first, then prototype extenders, then everything else
179
+ const first = modulesToLoad.filter(f => LOAD_FIRST.has(f));
180
+ const rest = modulesToLoad.filter(f => !LOAD_FIRST.has(f));
170
181
 
171
- // Create h alias
172
- window.h = window.hyperclay;
182
+ try {
183
+ // Load export-to-window FIRST to flip the flag before other modules load
184
+ if (shouldExportToWindow) {
185
+ if (debug) console.log('HyperclayJS: Enabling window exports...');
186
+ const exportModule = await import(`${baseUrl}/${MODULE_PATHS[LOAD_BEFORE_ALL]}`);
187
+ window.hyperclayModules[LOAD_BEFORE_ALL] = exportModule;
188
+ }
189
+
190
+ if (first.length) await loadModules(first);
191
+ if (rest.length) await loadModules(rest);
192
+ } catch (err) {
193
+ console.error('HyperclayJS: Failed to load modules:', err);
194
+ throw err;
195
+ }
173
196
 
174
197
  if (debug) console.log('HyperclayJS: Ready');
198
+
199
+ // ES module exports - allows destructuring from import()
200
+ export const savePage = window.hyperclayModules['save-core']?.savePage ?? window.hyperclayModules['save-core']?.default;
201
+ export const beforeSave = window.hyperclayModules['save-system']?.beforeSave ?? window.hyperclayModules['save-system']?.default;
202
+ export const savePageThrottled = window.hyperclayModules['save-system']?.savePageThrottled ?? window.hyperclayModules['save-system']?.default;
203
+ export const replacePageWith = window.hyperclayModules['save-system']?.replacePageWith ?? window.hyperclayModules['save-system']?.default;
204
+ export const toggleEditMode = window.hyperclayModules['edit-mode']?.toggleEditMode ?? window.hyperclayModules['edit-mode']?.default;
205
+ export const isEditMode = window.hyperclayModules['edit-mode']?.isEditMode ?? window.hyperclayModules['edit-mode']?.default;
206
+ export const isOwner = window.hyperclayModules['edit-mode']?.isOwner ?? window.hyperclayModules['edit-mode']?.default;
207
+ export const ask = window.hyperclayModules['dialogs']?.ask ?? window.hyperclayModules['dialogs']?.default;
208
+ export const consent = window.hyperclayModules['dialogs']?.consent ?? window.hyperclayModules['dialogs']?.default;
209
+ export const tell = window.hyperclayModules['dialogs']?.tell ?? window.hyperclayModules['dialogs']?.default;
210
+ export const snippet = window.hyperclayModules['dialogs']?.snippet ?? window.hyperclayModules['dialogs']?.default;
211
+ export const toast = window.hyperclayModules['toast']?.toast ?? window.hyperclayModules['toast']?.default;
212
+ export const toastHyperclay = window.hyperclayModules['toast-hyperclay']?.toastHyperclay ?? window.hyperclayModules['toast-hyperclay']?.default;
213
+ export const themodal = window.hyperclayModules['the-modal']?.themodal ?? window.hyperclayModules['the-modal']?.default;
214
+ export const Mutation = window.hyperclayModules['mutation']?.Mutation ?? window.hyperclayModules['mutation']?.default;
215
+ export const nearest = window.hyperclayModules['nearest']?.nearest ?? window.hyperclayModules['nearest']?.default;
216
+ export const cookie = window.hyperclayModules['cookie']?.cookie ?? window.hyperclayModules['cookie']?.default;
217
+ export const throttle = window.hyperclayModules['throttle']?.throttle ?? window.hyperclayModules['throttle']?.default;
218
+ export const debounce = window.hyperclayModules['debounce']?.debounce ?? window.hyperclayModules['debounce']?.default;
219
+ export const onDomReady = window.hyperclayModules['dom-ready']?.onDomReady ?? window.hyperclayModules['dom-ready']?.default;
220
+ export const onLoad = window.hyperclayModules['window-load']?.onLoad ?? window.hyperclayModules['window-load']?.default;
221
+ export const All = window.hyperclayModules['all-js']?.All ?? window.hyperclayModules['all-js']?.default;
222
+ export const insertStyleTag = window.hyperclayModules['style-injection']?.insertStyleTag ?? window.hyperclayModules['style-injection']?.default;
223
+ export const getDataFromForm = window.hyperclayModules['form-data']?.getDataFromForm ?? window.hyperclayModules['form-data']?.default;
224
+ export const Idiomorph = window.hyperclayModules['idiomorph']?.Idiomorph ?? window.hyperclayModules['idiomorph']?.default;
225
+ export const slugify = window.hyperclayModules['slugify']?.slugify ?? window.hyperclayModules['slugify']?.default;
226
+ export const copyToClipboard = window.hyperclayModules['copy-to-clipboard']?.copyToClipboard ?? window.hyperclayModules['copy-to-clipboard']?.default;
227
+ export const query = window.hyperclayModules['query-params']?.query ?? window.hyperclayModules['query-params']?.default;
228
+ export const behaviorCollector = window.hyperclayModules['behavior-collector']?.behaviorCollector ?? window.hyperclayModules['behavior-collector']?.default;
229
+ export const sendMessage = window.hyperclayModules['send-message']?.sendMessage ?? window.hyperclayModules['send-message']?.default;
230
+ export const uploadFile = window.hyperclayModules['file-upload']?.uploadFile ?? window.hyperclayModules['file-upload']?.default;
231
+ export const createFile = window.hyperclayModules['file-upload']?.createFile ?? window.hyperclayModules['file-upload']?.default;
232
+ export const uploadFileBasic = window.hyperclayModules['file-upload']?.uploadFileBasic ?? window.hyperclayModules['file-upload']?.default;