juxscript 1.0.88 → 1.0.89

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 (70) hide show
  1. package/lib/componentsv2/base/BaseEngine.d.ts +10 -0
  2. package/lib/componentsv2/base/BaseEngine.d.ts.map +1 -1
  3. package/lib/componentsv2/base/BaseEngine.js +28 -7
  4. package/lib/componentsv2/base/BaseEngine.js.map +1 -1
  5. package/lib/componentsv2/base/BaseEngine.ts +29 -0
  6. package/lib/componentsv2/base/OptionsContract.d.ts +20 -0
  7. package/lib/componentsv2/base/OptionsContract.d.ts.map +1 -0
  8. package/lib/componentsv2/base/OptionsContract.js +107 -0
  9. package/lib/componentsv2/base/OptionsContract.js.map +1 -0
  10. package/lib/componentsv2/base/OptionsContract.ts +139 -0
  11. package/lib/componentsv2/element/component.d.ts +22 -0
  12. package/lib/componentsv2/element/component.d.ts.map +1 -1
  13. package/lib/componentsv2/element/component.js +22 -0
  14. package/lib/componentsv2/element/component.js.map +1 -1
  15. package/lib/componentsv2/element/component.ts +23 -1
  16. package/lib/componentsv2/element/engine.d.ts +31 -14
  17. package/lib/componentsv2/element/engine.d.ts.map +1 -1
  18. package/lib/componentsv2/element/engine.js +74 -23
  19. package/lib/componentsv2/element/engine.js.map +1 -1
  20. package/lib/componentsv2/element/engine.ts +86 -29
  21. package/lib/componentsv2/element/skin.d.ts.map +1 -1
  22. package/lib/componentsv2/element/skin.js +7 -10
  23. package/lib/componentsv2/element/skin.js.map +1 -1
  24. package/lib/componentsv2/element/skin.ts +7 -11
  25. package/lib/componentsv2/grid/engine.d.ts +48 -3
  26. package/lib/componentsv2/grid/engine.d.ts.map +1 -1
  27. package/lib/componentsv2/grid/engine.js +109 -14
  28. package/lib/componentsv2/grid/engine.js.map +1 -1
  29. package/lib/componentsv2/grid/engine.ts +120 -16
  30. package/lib/componentsv2/index.d.ts +1 -3
  31. package/lib/componentsv2/index.d.ts.map +1 -1
  32. package/lib/componentsv2/index.js +1 -3
  33. package/lib/componentsv2/index.js.map +1 -1
  34. package/lib/componentsv2/index.ts +1 -4
  35. package/lib/componentsv2/input/engine.d.ts +48 -5
  36. package/lib/componentsv2/input/engine.d.ts.map +1 -1
  37. package/lib/componentsv2/input/engine.js +108 -15
  38. package/lib/componentsv2/input/engine.js.map +1 -1
  39. package/lib/componentsv2/input/engine.ts +119 -16
  40. package/lib/componentsv2/input/skin.d.ts.map +1 -1
  41. package/lib/componentsv2/input/skin.js +1 -4
  42. package/lib/componentsv2/input/skin.js.map +1 -1
  43. package/lib/componentsv2/input/skin.ts +1 -4
  44. package/lib/componentsv2/list/component.d.ts +28 -6
  45. package/lib/componentsv2/list/component.d.ts.map +1 -1
  46. package/lib/componentsv2/list/component.js +28 -6
  47. package/lib/componentsv2/list/component.js.map +1 -1
  48. package/lib/componentsv2/list/component.ts +28 -6
  49. package/lib/componentsv2/list/engine.d.ts +61 -9
  50. package/lib/componentsv2/list/engine.d.ts.map +1 -1
  51. package/lib/componentsv2/list/engine.js +156 -95
  52. package/lib/componentsv2/list/engine.js.map +1 -1
  53. package/lib/componentsv2/list/engine.ts +175 -108
  54. package/package.json +1 -1
  55. package/lib/componentsv2/juxerror/component.d.ts +0 -28
  56. package/lib/componentsv2/juxerror/component.d.ts.map +0 -1
  57. package/lib/componentsv2/juxerror/component.js +0 -101
  58. package/lib/componentsv2/juxerror/component.js.map +0 -1
  59. package/lib/componentsv2/juxerror/component.ts +0 -125
  60. package/lib/componentsv2/juxerror/engine.d.ts +0 -35
  61. package/lib/componentsv2/juxerror/engine.d.ts.map +0 -1
  62. package/lib/componentsv2/juxerror/engine.js +0 -190
  63. package/lib/componentsv2/juxerror/engine.js.map +0 -1
  64. package/lib/componentsv2/juxerror/engine.ts +0 -241
  65. package/lib/componentsv2/juxerror/skin.d.ts +0 -11
  66. package/lib/componentsv2/juxerror/skin.d.ts.map +0 -1
  67. package/lib/componentsv2/juxerror/skin.js +0 -180
  68. package/lib/componentsv2/juxerror/skin.js.map +0 -1
  69. package/lib/componentsv2/juxerror/skin.ts +0 -200
  70. package/lib/componentsv2/juxerror/structure.css +0 -351
@@ -1,200 +0,0 @@
1
- import { BaseSkin } from '../base/BaseSkin.js';
2
- import { JuxErrorEngine, JuxErrorState, StackFrame } from './engine.js';
3
- import structureCss from './structure.css';
4
-
5
- export class JuxErrorSkin extends BaseSkin<JuxErrorState, JuxErrorEngine> {
6
- #overlay: HTMLElement | null = null;
7
- #keydownHandler: ((e: KeyboardEvent) => void) | null = null;
8
-
9
- constructor(engine: JuxErrorEngine) {
10
- super(engine);
11
- }
12
-
13
- protected get structureCss(): string {
14
- return structureCss;
15
- }
16
-
17
- protected createRoot(): HTMLElement {
18
- const root = document.createElement('div');
19
- root.className = 'jux-error-root';
20
-
21
- this.#overlay = document.createElement('div');
22
- this.#overlay.className = 'jux-error-overlay';
23
- this.#overlay.setAttribute('aria-live', 'assertive');
24
- this.#overlay.setAttribute('role', 'alert');
25
- root.appendChild(this.#overlay);
26
-
27
- return root;
28
- }
29
-
30
- protected updateSkin(state: JuxErrorState): void {
31
- if (!this.#overlay || !this.root) return;
32
-
33
- // Apply base attributes
34
- this.applySkinAttributes(this.root, state);
35
-
36
- if (!state.visible) {
37
- this.#overlay.classList.remove('jux-error-visible');
38
- this.#overlay.innerHTML = '';
39
- return;
40
- }
41
-
42
- this.#overlay.classList.add('jux-error-visible');
43
- this.#overlay.innerHTML = this.#renderError(state);
44
- }
45
-
46
- #renderError(state: JuxErrorState): string {
47
- const typeIcon = this.#getTypeIcon(state.errorType);
48
- const typeClass = `jux-error-type-${state.errorType}`;
49
-
50
- return `
51
- <div class="jux-error-backdrop"></div>
52
- <div class="jux-error-dialog ${typeClass}">
53
- <header class="jux-error-header">
54
- <span class="jux-error-icon">${typeIcon}</span>
55
- <h2 class="jux-error-title">${this.#escapeHtml(state.title)}</h2>
56
- <button class="jux-error-close" aria-label="Dismiss error">×</button>
57
- </header>
58
-
59
- <div class="jux-error-body">
60
- <p class="jux-error-message">${this.#escapeHtml(state.message)}</p>
61
-
62
- ${state.culpritFrame ? this.#renderCulprit(state.culpritFrame) : ''}
63
-
64
- ${state.stack.length > 0 ? this.#renderStackSection(state) : ''}
65
- </div>
66
-
67
- <footer class="jux-error-footer">
68
- <span class="jux-error-timestamp">${this.#formatTime(state.timestamp)}</span>
69
- <div class="jux-error-actions">
70
- <button class="jux-error-copy" title="Copy error details">📋 Copy</button>
71
- <button class="jux-error-dismiss">Dismiss</button>
72
- </div>
73
- </footer>
74
- </div>
75
- `;
76
- }
77
-
78
- #renderCulprit(frame: StackFrame): string {
79
- return `
80
- <div class="jux-error-culprit">
81
- <div class="jux-error-culprit-header">
82
- <span class="jux-error-culprit-icon">👉</span>
83
- <span class="jux-error-culprit-file">${this.#escapeHtml(frame.file)}</span>
84
- <span class="jux-error-culprit-location">:${frame.line}:${frame.column}</span>
85
- </div>
86
- ${frame.code ? `
87
- <pre class="jux-error-culprit-code"><code>${this.#escapeHtml(frame.code)}</code></pre>
88
- ` : ''}
89
- <div class="jux-error-culprit-function">
90
- in <code>${this.#escapeHtml(frame.function)}</code>
91
- </div>
92
- </div>
93
- `;
94
- }
95
-
96
- #renderStackSection(state: JuxErrorState): string {
97
- const expandedClass = state.expanded ? 'jux-error-stack-expanded' : '';
98
-
99
- return `
100
- <div class="jux-error-stack-section ${expandedClass}">
101
- <button class="jux-error-stack-toggle">
102
- <span class="jux-error-stack-toggle-icon">${state.expanded ? '▼' : '▶'}</span>
103
- Stack Trace (${state.stack.length} frames)
104
- </button>
105
- <div class="jux-error-stack-frames">
106
- ${state.stack.map((frame, i) => this.#renderFrame(frame, i)).join('')}
107
- </div>
108
- </div>
109
- `;
110
- }
111
-
112
- #renderFrame(frame: StackFrame, index: number): string {
113
- const userClass = frame.isUserCode ? 'jux-error-frame-user' : 'jux-error-frame-lib';
114
-
115
- return `
116
- <div class="jux-error-frame ${userClass}" data-index="${index}">
117
- <span class="jux-error-frame-index">${index}</span>
118
- <span class="jux-error-frame-function">${this.#escapeHtml(frame.function)}</span>
119
- <span class="jux-error-frame-location">
120
- ${this.#escapeHtml(frame.file)}:${frame.line}:${frame.column}
121
- </span>
122
- </div>
123
- `;
124
- }
125
-
126
- #getTypeIcon(type: JuxErrorState['errorType']): string {
127
- const icons: Record<JuxErrorState['errorType'], string> = {
128
- runtime: '💥',
129
- compile: '🔨',
130
- network: '🌐',
131
- validation: '⚠️',
132
- unknown: '❓'
133
- };
134
- return icons[type];
135
- }
136
-
137
- #formatTime(timestamp: number): string {
138
- return new Date(timestamp).toLocaleTimeString();
139
- }
140
-
141
- #escapeHtml(str: string): string {
142
- const div = document.createElement('div');
143
- div.textContent = str;
144
- return div.innerHTML;
145
- }
146
-
147
- #copyErrorDetails(): void {
148
- const state = this.engine.state;
149
- const details = [
150
- `${state.title}: ${state.message}`,
151
- '',
152
- state.culpritFrame ? `File: ${state.culpritFrame.file}:${state.culpritFrame.line}` : '',
153
- '',
154
- 'Stack Trace:',
155
- ...state.stack.map(f => ` at ${f.function} (${f.file}:${f.line}:${f.column})`)
156
- ].filter(Boolean).join('\n');
157
-
158
- navigator.clipboard.writeText(details).then(() => {
159
- const copyBtn = this.#overlay?.querySelector('.jux-error-copy');
160
- if (copyBtn) {
161
- copyBtn.textContent = '✓ Copied!';
162
- setTimeout(() => { copyBtn.textContent = '📋 Copy'; }, 1500);
163
- }
164
- });
165
- }
166
-
167
- protected bindEvents(root: HTMLElement): void {
168
- root.addEventListener('click', (e: MouseEvent) => {
169
- const target = e.target as HTMLElement;
170
-
171
- // Close button or backdrop
172
- if (target.closest('.jux-error-close') ||
173
- target.closest('.jux-error-dismiss') ||
174
- target.closest('.jux-error-backdrop')) {
175
- this.engine.dismiss();
176
- return;
177
- }
178
-
179
- // Toggle stack trace
180
- if (target.closest('.jux-error-stack-toggle')) {
181
- this.engine.toggleExpanded();
182
- return;
183
- }
184
-
185
- // Copy button
186
- if (target.closest('.jux-error-copy')) {
187
- this.#copyErrorDetails();
188
- return;
189
- }
190
- });
191
-
192
- // ESC key to dismiss
193
- this.#keydownHandler = (e: KeyboardEvent) => {
194
- if (e.key === 'Escape' && this.engine.state.visible) {
195
- this.engine.dismiss();
196
- }
197
- };
198
- document.addEventListener('keydown', this.#keydownHandler);
199
- }
200
- }
@@ -1,351 +0,0 @@
1
- /* ========================================
2
- JUX Error Overlay - Vite-style
3
- ======================================== */
4
-
5
- .jux-error-overlay {
6
- --jux-err-bg: #1a1a1a;
7
- --jux-err-surface: #242424;
8
- --jux-err-border: #333;
9
- --jux-err-text: #e0e0e0;
10
- --jux-err-text-dim: #888;
11
- --jux-err-accent: #ff5555;
12
- --jux-err-accent-compile: #ffaa00;
13
- --jux-err-accent-network: #55aaff;
14
- --jux-err-accent-validation: #ffcc00;
15
- --jux-err-code-bg: #2d2d2d;
16
- --jux-err-user-frame: #4ade80;
17
- --jux-err-lib-frame: #666;
18
- --jux-err-radius: 8px;
19
- --jux-err-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
20
-
21
- position: fixed;
22
- inset: 0;
23
- z-index: 99999;
24
- display: none;
25
- font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace;
26
- font-size: 14px;
27
- line-height: 1.5;
28
- }
29
-
30
- .jux-error-overlay.jux-error-visible {
31
- display: flex;
32
- align-items: center;
33
- justify-content: center;
34
- }
35
-
36
- /* Backdrop */
37
- .jux-error-backdrop {
38
- position: absolute;
39
- inset: 0;
40
- background: rgba(0, 0, 0, 0.75);
41
- backdrop-filter: blur(4px);
42
- }
43
-
44
- /* Dialog */
45
- .jux-error-dialog {
46
- position: relative;
47
- width: 90%;
48
- max-width: 800px;
49
- max-height: 85vh;
50
- overflow: hidden;
51
- display: flex;
52
- flex-direction: column;
53
- background: var(--jux-err-bg);
54
- border: 1px solid var(--jux-err-border);
55
- border-radius: var(--jux-err-radius);
56
- box-shadow: var(--jux-err-shadow);
57
- animation: jux-error-slide-in 0.2s ease-out;
58
- }
59
-
60
- @keyframes jux-error-slide-in {
61
- from {
62
- opacity: 0;
63
- transform: translateY(-20px) scale(0.98);
64
- }
65
- to {
66
- opacity: 1;
67
- transform: translateY(0) scale(1);
68
- }
69
- }
70
-
71
- /* Type-specific accent colors */
72
- .jux-error-type-runtime { --jux-err-current-accent: var(--jux-err-accent); }
73
- .jux-error-type-compile { --jux-err-current-accent: var(--jux-err-accent-compile); }
74
- .jux-error-type-network { --jux-err-current-accent: var(--jux-err-accent-network); }
75
- .jux-error-type-validation { --jux-err-current-accent: var(--jux-err-accent-validation); }
76
- .jux-error-type-unknown { --jux-err-current-accent: var(--jux-err-accent); }
77
-
78
- /* Header */
79
- .jux-error-header {
80
- display: flex;
81
- align-items: center;
82
- gap: 12px;
83
- padding: 16px 20px;
84
- background: var(--jux-err-surface);
85
- border-bottom: 1px solid var(--jux-err-border);
86
- border-left: 4px solid var(--jux-err-current-accent);
87
- }
88
-
89
- .jux-error-icon {
90
- font-size: 24px;
91
- line-height: 1;
92
- }
93
-
94
- .jux-error-title {
95
- flex: 1;
96
- margin: 0;
97
- font-size: 18px;
98
- font-weight: 600;
99
- color: var(--jux-err-current-accent);
100
- }
101
-
102
- .jux-error-close {
103
- width: 32px;
104
- height: 32px;
105
- display: flex;
106
- align-items: center;
107
- justify-content: center;
108
- background: transparent;
109
- border: none;
110
- border-radius: 4px;
111
- color: var(--jux-err-text-dim);
112
- font-size: 24px;
113
- cursor: pointer;
114
- transition: background 0.15s, color 0.15s;
115
- }
116
-
117
- .jux-error-close:hover {
118
- background: rgba(255, 255, 255, 0.1);
119
- color: var(--jux-err-text);
120
- }
121
-
122
- /* Body */
123
- .jux-error-body {
124
- flex: 1;
125
- overflow-y: auto;
126
- padding: 20px;
127
- }
128
-
129
- .jux-error-message {
130
- margin: 0 0 20px;
131
- padding: 16px;
132
- background: var(--jux-err-code-bg);
133
- border-radius: var(--jux-err-radius);
134
- color: var(--jux-err-text);
135
- white-space: pre-wrap;
136
- word-break: break-word;
137
- }
138
-
139
- /* Culprit Section */
140
- .jux-error-culprit {
141
- margin-bottom: 20px;
142
- padding: 16px;
143
- background: var(--jux-err-surface);
144
- border: 1px solid var(--jux-err-current-accent);
145
- border-radius: var(--jux-err-radius);
146
- }
147
-
148
- .jux-error-culprit-header {
149
- display: flex;
150
- align-items: center;
151
- gap: 8px;
152
- margin-bottom: 12px;
153
- font-weight: 600;
154
- }
155
-
156
- .jux-error-culprit-icon {
157
- font-size: 18px;
158
- }
159
-
160
- .jux-error-culprit-file {
161
- color: var(--jux-err-current-accent);
162
- }
163
-
164
- .jux-error-culprit-location {
165
- color: var(--jux-err-text-dim);
166
- }
167
-
168
- .jux-error-culprit-code {
169
- margin: 12px 0;
170
- padding: 12px;
171
- background: var(--jux-err-code-bg);
172
- border-radius: 4px;
173
- overflow-x: auto;
174
- }
175
-
176
- .jux-error-culprit-code code {
177
- color: var(--jux-err-text);
178
- }
179
-
180
- .jux-error-culprit-function {
181
- color: var(--jux-err-text-dim);
182
- font-size: 13px;
183
- }
184
-
185
- .jux-error-culprit-function code {
186
- color: var(--jux-err-user-frame);
187
- }
188
-
189
- /* Stack Trace Section */
190
- .jux-error-stack-section {
191
- border: 1px solid var(--jux-err-border);
192
- border-radius: var(--jux-err-radius);
193
- overflow: hidden;
194
- }
195
-
196
- .jux-error-stack-toggle {
197
- width: 100%;
198
- display: flex;
199
- align-items: center;
200
- gap: 8px;
201
- padding: 12px 16px;
202
- background: var(--jux-err-surface);
203
- border: none;
204
- color: var(--jux-err-text);
205
- font-family: inherit;
206
- font-size: 14px;
207
- cursor: pointer;
208
- transition: background 0.15s;
209
- }
210
-
211
- .jux-error-stack-toggle:hover {
212
- background: rgba(255, 255, 255, 0.05);
213
- }
214
-
215
- .jux-error-stack-toggle-icon {
216
- font-size: 10px;
217
- color: var(--jux-err-text-dim);
218
- }
219
-
220
- .jux-error-stack-frames {
221
- display: none;
222
- max-height: 300px;
223
- overflow-y: auto;
224
- }
225
-
226
- .jux-error-stack-expanded .jux-error-stack-frames {
227
- display: block;
228
- }
229
-
230
- .jux-error-frame {
231
- display: grid;
232
- grid-template-columns: 30px 1fr auto;
233
- gap: 12px;
234
- padding: 8px 16px;
235
- border-top: 1px solid var(--jux-err-border);
236
- font-size: 13px;
237
- }
238
-
239
- .jux-error-frame:hover {
240
- background: rgba(255, 255, 255, 0.02);
241
- }
242
-
243
- .jux-error-frame-index {
244
- color: var(--jux-err-text-dim);
245
- text-align: right;
246
- }
247
-
248
- .jux-error-frame-function {
249
- color: var(--jux-err-lib-frame);
250
- overflow: hidden;
251
- text-overflow: ellipsis;
252
- white-space: nowrap;
253
- }
254
-
255
- .jux-error-frame-user .jux-error-frame-function {
256
- color: var(--jux-err-user-frame);
257
- font-weight: 500;
258
- }
259
-
260
- .jux-error-frame-location {
261
- color: var(--jux-err-text-dim);
262
- overflow: hidden;
263
- text-overflow: ellipsis;
264
- white-space: nowrap;
265
- direction: rtl;
266
- text-align: left;
267
- }
268
-
269
- /* Footer */
270
- .jux-error-footer {
271
- display: flex;
272
- align-items: center;
273
- justify-content: space-between;
274
- padding: 12px 20px;
275
- background: var(--jux-err-surface);
276
- border-top: 1px solid var(--jux-err-border);
277
- }
278
-
279
- .jux-error-timestamp {
280
- color: var(--jux-err-text-dim);
281
- font-size: 12px;
282
- }
283
-
284
- .jux-error-actions {
285
- display: flex;
286
- gap: 8px;
287
- }
288
-
289
- .jux-error-actions button {
290
- padding: 8px 16px;
291
- background: var(--jux-err-code-bg);
292
- border: 1px solid var(--jux-err-border);
293
- border-radius: 4px;
294
- color: var(--jux-err-text);
295
- font-family: inherit;
296
- font-size: 13px;
297
- cursor: pointer;
298
- transition: background 0.15s, border-color 0.15s;
299
- }
300
-
301
- .jux-error-actions button:hover {
302
- background: rgba(255, 255, 255, 0.1);
303
- border-color: var(--jux-err-text-dim);
304
- }
305
-
306
- .jux-error-dismiss {
307
- background: var(--jux-err-current-accent) !important;
308
- border-color: var(--jux-err-current-accent) !important;
309
- color: #000 !important;
310
- font-weight: 500;
311
- }
312
-
313
- .jux-error-dismiss:hover {
314
- filter: brightness(1.1);
315
- }
316
-
317
- /* Scrollbar styling */
318
- .jux-error-body::-webkit-scrollbar,
319
- .jux-error-stack-frames::-webkit-scrollbar {
320
- width: 8px;
321
- }
322
-
323
- .jux-error-body::-webkit-scrollbar-track,
324
- .jux-error-stack-frames::-webkit-scrollbar-track {
325
- background: transparent;
326
- }
327
-
328
- .jux-error-body::-webkit-scrollbar-thumb,
329
- .jux-error-stack-frames::-webkit-scrollbar-thumb {
330
- background: var(--jux-err-border);
331
- border-radius: 4px;
332
- }
333
-
334
- .jux-error-body::-webkit-scrollbar-thumb:hover,
335
- .jux-error-stack-frames::-webkit-scrollbar-thumb:hover {
336
- background: var(--jux-err-text-dim);
337
- }
338
-
339
- .jux-juxerror {
340
- display: block;
341
- padding: var(--space-md);
342
- border: 1px solid var(--color-border);
343
- border-radius: var(--radius-sm);
344
- background-color: var(--color-surface-base);
345
- color: var(--color-text-primary);
346
- transition: all var(--transition-fast);
347
- }
348
-
349
- .jux-juxerror:hover {
350
- background-color: var(--color-surface-hover);
351
- }