@vesk/runtime 0.0.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.
Files changed (81) hide show
  1. package/README.md +23 -0
  2. package/dist/action.d.ts +43 -0
  3. package/dist/action.d.ts.map +1 -0
  4. package/dist/action.js +84 -0
  5. package/dist/bindings.d.ts +4 -0
  6. package/dist/bindings.d.ts.map +1 -0
  7. package/dist/bindings.js +137 -0
  8. package/dist/context.d.ts +15 -0
  9. package/dist/context.d.ts.map +1 -0
  10. package/dist/context.js +34 -0
  11. package/dist/experiment.d.ts +17 -0
  12. package/dist/experiment.d.ts.map +1 -0
  13. package/dist/experiment.js +71 -0
  14. package/dist/form.d.ts +36 -0
  15. package/dist/form.d.ts.map +1 -0
  16. package/dist/form.js +278 -0
  17. package/dist/hmr-client.d.ts +1 -0
  18. package/dist/hmr-client.d.ts.map +1 -0
  19. package/dist/hmr-client.js +273 -0
  20. package/dist/hydrate.d.ts +34 -0
  21. package/dist/hydrate.d.ts.map +1 -0
  22. package/dist/hydrate.js +248 -0
  23. package/dist/image.d.ts +19 -0
  24. package/dist/image.d.ts.map +1 -0
  25. package/dist/image.js +51 -0
  26. package/dist/index-client.d.ts +16 -0
  27. package/dist/index-client.d.ts.map +1 -0
  28. package/dist/index-client.js +15 -0
  29. package/dist/index-server.d.ts +15 -0
  30. package/dist/index-server.d.ts.map +1 -0
  31. package/dist/index-server.js +14 -0
  32. package/dist/isr.d.ts +27 -0
  33. package/dist/isr.d.ts.map +1 -0
  34. package/dist/isr.js +143 -0
  35. package/dist/md.d.ts +17 -0
  36. package/dist/md.d.ts.map +1 -0
  37. package/dist/md.js +507 -0
  38. package/dist/package.json +23 -0
  39. package/dist/portal.d.ts +8 -0
  40. package/dist/portal.d.ts.map +1 -0
  41. package/dist/portal.js +20 -0
  42. package/dist/reconcile.d.ts +3 -0
  43. package/dist/reconcile.d.ts.map +1 -0
  44. package/dist/reconcile.js +66 -0
  45. package/dist/request.d.ts +188 -0
  46. package/dist/request.d.ts.map +1 -0
  47. package/dist/request.js +624 -0
  48. package/dist/resource.d.ts +47 -0
  49. package/dist/resource.d.ts.map +1 -0
  50. package/dist/resource.js +502 -0
  51. package/dist/ripple-blocks.d.ts +18 -0
  52. package/dist/ripple-blocks.d.ts.map +1 -0
  53. package/dist/ripple-blocks.js +184 -0
  54. package/dist/ripple-constants.d.ts +42 -0
  55. package/dist/ripple-constants.d.ts.map +1 -0
  56. package/dist/ripple-constants.js +41 -0
  57. package/dist/ripple-runtime.d.ts +125 -0
  58. package/dist/ripple-runtime.d.ts.map +1 -0
  59. package/dist/ripple-runtime.js +891 -0
  60. package/dist/ripple-utils.d.ts +12 -0
  61. package/dist/ripple-utils.d.ts.map +1 -0
  62. package/dist/ripple-utils.js +10 -0
  63. package/dist/router-components.d.ts +83 -0
  64. package/dist/router-components.d.ts.map +1 -0
  65. package/dist/router-components.js +320 -0
  66. package/dist/router-match.d.ts +40 -0
  67. package/dist/router-match.d.ts.map +1 -0
  68. package/dist/router-match.js +158 -0
  69. package/dist/router.d.ts +56 -0
  70. package/dist/router.d.ts.map +1 -0
  71. package/dist/router.js +1330 -0
  72. package/dist/seo.d.ts +94 -0
  73. package/dist/seo.d.ts.map +1 -0
  74. package/dist/seo.js +138 -0
  75. package/dist/suspense.d.ts +1 -0
  76. package/dist/suspense.d.ts.map +1 -0
  77. package/dist/suspense.js +14 -0
  78. package/dist/track.d.ts +20 -0
  79. package/dist/track.d.ts.map +1 -0
  80. package/dist/track.js +124 -0
  81. package/package.json +55 -0
package/dist/form.js ADDED
@@ -0,0 +1,278 @@
1
+ function appendChildren(parent, children) {
2
+ if (children == null)
3
+ return;
4
+ if (typeof children === 'string' || typeof children === 'number') {
5
+ parent.insertAdjacentHTML('beforeend', String(children));
6
+ }
7
+ else if (children instanceof Node) {
8
+ parent.appendChild(children);
9
+ }
10
+ else if (Array.isArray(children)) {
11
+ for (const c of children)
12
+ appendChildren(parent, c);
13
+ }
14
+ }
15
+ function formIsSSR() {
16
+ return typeof document === 'undefined';
17
+ }
18
+ function escapeHtml(s) {
19
+ return s
20
+ .replace(/&/g, '&')
21
+ .replace(/</g, '&lt;')
22
+ .replace(/>/g, '&gt;')
23
+ .replace(/"/g, '&quot;');
24
+ }
25
+ function actionUrl(action) {
26
+ if (typeof action === 'string')
27
+ return action;
28
+ if (action && typeof action === 'object') {
29
+ const a = action;
30
+ if (a.__veskAction === true || typeof a.url === 'string')
31
+ return String(a.url || '');
32
+ }
33
+ return '';
34
+ }
35
+ function readServerFieldErrors() {
36
+ return globalThis.__vesk_action_errors || {};
37
+ }
38
+ export function required(msg) {
39
+ return { validate: (v) => v != null && v !== '', message: msg || 'This field is required' };
40
+ }
41
+ export function email(msg) {
42
+ return { validate: (v) => !v || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v), message: msg || 'Invalid email address' };
43
+ }
44
+ export function minLength(n, msg) {
45
+ return { validate: (v) => !v || v.length >= n, message: msg || `Must be at least ${n} characters` };
46
+ }
47
+ export function maxLength(n, msg) {
48
+ return { validate: (v) => !v || v.length <= n, message: msg || `Must be at most ${n} characters` };
49
+ }
50
+ export function pattern(re, msg) {
51
+ return { validate: (v) => !v || re.test(v), message: msg || 'Invalid format' };
52
+ }
53
+ export function custom(fn, msg) {
54
+ return { validate: fn, message: msg || 'Invalid value' };
55
+ }
56
+ export function Field(props, registry, hydrate) {
57
+ const { name, label, rules = [], children, errorClass, class: className, style, ...rest } = props;
58
+ if (formIsSSR()) {
59
+ const labelHtml = label ? `<label>${label}</label>` : '';
60
+ const serverErrors = readServerFieldErrors();
61
+ const serverErr = serverErrors[name] ? String(serverErrors[name]) : '';
62
+ const errStyle = serverErr ? '' : 'display:none';
63
+ const errText = serverErr ? escapeHtml(serverErr) : '';
64
+ const errCls = errorClass ? ` class="${errorClass}"` : '';
65
+ const wrapCls = className ? ` class="${className}"` : '';
66
+ const wrapStyle = style ? ` style="${String(style).replace(/"/g, '&quot;')}"` : '';
67
+ const fieldAttrs = ` data-vsk-field="${name}"`;
68
+ const extra = Object.entries(rest).filter(([, v]) => v != null && v !== false).map(([k, v]) => ` ${k}="${String(v).replace(/"/g, '&quot;')}"`).join('');
69
+ return `<div${fieldAttrs}${wrapCls}${wrapStyle}${extra}>${labelHtml}${children || ''}<div data-vsk-error style="${errStyle}"${errCls}>${errText}</div></div>`;
70
+ }
71
+ if (hydrate && hydrate.nextElement) {
72
+ let wrapper = hydrate.nextElement('div');
73
+ if (wrapper && !wrapper.parentNode && hydrate.root) {
74
+ const existing = hydrate.root.querySelector(`[data-vsk-field="${name}"]`);
75
+ if (existing)
76
+ wrapper = existing;
77
+ }
78
+ const inner = wrapper ? wrapper.querySelector(`[data-vsk-field="${name}"]`) : null;
79
+ const fieldEl = inner || wrapper;
80
+ if (fieldEl)
81
+ fieldEl.__vsk_rules = rules;
82
+ return document.createDocumentFragment();
83
+ }
84
+ const wrapper = document.createElement('div');
85
+ wrapper.setAttribute('data-vsk-field', name);
86
+ if (className)
87
+ wrapper.className = className;
88
+ if (style)
89
+ wrapper.style.cssText = style;
90
+ for (const [k, v] of Object.entries(rest)) {
91
+ if (v != null && v !== false)
92
+ wrapper.setAttribute(k, v === true ? '' : String(v));
93
+ }
94
+ wrapper.__vsk_rules = rules;
95
+ if (label) {
96
+ const lbl = document.createElement('label');
97
+ lbl.textContent = label;
98
+ wrapper.appendChild(lbl);
99
+ }
100
+ if (children)
101
+ appendChildren(wrapper, children);
102
+ const errEl = document.createElement('div');
103
+ errEl.setAttribute('data-vsk-error', '');
104
+ errEl.style.display = 'none';
105
+ if (errorClass)
106
+ errEl.className = errorClass;
107
+ wrapper.appendChild(errEl);
108
+ return wrapper;
109
+ }
110
+ function bindFormSubmit(form, { action, method, onSubmit, onError, onSuccess }) {
111
+ const resolvedAction = actionUrl(action);
112
+ const actionSchema = (typeof action === 'object' && action !== null && action.input)
113
+ ? action.input
114
+ : undefined;
115
+ form.addEventListener('submit', async (e) => {
116
+ e.preventDefault();
117
+ const data = new FormData(form);
118
+ const obj = {};
119
+ for (const [k, v] of data.entries()) {
120
+ if (k in obj) {
121
+ if (!Array.isArray(obj[k]))
122
+ obj[k] = [obj[k]];
123
+ obj[k].push(v);
124
+ }
125
+ else {
126
+ obj[k] = v;
127
+ }
128
+ }
129
+ const fields = form.querySelectorAll('[data-vsk-field]');
130
+ let hasErrors = false;
131
+ for (const el of fields) {
132
+ const fieldName = el.getAttribute('data-vsk-field');
133
+ const propRules = (el.__vsk_rules || []);
134
+ const schemaRules = fieldName && actionSchema && actionSchema[fieldName]
135
+ ? (Array.isArray(actionSchema[fieldName]) ? actionSchema[fieldName] : [actionSchema[fieldName]])
136
+ : [];
137
+ const rules = [...propRules, ...schemaRules];
138
+ const errEl = el.querySelector('[data-vsk-error]');
139
+ let errMsg = '';
140
+ for (const rule of rules) {
141
+ if (!rule.validate(obj[fieldName || ''])) {
142
+ errMsg = rule.message;
143
+ break;
144
+ }
145
+ }
146
+ if (errEl) {
147
+ errEl.textContent = errMsg;
148
+ errEl.style.display = errMsg ? '' : 'none';
149
+ }
150
+ if (errMsg)
151
+ hasErrors = true;
152
+ }
153
+ if (hasErrors) {
154
+ form.dispatchEvent(new CustomEvent('vsk-error', { detail: { errors: true } }));
155
+ return;
156
+ }
157
+ form.classList.add('vsk-submitting');
158
+ const submitBtn = form.querySelector('[type="submit"], button[type="submit"]');
159
+ if (submitBtn)
160
+ submitBtn.disabled = true;
161
+ form.dispatchEvent(new CustomEvent('vsk-loading', { detail: { loading: true } }));
162
+ const isActionDescriptor = typeof action === 'object' && action !== null;
163
+ try {
164
+ if (onSubmit) {
165
+ const result = onSubmit(obj, form);
166
+ if (result && typeof result.then === 'function')
167
+ await result;
168
+ }
169
+ else if (isActionDescriptor) {
170
+ const res = await fetch(resolvedAction, {
171
+ method,
172
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
173
+ body: JSON.stringify(obj),
174
+ });
175
+ const payload = await res.json().catch(() => null);
176
+ if (payload && payload.ok === false && Array.isArray(payload.issues)) {
177
+ const byField = {};
178
+ for (const issue of payload.issues) {
179
+ if (issue && typeof issue.field === 'string' && !(issue.field in byField)) {
180
+ byField[issue.field] = String(issue.message || 'Invalid value');
181
+ }
182
+ }
183
+ let hasServerErrors = false;
184
+ for (const el of fields) {
185
+ const fieldName = el.getAttribute('data-vsk-field');
186
+ const errEl = el.querySelector('[data-vsk-error]');
187
+ const msg = fieldName ? byField[fieldName] : '';
188
+ if (errEl) {
189
+ errEl.textContent = msg;
190
+ errEl.style.display = msg ? '' : 'none';
191
+ }
192
+ if (msg)
193
+ hasServerErrors = true;
194
+ }
195
+ if (hasServerErrors) {
196
+ form.dispatchEvent(new CustomEvent('vsk-error', { detail: { issues: payload.issues } }));
197
+ return;
198
+ }
199
+ }
200
+ if (!res.ok)
201
+ throw res;
202
+ form.dispatchEvent(new CustomEvent('vsk-success', { detail: { response: res, data: payload } }));
203
+ if (onSuccess)
204
+ onSuccess(res);
205
+ }
206
+ else if (resolvedAction) {
207
+ const res = await fetch(resolvedAction, { method, body: data });
208
+ if (!res.ok)
209
+ throw res;
210
+ form.dispatchEvent(new CustomEvent('vsk-success', { detail: { response: res } }));
211
+ if (onSuccess)
212
+ onSuccess(res);
213
+ }
214
+ }
215
+ catch (err) {
216
+ form.dispatchEvent(new CustomEvent('vsk-error', { detail: { error: err } }));
217
+ if (onError)
218
+ onError(err);
219
+ }
220
+ finally {
221
+ if (submitBtn)
222
+ submitBtn.disabled = false;
223
+ form.classList.remove('vsk-submitting');
224
+ form.dispatchEvent(new CustomEvent('vsk-loading', { detail: { loading: false } }));
225
+ }
226
+ });
227
+ }
228
+ export function Form(props, registry, hydrate) {
229
+ const { children, onSubmit, onError, onSuccess, action, method = 'POST', class: className, style, ...rest } = props;
230
+ if (formIsSSR()) {
231
+ const attrs = { action: actionUrl(action), method, novalidate: true };
232
+ if (className)
233
+ attrs.class = className;
234
+ if (style)
235
+ attrs.style = style;
236
+ for (const [k, v] of Object.entries(rest)) {
237
+ if (v != null && v !== false)
238
+ attrs[k] = v;
239
+ }
240
+ const attrStr = Object.entries(attrs)
241
+ .filter(([, v]) => v != null && v !== false)
242
+ .map(([k, v]) => v === true ? k : `${k}="${String(v).replace(/"/g, '&quot;')}"`)
243
+ .join(' ');
244
+ return `<form ${attrStr}>${children || ''}</form>`;
245
+ }
246
+ if (hydrate && hydrate.nextElement) {
247
+ let form = hydrate.nextElement('form');
248
+ if (form && !form.parentNode && hydrate.root) {
249
+ const existing = hydrate.root.querySelector('form');
250
+ if (existing)
251
+ form = existing;
252
+ }
253
+ if (form) {
254
+ form.noValidate = true;
255
+ bindFormSubmit(form, { action, method, onSubmit, onError, onSuccess });
256
+ }
257
+ return document.createDocumentFragment();
258
+ }
259
+ const form = document.createElement('form');
260
+ const resolvedAction = actionUrl(action);
261
+ if (resolvedAction)
262
+ form.action = resolvedAction;
263
+ if (method)
264
+ form.method = method;
265
+ form.noValidate = true;
266
+ if (className)
267
+ form.className = className;
268
+ if (style)
269
+ form.style.cssText = style;
270
+ for (const [k, v] of Object.entries(rest)) {
271
+ if (typeof v === 'string')
272
+ form.setAttribute(k, v);
273
+ }
274
+ if (children)
275
+ appendChildren(form, children);
276
+ bindFormSubmit(form, { action, method, onSubmit, onError, onSuccess });
277
+ return form;
278
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=hmr-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-client.d.ts","sourceRoot":"","sources":["../src/hmr-client.ts"],"names":[],"mappings":""}
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ (function () {
3
+ var host = (location.protocol === 'https:' ? 'wss:' : 'ws:') + '//' + location.host + '/_vesk/hmr';
4
+ var ws = null;
5
+ var status = 'loading';
6
+ var lastError = null;
7
+ var lastCompileMs = 0;
8
+ var reconnectTimer = null;
9
+ function connect() {
10
+ try {
11
+ ws = new WebSocket(host);
12
+ ws.onopen = function () {
13
+ status = 'connected';
14
+ clearError();
15
+ updateDot();
16
+ };
17
+ ws.onmessage = function (e) {
18
+ try {
19
+ var msg = JSON.parse(e.data);
20
+ switch (msg.type) {
21
+ case 'update':
22
+ if (msg.fnSources) {
23
+ var _eval = globalThis.__vesk_hmr_eval || function (c) { try {
24
+ return eval(c);
25
+ }
26
+ catch (ex) {
27
+ console.error('HMR eval error:', ex);
28
+ } };
29
+ Object.values(msg.fnSources).forEach(function (fn) { _eval(fn); });
30
+ }
31
+ globalThis.__updatedComponents = new Set(Object.keys((msg.components || {})));
32
+ var router = globalThis.__vesk_router;
33
+ if (router && typeof router.hmrUpdate === 'function') {
34
+ router.hmrUpdate();
35
+ }
36
+ lastCompileMs = msg.time || 0;
37
+ status = 'connected';
38
+ clearError();
39
+ updateDot();
40
+ break;
41
+ case 'reload':
42
+ window.location.reload();
43
+ break;
44
+ case 'error':
45
+ status = 'error';
46
+ lastError = msg;
47
+ showOverlay(msg);
48
+ updateDot();
49
+ break;
50
+ case 'css-update':
51
+ document.querySelectorAll('link[rel="stylesheet"]').forEach(function (el) {
52
+ var parent = el.parentNode;
53
+ if (!parent)
54
+ return;
55
+ var fresh = document.createElement('link');
56
+ fresh.rel = 'stylesheet';
57
+ fresh.href = el.href.split('?')[0] + '?t=' + Date.now();
58
+ fresh.onload = function () { el.remove(); };
59
+ fresh.onerror = function () { fresh.remove(); };
60
+ parent.insertBefore(fresh, el.nextSibling);
61
+ });
62
+ status = 'connected';
63
+ updateDot();
64
+ break;
65
+ case 'compiling':
66
+ status = 'compiling';
67
+ clearError();
68
+ updateDot();
69
+ break;
70
+ }
71
+ }
72
+ catch (_ex) { /* ignore bad messages */ }
73
+ };
74
+ ws.onclose = function () { if (status !== 'error') {
75
+ status = 'disconnected';
76
+ updateDot();
77
+ } scheduleReconnect(); };
78
+ ws.onerror = function () { if (status !== 'error') {
79
+ status = 'disconnected';
80
+ updateDot();
81
+ } scheduleReconnect(); };
82
+ }
83
+ catch (_ex) { /* WebSocket unavailable */ }
84
+ }
85
+ function scheduleReconnect() {
86
+ if (reconnectTimer)
87
+ clearTimeout(reconnectTimer);
88
+ reconnectTimer = setTimeout(connect, 3000);
89
+ }
90
+ function clearError() {
91
+ lastError = null;
92
+ hideOverlay();
93
+ }
94
+ var overlayEl = null;
95
+ var overlayVisible = false;
96
+ function createOverlay() {
97
+ if (document.getElementById('__vesk_overlay'))
98
+ return;
99
+ overlayEl = document.createElement('div');
100
+ overlayEl.id = '__vesk_overlay';
101
+ overlayEl.innerHTML =
102
+ '<style>' +
103
+ '#__vesk_overlay{all:initial;position:fixed;inset:0;z-index:2147483646;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;line-height:1.5;color:#e0e0e0;display:none;}' +
104
+ '#__vesk_overlay.open{display:flex;}' +
105
+ '#__vesk_overlay .__vo_backdrop{position:absolute;inset:0;background:rgba(0,0,0,0.65);backdrop-filter:blur(2px);}' +
106
+ '#__vesk_overlay .__vo_panel{position:relative;margin:32px auto;max-width:800px;width:90%;max-height:calc(100vh - 64px);background:#1a1b26;border:1px solid #2a2b3e;border-radius:12px;box-shadow:0 8px 48px rgba(0,0,0,0.7);display:flex;flex-direction:column;overflow:hidden;}' +
107
+ '#__vesk_overlay .__vo_header{display:flex;align-items:center;gap:10px;padding:16px 20px;border-bottom:1px solid #2a2b3e;flex-shrink:0;}' +
108
+ '#__vesk_overlay .__vo_icon{width:20px;height:20px;border-radius:50%;background:#ef4444;flex-shrink:0;}' +
109
+ '#__vesk_overlay .__vo_title{font-size:14px;font-weight:700;color:#ef4444;flex:1;}' +
110
+ '#__vesk_overlay .__vo_close{all:unset;cursor:pointer;width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:4px;color:#888;font-size:18px;}' +
111
+ '#__vesk_overlay .__vo_close:hover{background:#2a2b3e;color:#e0e0e0;}' +
112
+ '#__vesk_overlay .__vo_body{overflow-y:auto;padding:16px 20px;flex:1;}' +
113
+ '#__vesk_overlay .__vo_file{font-size:12px;color:#888;margin-bottom:8px;}' +
114
+ '#__vesk_overlay .__vo_file strong{color:#e0e0e0;}' +
115
+ '#__vesk_overlay .__vo_message{font-size:13px;color:#f87171;padding:8px 12px;background:#2a1b1b;border-radius:6px;margin-bottom:12px;white-space:pre-wrap;word-break:break-all;}' +
116
+ '#__vesk_overlay .__vo_code{background:#0f0f1a;border-radius:6px;padding:12px;margin-bottom:12px;overflow-x:auto;font-size:12px;line-height:1.6;}' +
117
+ '#__vesk_overlay .__vo_code pre{margin:0;white-space:pre;}' +
118
+ '#__vesk_overlay .__vo_code .hl{background:rgba(239,68,68,0.25);display:block;}' +
119
+ '#__vesk_overlay .__vo_code .hl::before{content:"> ";color:#ef4444;font-weight:700;}' +
120
+ '#__vesk_overlay .__vo_code .ln{color:#555;margin-right:12px;user-select:none;}' +
121
+ '#__vesk_overlay .__vo_tips{margin-top:8px;}' +
122
+ '#__vesk_overlay .__vo_tips_title{font-size:11px;font-weight:700;color:#eab308;margin-bottom:4px;}' +
123
+ '#__vesk_overlay .__vo_tip{padding:4px 0 4px 16px;font-size:12px;color:#bbb;position:relative;}' +
124
+ '#__vesk_overlay .__vo_tip::before{content:"\\2192";position:absolute;left:0;color:#eab308;}' +
125
+ '#__vesk_overlay .__vo_stack{margin-top:12px;}' +
126
+ '#__vesk_overlay .__vo_stack summary{cursor:pointer;font-size:11px;color:#888;padding:4px 0;}' +
127
+ '#__vesk_overlay .__vo_stack pre{background:#0f0f1a;border-radius:4px;padding:8px;margin-top:4px;font-size:11px;color:#888;max-height:200px;overflow:auto;white-space:pre;}' +
128
+ '#__vesk_overlay .__vo_footer{padding:8px 20px;border-top:1px solid #2a2b3e;font-size:11px;color:#555;text-align:center;flex-shrink:0;}' +
129
+ '</style>' +
130
+ '<div class="__vo_backdrop"></div>' +
131
+ '<div class="__vo_panel">' +
132
+ ' <div class="__vo_header">' +
133
+ ' <div class="__vo_icon"></div>' +
134
+ ' <div class="__vo_title">Compilation Error</div>' +
135
+ ' <button class="__vo_close" id="__vo_close">&times;</button>' +
136
+ ' </div>' +
137
+ ' <div class="__vo_body">' +
138
+ ' <div class="__vo_file" id="__vo_file"></div>' +
139
+ ' <div class="__vo_message" id="__vo_message"></div>' +
140
+ ' <div class="__vo_code" id="__vo_code"></div>' +
141
+ ' <div class="__vo_tips" id="__vo_tips"></div>' +
142
+ ' <details class="__vo_stack">' +
143
+ ' <summary>Stack trace</summary>' +
144
+ ' <pre id="__vo_stack"></pre>' +
145
+ ' </details>' +
146
+ ' </div>' +
147
+ ' <div class="__vo_footer">Vesk dev — click background or X to dismiss</div>' +
148
+ '</div>';
149
+ document.body.appendChild(overlayEl);
150
+ document.getElementById('__vo_close').onclick = hideOverlay;
151
+ overlayEl.querySelector('.__vo_backdrop').addEventListener('click', hideOverlay);
152
+ document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && overlayVisible)
153
+ hideOverlay(); });
154
+ }
155
+ function showOverlay(msg) {
156
+ if (!overlayEl)
157
+ createOverlay();
158
+ overlayEl = document.getElementById('__vesk_overlay');
159
+ if (!overlayEl)
160
+ return;
161
+ overlayVisible = true;
162
+ overlayEl.classList.add('open');
163
+ var fileInfo = '';
164
+ if (msg.file) {
165
+ fileInfo = 'File: <strong>' + escapeHtml(msg.file) + '</strong>';
166
+ if (msg.line)
167
+ fileInfo += ' at line ' + msg.line + (msg.column ? ', column ' + msg.column : '');
168
+ }
169
+ document.getElementById('__vo_file').innerHTML = fileInfo;
170
+ document.getElementById('__vo_message').textContent = msg.message || 'Unknown error';
171
+ var codeHtml = '';
172
+ if (msg.code) {
173
+ var codeLines = msg.code.split('\n');
174
+ codeHtml = '<pre>';
175
+ for (var i = 0; i < codeLines.length; i++) {
176
+ var ln = codeLines[i].match(/^(\d+):\s*/);
177
+ var lineNum = ln ? ln[1] : '';
178
+ var lineContent = ln ? codeLines[i].slice(ln[0].length) : codeLines[i];
179
+ var isErrorLine = msg.line && parseInt(lineNum) === msg.line;
180
+ codeHtml += '<span class="' + (isErrorLine ? 'hl' : '') + '"><span class="ln">' + padNum(lineNum, 4) + '</span>' + escapeHtml(lineContent) + '</span>';
181
+ }
182
+ codeHtml += '</pre>';
183
+ }
184
+ document.getElementById('__vo_code').innerHTML = codeHtml;
185
+ var tipsHtml = '';
186
+ if (msg.tips && msg.tips.length > 0) {
187
+ var shownHeader = false;
188
+ for (var t = 0; t < msg.tips.length; t++) {
189
+ if (!shownHeader) {
190
+ tipsHtml += '<div class="__vo_tips_title">Debug Tips</div>';
191
+ shownHeader = true;
192
+ }
193
+ tipsHtml += '<div class="__vo_tip">' + msg.tips[t] + '</div>';
194
+ }
195
+ }
196
+ if (msg.suggestions && msg.suggestions.length > 0) {
197
+ tipsHtml += '<div class="__vo_tips_title" style="margin-top:8px">Suggestions</div>';
198
+ for (var s = 0; s < Math.min(msg.suggestions.length, 4); s++) {
199
+ tipsHtml += '<div class="__vo_tip">-- ' + escapeHtml(msg.suggestions[s]) + '</div>';
200
+ }
201
+ }
202
+ if (msg.nextSteps && msg.nextSteps.length > 0) {
203
+ tipsHtml += '<div class="__vo_tips_title" style="margin-top:8px">Next Steps</div>';
204
+ for (var n = 0; n < Math.min(msg.nextSteps.length, 4); n++) {
205
+ tipsHtml += '<div class="__vo_tip">' + escapeHtml(msg.nextSteps[n]) + '</div>';
206
+ }
207
+ }
208
+ document.getElementById('__vo_tips').innerHTML = tipsHtml;
209
+ document.getElementById('__vo_stack').textContent = msg.stack || '(no stack trace)';
210
+ }
211
+ function hideOverlay() {
212
+ overlayVisible = false;
213
+ if (overlayEl)
214
+ overlayEl.classList.remove('open');
215
+ }
216
+ function escapeHtml(s) {
217
+ if (!s)
218
+ return '';
219
+ return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
220
+ }
221
+ function padNum(n, len) {
222
+ n = String(n);
223
+ while (n.length < len)
224
+ n = ' ' + n;
225
+ return n;
226
+ }
227
+ var dot = null;
228
+ function createDot() {
229
+ if (document.getElementById('__vesk_dev'))
230
+ return;
231
+ dot = document.createElement('div');
232
+ dot.id = '__vesk_dev';
233
+ dot.innerHTML =
234
+ '<style>' +
235
+ '#__vesk_dev{all:initial;position:fixed;bottom:16px;right:16px;z-index:2147483647;font-family:ui-monospace,monospace;font-size:11px;line-height:1.4;color:#e0e0e0;}' +
236
+ '#__vesk_dev .__v_bar{display:flex;align-items:center;gap:8px;background:#1a1b26;border:1px solid #2a2b3e;border-radius:10px;padding:6px 12px;box-shadow:0 4px 24px rgba(0,0,0,0.6);transition:all .2s;}' +
237
+ '#__vesk_dev .__v_bar:hover{border-color:#3a3b5e;}' +
238
+ '#__vesk_dev .__v_dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;transition:background .3s;}' +
239
+ '#__vesk_dev .__v_dot.connected{background:#22c55e;box-shadow:0 0 6px rgba(34,197,94,0.5);}' +
240
+ '#__vesk_dev .__v_dot.compiling{background:#eab308;box-shadow:0 0 6px rgba(234,179,8,0.5);animation:__v_pulse .8s infinite;}' +
241
+ '#__vesk_dev .__v_dot.error{background:#ef4444;box-shadow:0 0 6px rgba(239,68,68,0.5);}' +
242
+ '#__vesk_dev .__v_dot.disconnected{background:#6b7280;}' +
243
+ '#__vesk_dev .__v_dot.loading{background:#6b7280;animation:__v_pulse 1.2s infinite;}' +
244
+ '#__vesk_dev .__v_label{white-space:nowrap;}' +
245
+ '#__vesk_dev .__v_version{font-size:9px;color:#555;}' +
246
+ '@keyframes __v_pulse{0%,100%{opacity:1}50%{opacity:.4}}' +
247
+ '</style>' +
248
+ '<div class="__v_bar">' +
249
+ ' <span class="__v_dot loading"></span>' +
250
+ ' <span class="__v_label">Vesk</span>' +
251
+ ' <span class="__v_version">dev</span>' +
252
+ '</div>';
253
+ dot.querySelector('.__v_bar').addEventListener('click', function () {
254
+ if (lastError)
255
+ showOverlay(lastError);
256
+ });
257
+ document.body.appendChild(dot);
258
+ }
259
+ function updateDot() {
260
+ if (!document.getElementById('__vesk_dev'))
261
+ createDot();
262
+ var d = document.querySelector('#__vesk_dev .__v_dot');
263
+ if (d)
264
+ d.className = '__v_dot ' + status;
265
+ }
266
+ if (typeof document !== 'undefined' && document.body) {
267
+ createDot();
268
+ connect();
269
+ }
270
+ else if (typeof document !== 'undefined') {
271
+ document.addEventListener('DOMContentLoaded', function () { createDot(); connect(); });
272
+ }
273
+ })();
@@ -0,0 +1,34 @@
1
+ export interface HydrateWalker {
2
+ root: HTMLElement | null;
3
+ done(): boolean;
4
+ nextElement(tag?: string): Element;
5
+ subWalker(rootEl: HTMLElement): HydrateWalker;
6
+ }
7
+ interface HydrateIdleOptions {
8
+ chunkSize?: number;
9
+ timeout?: number;
10
+ }
11
+ interface HydrateInteractionOptions {
12
+ events?: string[];
13
+ }
14
+ interface HydrateCancelBase {
15
+ cancel(): void;
16
+ }
17
+ interface HydrateCancel extends HydrateCancelBase {
18
+ hydrateNow(): void;
19
+ }
20
+ export declare function reactiveProps<T extends Record<string, unknown>>(props: T): T;
21
+ export declare const _FILTER_ACCEPT = 1;
22
+ export declare const _FILTER_SKIP = 2;
23
+ export declare function collectVskMarkers(container: HTMLElement): Comment[];
24
+ export declare function createHydrateWalker(container: HTMLElement | null, markerList?: Comment[]): HydrateWalker;
25
+ export declare function createHydrateChildWalker(parentEl: HTMLElement | null): HydrateWalker;
26
+ export declare function hydrate(container: HTMLElement, componentFn: (props: Record<string, unknown>, registry: Map<string, unknown>, walker: HydrateWalker) => unknown, props?: Record<string, unknown>): unknown;
27
+ export declare function hydrateViewport(container: HTMLElement, componentFn: (props: Record<string, unknown>, registry: Map<string, unknown>, walker: HydrateWalker) => unknown, props?: Record<string, unknown>, rootMargin?: number): Promise<void>;
28
+ export declare function hydrateIdle(container: HTMLElement, componentFn: (props: Record<string, unknown>, registry: Map<string, unknown>, walker: HydrateWalker) => unknown, props?: Record<string, unknown>, options?: HydrateIdleOptions): HydrateCancelBase;
29
+ export declare function needsHydration(container: HTMLElement): boolean;
30
+ export declare function hydrateOnInteraction(container: HTMLElement, componentFn: (props: Record<string, unknown>, registry: Map<string, unknown>, walker: HydrateWalker) => unknown, props?: Record<string, unknown>, options?: HydrateInteractionOptions): HydrateCancel;
31
+ export declare function hydrationCount(container: HTMLElement): number;
32
+ export declare function hydrateInitial(container: HTMLElement, componentFn: (props: Record<string, unknown>, registry: Map<string, unknown>, walker: HydrateWalker) => unknown, props?: Record<string, unknown>): void;
33
+ export {};
34
+ //# sourceMappingURL=hydrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,IAAI,IAAI,OAAO,CAAC;IAChB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAAC;CAC9C;AAED,UAAU,kBAAkB;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,yBAAyB;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,UAAU,iBAAiB;IAC1B,MAAM,IAAI,IAAI,CAAC;CACf;AAED,UAAU,aAAc,SAAQ,iBAAiB;IAChD,UAAU,IAAI,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAU5E;AAGD,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,EAAE,CAOnE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,GAAG,aAAa,CAqCxG;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,GAAG,aAAa,CA2BpF;AAED,wBAAgB,OAAO,CACtB,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,EAC/G,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAGT;AAED,wBAAgB,eAAe,CAC9B,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,EAC/G,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,SAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED,wBAAgB,WAAW,CAC1B,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,EAC/G,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,GAAE,kBAAuB,GAC9B,iBAAiB,CAuCnB;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAK9D;AAED,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,EAC/G,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,GAAE,yBAA8B,GACrC,aAAa,CA6Bf;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,CAU7D;AAED,wBAAgB,cAAc,CAC7B,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,EAC/G,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI,CAGN"}