@vesk/vesk-cli 0.2.50-canary.9 → 0.2.50
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/dist/cli.js +595 -55
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -147,7 +147,10 @@ var init_errors = __esm({
|
|
|
147
147
|
suggestions;
|
|
148
148
|
nextSteps;
|
|
149
149
|
tip;
|
|
150
|
+
/** The V-diagnostic code, e.g. `V0501`. */
|
|
150
151
|
code;
|
|
152
|
+
/** The rendered code frame. Used to be written into `code`, which silently replaced the V-code. */
|
|
153
|
+
frame;
|
|
151
154
|
constructor(message, opts = {}) {
|
|
152
155
|
super(message);
|
|
153
156
|
this.name = "VeskError";
|
|
@@ -157,7 +160,8 @@ var init_errors = __esm({
|
|
|
157
160
|
this.suggestions = opts.suggestions || [];
|
|
158
161
|
this.nextSteps = opts.nextSteps || [];
|
|
159
162
|
this.tip = opts.tip || "";
|
|
160
|
-
if (opts.code !== void 0) this.code = opts.code;
|
|
163
|
+
if (opts.code !== void 0 && !opts.code.includes("\n")) this.code = opts.code;
|
|
164
|
+
if (opts.frame !== void 0) this.frame = opts.frame;
|
|
161
165
|
}
|
|
162
166
|
static notFound(name, candidates = [], context = {}) {
|
|
163
167
|
const allCandidates = [.../* @__PURE__ */ new Set([...candidates, ...VESK_BUILTINS])];
|
|
@@ -236,6 +240,84 @@ var init_errors = __esm({
|
|
|
236
240
|
}
|
|
237
241
|
);
|
|
238
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* A browser-only global used in code the SERVER evaluates.
|
|
245
|
+
*
|
|
246
|
+
* On the server these are either absent (`window is not defined`) or, worse,
|
|
247
|
+
* silently present-but-wrong (`navigator` exists in modern Node, so
|
|
248
|
+
* `navigator.onLine` is `undefined` and a page renders as if it were offline).
|
|
249
|
+
* A raw `ReferenceError` at request time is the worst possible report: it
|
|
250
|
+
* names neither the component nor the fix. This points at the line.
|
|
251
|
+
*/
|
|
252
|
+
static ssrUnsafeGlobal(name, context = {}) {
|
|
253
|
+
return new _VeskError(
|
|
254
|
+
`\`${name}\` is browser-only, and this component body runs during SSR.`,
|
|
255
|
+
{
|
|
256
|
+
...context,
|
|
257
|
+
code: context.code || "V0501",
|
|
258
|
+
suggestions: [
|
|
259
|
+
`Wrap the part that needs the DOM in a {#client} block.`,
|
|
260
|
+
`Move the code into an event handler \u2014 handlers never run on the server.`,
|
|
261
|
+
`Do the setup in on_destroy(), which the compiler only emits on the client.`
|
|
262
|
+
],
|
|
263
|
+
nextSteps: [
|
|
264
|
+
`component ${context.inComponent ?? "this component"}: wrap the \`${name}\` access in {#client}...{/client}.`,
|
|
265
|
+
`Or guard it: if (typeof ${name} !== 'undefined') { ... }`
|
|
266
|
+
],
|
|
267
|
+
tip: "SSR renders this component before the client exists. Reading a browser global here either throws during the request or (for `navigator`) silently returns undefined."
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The second name from `track()` called as a function.
|
|
273
|
+
*
|
|
274
|
+
* `const &[count, setCount] = track(0)` returns a CELL, not a setter function, so
|
|
275
|
+
* `setCount(1)` throws `setCount is not a function` from generated code with
|
|
276
|
+
* no line of user code in the message. The cell is the writer: `.set(v)`.
|
|
277
|
+
*/
|
|
278
|
+
static cellCalledAsFunction(name, context = {}) {
|
|
279
|
+
return new _VeskError(
|
|
280
|
+
`\`${name}\` is a cell, not a function \u2014 cells are written with \`.set()\`.`,
|
|
281
|
+
{
|
|
282
|
+
...context,
|
|
283
|
+
code: context.code || "V0502",
|
|
284
|
+
suggestions: [
|
|
285
|
+
`Use \`${name}.set(...)\` instead of \`${name}(...)\`.`,
|
|
286
|
+
`Or use the tracked spelling inside an event handler: set(${context.value ?? "value"}, ...)`
|
|
287
|
+
],
|
|
288
|
+
nextSteps: [
|
|
289
|
+
`const &[${context.value ?? "value"}, ${name}] = track(0) \u2192 \`${name}.set(v)\``,
|
|
290
|
+
"The value read in markup is the first name; the second is the cell object."
|
|
291
|
+
],
|
|
292
|
+
tip: `\`track()\` returns [value, cell]. \`${name}\` is the cell half.`
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* `set(value, …)` used outside a rewritten expression.
|
|
298
|
+
*
|
|
299
|
+
* The compiler rewrites `set(count, v)` to `countCell.set(v)` inside JSX and
|
|
300
|
+
* event handlers — but a bare statement in the component body is NOT
|
|
301
|
+
* rewritten, so the runtime `set` receives the value and throws
|
|
302
|
+
* "Cannot read properties of undefined". Pass the CELL, not the value.
|
|
303
|
+
*/
|
|
304
|
+
static setWithValueName(name, context = {}) {
|
|
305
|
+
return new _VeskError(
|
|
306
|
+
`\`set(${name}, \u2026)\` needs the CELL, and \`${name}\` is the value half of track().`,
|
|
307
|
+
{
|
|
308
|
+
...context,
|
|
309
|
+
code: context.code || "V0503",
|
|
310
|
+
suggestions: [
|
|
311
|
+
`Use \`set(${context.cell ?? "cell"}, \u2026)\` or \`${context.cell ?? "cell"}.set(\u2026)\`.`,
|
|
312
|
+
`Or move the set() into an event handler, where the compiler rewrites it for you.`
|
|
313
|
+
],
|
|
314
|
+
nextSteps: [
|
|
315
|
+
`const &[${name}, ${context.cell ?? "cell"}] = track(0) \u2192 \`${context.cell ?? "cell"}.set(v)\``
|
|
316
|
+
],
|
|
317
|
+
tip: "set(cell, value) is only rewritten inside JSX and handlers; in a body statement it reaches the runtime untouched."
|
|
318
|
+
}
|
|
319
|
+
);
|
|
320
|
+
}
|
|
239
321
|
static serverBlockInClient(compName, context = {}) {
|
|
240
322
|
return new _VeskError(
|
|
241
323
|
`{#server} block found in client island "${compName}". Client islands render on both server and client, so {#server} blocks have no effect.`,
|
|
@@ -18025,6 +18107,52 @@ function containsForOfIn(text) {
|
|
|
18025
18107
|
}
|
|
18026
18108
|
return false;
|
|
18027
18109
|
}
|
|
18110
|
+
function callsIdentifier(text, ident) {
|
|
18111
|
+
let i = 0;
|
|
18112
|
+
const len = text.length;
|
|
18113
|
+
let afterDot = false;
|
|
18114
|
+
while (i < len) {
|
|
18115
|
+
const ch = text[i];
|
|
18116
|
+
if (isWhitespaceChar(ch)) {
|
|
18117
|
+
i++;
|
|
18118
|
+
continue;
|
|
18119
|
+
}
|
|
18120
|
+
const commentEnd = skipComment(text, i);
|
|
18121
|
+
if (commentEnd !== i) {
|
|
18122
|
+
i = commentEnd;
|
|
18123
|
+
continue;
|
|
18124
|
+
}
|
|
18125
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
18126
|
+
i = skipString(text, i);
|
|
18127
|
+
afterDot = false;
|
|
18128
|
+
continue;
|
|
18129
|
+
}
|
|
18130
|
+
if (ch === "." || ch === "?" && text[i + 1] === ".") {
|
|
18131
|
+
afterDot = true;
|
|
18132
|
+
i += ch === "." ? 1 : 2;
|
|
18133
|
+
continue;
|
|
18134
|
+
}
|
|
18135
|
+
if (isIdentStartCode2(ch.charCodeAt(0))) {
|
|
18136
|
+
let j = i + 1;
|
|
18137
|
+
while (j < len && isIdentCharCode2(text.charCodeAt(j))) j++;
|
|
18138
|
+
const name = text.slice(i, j);
|
|
18139
|
+
let k = skipWhitespace(text, j);
|
|
18140
|
+
if (text[k] === "<") {
|
|
18141
|
+
k = skipTrackGeneric(text, k);
|
|
18142
|
+
k = skipWhitespace(text, k);
|
|
18143
|
+
}
|
|
18144
|
+
if (name === ident && text[k] === "(" && !afterDot) {
|
|
18145
|
+
return true;
|
|
18146
|
+
}
|
|
18147
|
+
afterDot = false;
|
|
18148
|
+
i = j;
|
|
18149
|
+
continue;
|
|
18150
|
+
}
|
|
18151
|
+
afterDot = false;
|
|
18152
|
+
i++;
|
|
18153
|
+
}
|
|
18154
|
+
return false;
|
|
18155
|
+
}
|
|
18028
18156
|
function unwrapTrackCall(init) {
|
|
18029
18157
|
const text = init.trim();
|
|
18030
18158
|
if (!startsWithIdentifier(text, "track")) return init;
|
|
@@ -21236,7 +21364,7 @@ function validateBlocks(compName, isClient, body, file, source) {
|
|
|
21236
21364
|
const { line, column } = offsetToLineCol2(source, pos);
|
|
21237
21365
|
opts.line = line;
|
|
21238
21366
|
opts.column = column;
|
|
21239
|
-
opts.
|
|
21367
|
+
opts.frame = codeFrame(source, line, column);
|
|
21240
21368
|
}
|
|
21241
21369
|
throw VeskError.serverBlockInClient(compName, opts);
|
|
21242
21370
|
}
|
|
@@ -21248,7 +21376,7 @@ function validateBlocks(compName, isClient, body, file, source) {
|
|
|
21248
21376
|
const { line, column } = offsetToLineCol2(source, pos);
|
|
21249
21377
|
opts.line = line;
|
|
21250
21378
|
opts.column = column;
|
|
21251
|
-
opts.
|
|
21379
|
+
opts.frame = codeFrame(source, line, column);
|
|
21252
21380
|
}
|
|
21253
21381
|
throw VeskError.clientBlockInServer(compName, opts);
|
|
21254
21382
|
}
|
|
@@ -25844,8 +25972,8 @@ function isPublicMarkdownPath(v) {
|
|
|
25844
25972
|
const c = s.charCodeAt(i);
|
|
25845
25973
|
if (c === 63 || c === 35 || c === 92) return false;
|
|
25846
25974
|
}
|
|
25847
|
-
const
|
|
25848
|
-
return stringEndsWith(
|
|
25975
|
+
const lower2 = s.toLowerCase();
|
|
25976
|
+
return stringEndsWith(lower2, ".md") || stringEndsWith(lower2, ".markdown");
|
|
25849
25977
|
}
|
|
25850
25978
|
function getMdPathCell(path) {
|
|
25851
25979
|
let cell = mdPathCells.get(path);
|
|
@@ -26517,9 +26645,9 @@ function toDomNode(value) {
|
|
|
26517
26645
|
}
|
|
26518
26646
|
if (typeof value !== "string") return value;
|
|
26519
26647
|
if (value === "") return document.createDocumentFragment();
|
|
26520
|
-
const
|
|
26521
|
-
|
|
26522
|
-
const { content } =
|
|
26648
|
+
const template2 = document.createElement("template");
|
|
26649
|
+
template2.innerHTML = value;
|
|
26650
|
+
const { content } = template2;
|
|
26523
26651
|
if (content.childNodes.length === 1) {
|
|
26524
26652
|
const only = content.firstChild;
|
|
26525
26653
|
content.removeChild(only);
|
|
@@ -26712,7 +26840,7 @@ function resolveTitle(meta, child) {
|
|
|
26712
26840
|
}
|
|
26713
26841
|
function mergeMetadata(...sources) {
|
|
26714
26842
|
const out = {};
|
|
26715
|
-
let
|
|
26843
|
+
let template2;
|
|
26716
26844
|
let sawTemplate = false;
|
|
26717
26845
|
for (const source of sources) {
|
|
26718
26846
|
if (!source) continue;
|
|
@@ -26725,7 +26853,7 @@ function mergeMetadata(...sources) {
|
|
|
26725
26853
|
if (key === "title") {
|
|
26726
26854
|
if (value && typeof value === "object" && value.template) {
|
|
26727
26855
|
sawTemplate = true;
|
|
26728
|
-
|
|
26856
|
+
template2 = value.template || template2;
|
|
26729
26857
|
}
|
|
26730
26858
|
out.title = value;
|
|
26731
26859
|
continue;
|
|
@@ -26737,9 +26865,9 @@ function mergeMetadata(...sources) {
|
|
|
26737
26865
|
const own = out.title;
|
|
26738
26866
|
if (typeof own === "string") out.title = { absolute: own };
|
|
26739
26867
|
else if (own && typeof own === "object" && own.template) {
|
|
26740
|
-
out.title = { default: own.default, template: own.template ||
|
|
26868
|
+
out.title = { default: own.default, template: own.template || template2 };
|
|
26741
26869
|
} else if (own && typeof own === "object") {
|
|
26742
|
-
out.title = { ...own, template };
|
|
26870
|
+
out.title = { ...own, template: template2 };
|
|
26743
26871
|
}
|
|
26744
26872
|
}
|
|
26745
26873
|
return out;
|
|
@@ -26825,6 +26953,56 @@ var init_metadata = __esm({
|
|
|
26825
26953
|
}
|
|
26826
26954
|
});
|
|
26827
26955
|
|
|
26956
|
+
// ../runtime/src/nested-update.ts
|
|
26957
|
+
function isObject(value) {
|
|
26958
|
+
return value !== null && typeof value === "object";
|
|
26959
|
+
}
|
|
26960
|
+
function setIn(value, path, next) {
|
|
26961
|
+
if (path.length === 0) return next;
|
|
26962
|
+
const [key, ...rest] = path;
|
|
26963
|
+
const container = Array.isArray(value) ? value : isObject(value) ? value : null;
|
|
26964
|
+
if (container === null) return value;
|
|
26965
|
+
const current2 = Array.isArray(container) ? container[typeof key === "number" ? key : Number(key)] : container[String(key)];
|
|
26966
|
+
if (rest.length > 0 && current2 === void 0) return value;
|
|
26967
|
+
if (Array.isArray(value)) {
|
|
26968
|
+
const index = typeof key === "number" ? key : Number(key);
|
|
26969
|
+
if (!Number.isInteger(index) || index < 0) return value;
|
|
26970
|
+
const copy2 = value.slice();
|
|
26971
|
+
copy2[index] = rest.length === 0 ? next : setIn(value[index], rest, next);
|
|
26972
|
+
return copy2;
|
|
26973
|
+
}
|
|
26974
|
+
if (!isObject(value)) return value;
|
|
26975
|
+
const copy = { ...value };
|
|
26976
|
+
copy[String(key)] = rest.length === 0 ? next : setIn(value[String(key)], rest, next);
|
|
26977
|
+
return copy;
|
|
26978
|
+
}
|
|
26979
|
+
function updateIn(value, path, fn) {
|
|
26980
|
+
if (path.length === 0) return fn(value);
|
|
26981
|
+
const [key, ...rest] = path;
|
|
26982
|
+
const child = getIn(value, [key]);
|
|
26983
|
+
const next = rest.length === 0 ? fn(child) : updateIn(child, rest, fn);
|
|
26984
|
+
return setIn(value, [key], next);
|
|
26985
|
+
}
|
|
26986
|
+
function getIn(value, path) {
|
|
26987
|
+
let current2 = value;
|
|
26988
|
+
for (const key of path) {
|
|
26989
|
+
if (Array.isArray(current2)) {
|
|
26990
|
+
const index = typeof key === "number" ? key : Number(key);
|
|
26991
|
+
if (!Number.isInteger(index)) return void 0;
|
|
26992
|
+
current2 = current2[index];
|
|
26993
|
+
continue;
|
|
26994
|
+
}
|
|
26995
|
+
if (!isObject(current2)) return void 0;
|
|
26996
|
+
current2 = current2[String(key)];
|
|
26997
|
+
}
|
|
26998
|
+
return current2;
|
|
26999
|
+
}
|
|
27000
|
+
var init_nested_update = __esm({
|
|
27001
|
+
"../runtime/src/nested-update.ts"() {
|
|
27002
|
+
"use strict";
|
|
27003
|
+
}
|
|
27004
|
+
});
|
|
27005
|
+
|
|
26828
27006
|
// ../runtime/src/index-server.ts
|
|
26829
27007
|
var index_server_exports = {};
|
|
26830
27008
|
__export(index_server_exports, {
|
|
@@ -26897,6 +27075,7 @@ __export(index_server_exports, {
|
|
|
26897
27075
|
get: () => get,
|
|
26898
27076
|
getAction: () => getAction,
|
|
26899
27077
|
getActiveComponent: () => getActiveComponent,
|
|
27078
|
+
getIn: () => getIn,
|
|
26900
27079
|
getLoadingError: () => getLoadingError,
|
|
26901
27080
|
getLoadingProgress: () => getLoadingProgress,
|
|
26902
27081
|
getServerContext: () => getServerContext,
|
|
@@ -26950,6 +27129,7 @@ __export(index_server_exports, {
|
|
|
26950
27129
|
server_locals: () => server_locals,
|
|
26951
27130
|
set: () => set,
|
|
26952
27131
|
setActiveComponent: () => setActiveComponent,
|
|
27132
|
+
setIn: () => setIn,
|
|
26953
27133
|
setServerContext: () => setServerContext,
|
|
26954
27134
|
setSignedCookie: () => setSignedCookie2,
|
|
26955
27135
|
setSsrData: () => setSsrData,
|
|
@@ -26964,6 +27144,7 @@ __export(index_server_exports, {
|
|
|
26964
27144
|
unlink_block: () => unlink_block,
|
|
26965
27145
|
unsignCookie: () => unsignCookie2,
|
|
26966
27146
|
untrack: () => untrack2,
|
|
27147
|
+
updateIn: () => updateIn,
|
|
26967
27148
|
useBody: () => useBody,
|
|
26968
27149
|
useFetch: () => useFetch,
|
|
26969
27150
|
useLoadingIndicator: () => useLoadingIndicator,
|
|
@@ -27002,6 +27183,7 @@ var init_index_server = __esm({
|
|
|
27002
27183
|
init_loading_indicator();
|
|
27003
27184
|
init_action();
|
|
27004
27185
|
init_metadata();
|
|
27186
|
+
init_nested_update();
|
|
27005
27187
|
}
|
|
27006
27188
|
});
|
|
27007
27189
|
|
|
@@ -29243,8 +29425,8 @@ function looksLikeMarkdownPath(value) {
|
|
|
29243
29425
|
const v = value.trim();
|
|
29244
29426
|
if (v.length === 0 || v.length > 4096) return false;
|
|
29245
29427
|
if (v.includes("\n") || v.includes("\r")) return false;
|
|
29246
|
-
const
|
|
29247
|
-
return
|
|
29428
|
+
const lower2 = v.toLowerCase();
|
|
29429
|
+
return lower2.endsWith(MD_EXT_MARKER) || lower2.endsWith(".markdown");
|
|
29248
29430
|
}
|
|
29249
29431
|
function isRelativeSpecifier(v) {
|
|
29250
29432
|
return v.startsWith("./") || v.startsWith("../");
|
|
@@ -31817,7 +31999,202 @@ var init_server_head = __esm({
|
|
|
31817
31999
|
}
|
|
31818
32000
|
});
|
|
31819
32001
|
|
|
32002
|
+
// ../compiler/src/server-jsx-lowering.ts
|
|
32003
|
+
function containsJsx2(node, depth = 0) {
|
|
32004
|
+
if (!node || typeof node !== "object" || depth > 40) return false;
|
|
32005
|
+
if (Array.isArray(node)) {
|
|
32006
|
+
for (const item of node) if (containsJsx2(item, depth + 1)) return true;
|
|
32007
|
+
return false;
|
|
32008
|
+
}
|
|
32009
|
+
const type = node.type;
|
|
32010
|
+
if (type === "JSXElement" || type === "JSXFragment") return true;
|
|
32011
|
+
for (const key of Object.keys(node)) {
|
|
32012
|
+
const value = node[key];
|
|
32013
|
+
if (value && typeof value === "object" && containsJsx2(value, depth + 1)) return true;
|
|
32014
|
+
}
|
|
32015
|
+
return false;
|
|
32016
|
+
}
|
|
32017
|
+
function normalizeJsxText(value) {
|
|
32018
|
+
const lines = value.split(/\r\n|\n|\r/);
|
|
32019
|
+
let lastNonEmpty = -1;
|
|
32020
|
+
for (let i = 0; i < lines.length; i++) {
|
|
32021
|
+
if (/[^ \t]/.test(lines[i])) lastNonEmpty = i;
|
|
32022
|
+
}
|
|
32023
|
+
let out = "";
|
|
32024
|
+
for (let i = 0; i < lines.length; i++) {
|
|
32025
|
+
let line = lines[i].replace(/\t/g, " ");
|
|
32026
|
+
if (i !== 0) line = line.replace(/^ +/, "");
|
|
32027
|
+
if (i !== lines.length - 1) line = line.replace(/ +$/, "");
|
|
32028
|
+
if (line) {
|
|
32029
|
+
if (i !== lastNonEmpty) line += " ";
|
|
32030
|
+
out += line;
|
|
32031
|
+
}
|
|
32032
|
+
}
|
|
32033
|
+
return out;
|
|
32034
|
+
}
|
|
32035
|
+
function lower(node, ctx2) {
|
|
32036
|
+
if (Array.isArray(node)) return node.map((n2) => lower(n2, ctx2));
|
|
32037
|
+
if (!node || typeof node !== "object") return node;
|
|
32038
|
+
const n = node;
|
|
32039
|
+
if (n.type === "JSXElement") {
|
|
32040
|
+
const opening = n.openingElement;
|
|
32041
|
+
const name = jsxTagName(opening.name);
|
|
32042
|
+
const attrs = lowerAttributes(opening.attributes, ctx2);
|
|
32043
|
+
const children = lowerChildren(n.children, ctx2);
|
|
32044
|
+
const statics = [`<${name}`, ...attrs.statics.slice(1)];
|
|
32045
|
+
statics[statics.length - 1] += ">";
|
|
32046
|
+
const quasis = [...statics, `</${name}>`];
|
|
32047
|
+
const expressions = [...attrs.exprs, ...children];
|
|
32048
|
+
return template(quasis, expressions);
|
|
32049
|
+
}
|
|
32050
|
+
if (n.type === "JSXFragment") {
|
|
32051
|
+
return template(["", ""], lowerChildren(n.children, ctx2));
|
|
32052
|
+
}
|
|
32053
|
+
const out = {};
|
|
32054
|
+
for (const key of Object.keys(n)) {
|
|
32055
|
+
if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range") {
|
|
32056
|
+
out[key] = n[key];
|
|
32057
|
+
continue;
|
|
32058
|
+
}
|
|
32059
|
+
const value = n[key];
|
|
32060
|
+
out[key] = value && typeof value === "object" ? lower(value, ctx2) : value;
|
|
32061
|
+
}
|
|
32062
|
+
return out;
|
|
32063
|
+
}
|
|
32064
|
+
function jsxTagName(nameNode) {
|
|
32065
|
+
const n = nameNode;
|
|
32066
|
+
if (!n) return "div";
|
|
32067
|
+
if (n.type === "JSXIdentifier") return String(n.name);
|
|
32068
|
+
if (n.type === "JSXMemberExpression") {
|
|
32069
|
+
const object = jsxTagName(n.object);
|
|
32070
|
+
const property = n.property;
|
|
32071
|
+
return `${object}.${String(property?.name)}`;
|
|
32072
|
+
}
|
|
32073
|
+
if (n.type === "JSXNamespacedName") {
|
|
32074
|
+
const ns = n.namespace;
|
|
32075
|
+
const name = n.name;
|
|
32076
|
+
return `${String(ns?.name)}:${String(name?.name)}`;
|
|
32077
|
+
}
|
|
32078
|
+
return "div";
|
|
32079
|
+
}
|
|
32080
|
+
function lowerAttributes(attrs, ctx2) {
|
|
32081
|
+
const statics = [""];
|
|
32082
|
+
const exprs = [];
|
|
32083
|
+
const push = (text, expr) => {
|
|
32084
|
+
if (expr === void 0) {
|
|
32085
|
+
statics[statics.length - 1] += text;
|
|
32086
|
+
return;
|
|
32087
|
+
}
|
|
32088
|
+
statics[statics.length - 1] += text;
|
|
32089
|
+
statics.push("");
|
|
32090
|
+
exprs.push(expr);
|
|
32091
|
+
};
|
|
32092
|
+
for (const attr of attrs || []) {
|
|
32093
|
+
const a = attr;
|
|
32094
|
+
if (a.type === "JSXSpreadAttribute") {
|
|
32095
|
+
console.error("[vesk] a spread attribute in a JSX expression is not supported yet (dropped):", String(a.argument ?? "").slice(0, 60));
|
|
32096
|
+
continue;
|
|
32097
|
+
}
|
|
32098
|
+
const name = jsxAttrName(a.name);
|
|
32099
|
+
const value = a.value;
|
|
32100
|
+
if (value === null || value === void 0) {
|
|
32101
|
+
push(` ${name}`);
|
|
32102
|
+
continue;
|
|
32103
|
+
}
|
|
32104
|
+
if (value.type === "StringLiteral") {
|
|
32105
|
+
push(` ${name}="${escapeAttrText(String(value.value))}"`);
|
|
32106
|
+
continue;
|
|
32107
|
+
}
|
|
32108
|
+
if (value.type === "JSXExpressionContainer") {
|
|
32109
|
+
const inner = value.expression;
|
|
32110
|
+
if (!inner || inner.type === "JSXEmptyExpression") {
|
|
32111
|
+
push(` ${name}="true"`);
|
|
32112
|
+
continue;
|
|
32113
|
+
}
|
|
32114
|
+
push(` ${name}="`, callNode(ATTR, [literal3(name), coerceString(lower(inner, ctx2))]));
|
|
32115
|
+
push('"');
|
|
32116
|
+
continue;
|
|
32117
|
+
}
|
|
32118
|
+
push(` ${name}="`, callNode(ATTR, [literal3(name), coerceString(lower(value, ctx2))]));
|
|
32119
|
+
push('"');
|
|
32120
|
+
}
|
|
32121
|
+
return { statics, exprs };
|
|
32122
|
+
}
|
|
32123
|
+
function jsxAttrName(nameNode) {
|
|
32124
|
+
const n = nameNode;
|
|
32125
|
+
if (!n) return "data";
|
|
32126
|
+
if (n.type === "JSXIdentifier") return String(n.name);
|
|
32127
|
+
return jsxTagName(n);
|
|
32128
|
+
}
|
|
32129
|
+
function lowerChildren(children, ctx2) {
|
|
32130
|
+
const out = [];
|
|
32131
|
+
for (const child of children || []) {
|
|
32132
|
+
const c = child;
|
|
32133
|
+
if (c.type === "JSXText") {
|
|
32134
|
+
const text = normalizeJsxText(String(c.value ?? ""));
|
|
32135
|
+
if (text) out.push(literal3(text));
|
|
32136
|
+
continue;
|
|
32137
|
+
}
|
|
32138
|
+
if (c.type === "JSXExpressionContainer") {
|
|
32139
|
+
const inner = c.expression;
|
|
32140
|
+
if (!inner || inner.type === "JSXEmptyExpression") continue;
|
|
32141
|
+
const lowered2 = lower(inner, ctx2);
|
|
32142
|
+
out.push(coerceString(lowered2));
|
|
32143
|
+
continue;
|
|
32144
|
+
}
|
|
32145
|
+
const lowered = lower(c, ctx2);
|
|
32146
|
+
out.push(coerceString(lowered));
|
|
32147
|
+
}
|
|
32148
|
+
return out;
|
|
32149
|
+
}
|
|
32150
|
+
function coerceString(node) {
|
|
32151
|
+
if (!node || typeof node !== "object") return callNode(ESCAPE, [literal3(String(node))]);
|
|
32152
|
+
const n = node;
|
|
32153
|
+
if (n.type === "TemplateLiteral") return n;
|
|
32154
|
+
if (n.type === "Literal" || n.type === "StringLiteral") return callNode(ESCAPE, [node]);
|
|
32155
|
+
return callNode(ESCAPE, [callNode("String", [node])]);
|
|
32156
|
+
}
|
|
32157
|
+
function template(statics, expressions) {
|
|
32158
|
+
const quasis = statics.map((raw2, i) => ({
|
|
32159
|
+
type: "TemplateElement",
|
|
32160
|
+
value: { raw: raw2 },
|
|
32161
|
+
tail: i === statics.length - 1
|
|
32162
|
+
}));
|
|
32163
|
+
return { type: "TemplateLiteral", quasis, expressions };
|
|
32164
|
+
}
|
|
32165
|
+
function literal3(value) {
|
|
32166
|
+
return { type: "Literal", value };
|
|
32167
|
+
}
|
|
32168
|
+
function callNode(callee, args2) {
|
|
32169
|
+
return {
|
|
32170
|
+
type: "CallExpression",
|
|
32171
|
+
callee: { type: "Identifier", name: callee },
|
|
32172
|
+
arguments: args2,
|
|
32173
|
+
optional: false
|
|
32174
|
+
};
|
|
32175
|
+
}
|
|
32176
|
+
function escapeAttrText(value) {
|
|
32177
|
+
return value.split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""");
|
|
32178
|
+
}
|
|
32179
|
+
function lowerJsxInExpression(ast) {
|
|
32180
|
+
if (!containsJsx2(ast)) return ast;
|
|
32181
|
+
return lower(ast, { track: false });
|
|
32182
|
+
}
|
|
32183
|
+
var ESCAPE, ATTR;
|
|
32184
|
+
var init_server_jsx_lowering = __esm({
|
|
32185
|
+
"../compiler/src/server-jsx-lowering.ts"() {
|
|
32186
|
+
"use strict";
|
|
32187
|
+
ESCAPE = "__escape";
|
|
32188
|
+
ATTR = "__attr";
|
|
32189
|
+
}
|
|
32190
|
+
});
|
|
32191
|
+
|
|
31820
32192
|
// ../compiler/src/server-jsgen.ts
|
|
32193
|
+
import { print as print6 } from "esrap";
|
|
32194
|
+
import tsPrinter from "esrap/languages/ts";
|
|
32195
|
+
function printLoweredTs(ast) {
|
|
32196
|
+
return print6(ast, tsPrinter()).code;
|
|
32197
|
+
}
|
|
31821
32198
|
function sanitizeMarkerName(name) {
|
|
31822
32199
|
return String(name).split("--").join("-").split("<").join("").split(">").join("");
|
|
31823
32200
|
}
|
|
@@ -31868,7 +32245,19 @@ function irNodeToJS(node, importedNames, isAsync = false, tracked2) {
|
|
|
31868
32245
|
`})();`
|
|
31869
32246
|
].join("\n");
|
|
31870
32247
|
}
|
|
31871
|
-
if (node instanceof RuntimeStatement)
|
|
32248
|
+
if (node instanceof RuntimeStatement) {
|
|
32249
|
+
const stmt = node;
|
|
32250
|
+
const lowered = stmt.ast ? lowerJsxInExpression(stmt.ast) : null;
|
|
32251
|
+
if (lowered && lowered !== stmt.ast && (tracked2?.size ?? 0) === 0) {
|
|
32252
|
+
return semicolonizeStatement(printLoweredTs(lowered));
|
|
32253
|
+
}
|
|
32254
|
+
if (lowered && lowered !== stmt.ast) {
|
|
32255
|
+
return semicolonizeStatement(
|
|
32256
|
+
transformTracked({ ...node, ast: lowered }, tracked2 || /* @__PURE__ */ new Map())
|
|
32257
|
+
);
|
|
32258
|
+
}
|
|
32259
|
+
return semicolonizeStatement(transformTracked(node, tracked2 || /* @__PURE__ */ new Map()));
|
|
32260
|
+
}
|
|
31872
32261
|
if (node instanceof SlotNode) {
|
|
31873
32262
|
if (__vskMarkerless) return `__out.push(props.children || '');`;
|
|
31874
32263
|
const sid = `s${nextVskId()}`;
|
|
@@ -31885,7 +32274,12 @@ function isEvent(target) {
|
|
|
31885
32274
|
return !!target && target.startsWith("on") && target.length > 2;
|
|
31886
32275
|
}
|
|
31887
32276
|
function exprJSX(node, tracked2) {
|
|
31888
|
-
|
|
32277
|
+
const lowered = node.ast ? lowerJsxInExpression(node.ast) : null;
|
|
32278
|
+
const didLower = lowered !== node.ast;
|
|
32279
|
+
if (didLower && (tracked2?.size ?? 0) === 0) {
|
|
32280
|
+
return exprJS(printLoweredTs(lowered));
|
|
32281
|
+
}
|
|
32282
|
+
return exprJS(transformTracked({ ...node, ast: lowered }, tracked2 || /* @__PURE__ */ new Map()));
|
|
31889
32283
|
}
|
|
31890
32284
|
function staticNodeToJS(node, isAsync = false, tracked2) {
|
|
31891
32285
|
const lines = [];
|
|
@@ -32033,13 +32427,13 @@ function mapRegionToJS(node, isAsync = false, tracked2) {
|
|
|
32033
32427
|
}
|
|
32034
32428
|
function keyedItemTemplate(node) {
|
|
32035
32429
|
if (!node.keyExpr) return node.bodyTemplate;
|
|
32036
|
-
const
|
|
32037
|
-
const idx =
|
|
32038
|
-
if (idx === -1) return
|
|
32039
|
-
const root3 =
|
|
32430
|
+
const template2 = node.bodyTemplate;
|
|
32431
|
+
const idx = template2.findIndex((n) => n instanceof StaticNode);
|
|
32432
|
+
if (idx === -1) return template2;
|
|
32433
|
+
const root3 = template2[idx];
|
|
32040
32434
|
const copy = new StaticNode(root3.tag, root3.attributes, [...root3.children, new DynamicBinding(node.keyExpr, "attribute", "data-vsk-key")], root3.keyExpr);
|
|
32041
32435
|
copy.selfClosing = root3.selfClosing;
|
|
32042
|
-
const out =
|
|
32436
|
+
const out = template2.slice();
|
|
32043
32437
|
out[idx] = copy;
|
|
32044
32438
|
return out;
|
|
32045
32439
|
}
|
|
@@ -32151,18 +32545,24 @@ function componentCallToJS(node, importedNames, isAsync = false, tracked2) {
|
|
|
32151
32545
|
}
|
|
32152
32546
|
}
|
|
32153
32547
|
if (regularChildren.length > 0) {
|
|
32154
|
-
const
|
|
32155
|
-
|
|
32156
|
-
|
|
32157
|
-
|
|
32158
|
-
}
|
|
32159
|
-
|
|
32160
|
-
const
|
|
32161
|
-
|
|
32162
|
-
|
|
32163
|
-
|
|
32164
|
-
|
|
32165
|
-
|
|
32548
|
+
const fnType = regularChildren.length === 1 && regularChildren[0] instanceof DynamicBinding && regularChildren[0].kind === "text" ? regularChildren[0].expression.ast?.type : null;
|
|
32549
|
+
const isFnChild = fnType === "ArrowFunctionExpression" || fnType === "FunctionExpression" || fnType === "Identifier" || fnType === "MemberExpression";
|
|
32550
|
+
if (isFnChild) {
|
|
32551
|
+
propsEntries.push(`children: ${exprJSX(regularChildren[0].expression, tracked2)}`);
|
|
32552
|
+
} else {
|
|
32553
|
+
const childLines = [];
|
|
32554
|
+
for (const child of regularChildren) {
|
|
32555
|
+
const code = irNodeToJS(child, importedNames, isAsync, tracked2);
|
|
32556
|
+
if (code) childLines.push(code);
|
|
32557
|
+
}
|
|
32558
|
+
if (childLines.length > 0) {
|
|
32559
|
+
const childrenVar = `__ch${nextVskId()}`;
|
|
32560
|
+
propsEntries.push(`children: ${childrenVar}`);
|
|
32561
|
+
lines.push(`const ${childrenVar} = ${isAsync ? "await (async " : "("}() => {`);
|
|
32562
|
+
lines.push(`const __out = [];`);
|
|
32563
|
+
lines.push(indent(childLines.join("\n")));
|
|
32564
|
+
lines.push(`return __out.join(''); })();`);
|
|
32565
|
+
}
|
|
32166
32566
|
}
|
|
32167
32567
|
}
|
|
32168
32568
|
const propsObj = `{ ${propsEntries.join(", ")} }`;
|
|
@@ -32179,9 +32579,9 @@ function componentCallToJS(node, importedNames, isAsync = false, tracked2) {
|
|
|
32179
32579
|
}
|
|
32180
32580
|
const callExpr3 = `${awaitKw}${calleeVar}(${propsObj}, __registry, (${calleeVar}.__veskScope || __vesk))`;
|
|
32181
32581
|
if (__vskHydrate && !__vskMarkerless) {
|
|
32182
|
-
lines.push(`__out.push(${JSON.stringify(componentMarker(compName))} + (${callExpr3}
|
|
32582
|
+
lines.push(`__out.push(${JSON.stringify(componentMarker(compName))} + __flat(${callExpr3}));`);
|
|
32183
32583
|
} else {
|
|
32184
|
-
lines.push(`__out.push(${callExpr3}
|
|
32584
|
+
lines.push(`__out.push(__flat(${callExpr3}));`);
|
|
32185
32585
|
}
|
|
32186
32586
|
return lines.join("\n");
|
|
32187
32587
|
}
|
|
@@ -32199,6 +32599,7 @@ function generateFunctionBody(comp, importedNames) {
|
|
|
32199
32599
|
lines.push(`const __styleText = (v) => { if (typeof v === 'string') return v; if (v && typeof v === 'object') { let s = ''; for (const k in v) { const x = v[k]; if (x == null || x === false) continue; s += k.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase()) + ':' + x + ';'; } return s; } return String(v); };`);
|
|
32200
32600
|
lines.push(`const __attr = (n, v) => (v == null || v === false) ? '' : ' ' + n + '="' + __escape(n === 'style' ? __styleText(v) : String(v)) + '"';`);
|
|
32201
32601
|
lines.push(`const raw = (s) => s == null ? '' : String(s);`);
|
|
32602
|
+
lines.push(`const __flat = (v) => Array.isArray(v) ? v.join('') : (v == null ? '' : String(v));`);
|
|
32202
32603
|
lines.push(`const __tk = globalThis.__vsk_ssr_token || '';`);
|
|
32203
32604
|
if (asyncMode) {
|
|
32204
32605
|
lines.push(`const __pk = __tk ? '__vsk_ssr_promises_' + __tk : '__vsk_ssr_promises';`);
|
|
@@ -32235,6 +32636,64 @@ function generateFunctionBody(comp, importedNames) {
|
|
|
32235
32636
|
__currentCompName = "";
|
|
32236
32637
|
return lines.join("\n");
|
|
32237
32638
|
}
|
|
32639
|
+
function bodyNeedsRuntimeCells(nodes) {
|
|
32640
|
+
for (const node of nodes) {
|
|
32641
|
+
if (node instanceof TrackDecl) return true;
|
|
32642
|
+
if (node instanceof RuntimeStatement && callsIdentifier(node.raw, "track")) return true;
|
|
32643
|
+
if (node instanceof Expression && callsIdentifier(node.raw, "track")) return true;
|
|
32644
|
+
if (node instanceof ForLoop) {
|
|
32645
|
+
if (callsIdentifier(node.init, "track")) return true;
|
|
32646
|
+
if (callsIdentifier(node.update, "track")) return true;
|
|
32647
|
+
if (callsIdentifier(node.condition.raw, "track")) return true;
|
|
32648
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate)) return true;
|
|
32649
|
+
}
|
|
32650
|
+
if (node instanceof StaticNode) {
|
|
32651
|
+
for (const attr of node.attributes) {
|
|
32652
|
+
if (callsIdentifier(attr.value, "track")) return true;
|
|
32653
|
+
}
|
|
32654
|
+
if (bodyNeedsRuntimeCells(node.children)) return true;
|
|
32655
|
+
}
|
|
32656
|
+
if (node instanceof ComponentCall) {
|
|
32657
|
+
for (const prop of node.props) {
|
|
32658
|
+
if (callsIdentifier(prop.value.raw, "track")) return true;
|
|
32659
|
+
}
|
|
32660
|
+
for (const spread of node.spreadProps) {
|
|
32661
|
+
if (callsIdentifier(spread.raw, "track")) return true;
|
|
32662
|
+
}
|
|
32663
|
+
if (bodyNeedsRuntimeCells(node.children)) return true;
|
|
32664
|
+
}
|
|
32665
|
+
if (node instanceof ServerBlock || node instanceof ClientBlock || node instanceof HeadBlock) {
|
|
32666
|
+
if (bodyNeedsRuntimeCells(node.children)) return true;
|
|
32667
|
+
}
|
|
32668
|
+
if (node instanceof PropSlot && bodyNeedsRuntimeCells(node.body)) return true;
|
|
32669
|
+
if (node instanceof MapRegion) {
|
|
32670
|
+
if (callsIdentifier(node.expression.raw, "track")) return true;
|
|
32671
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate)) return true;
|
|
32672
|
+
if (bodyNeedsRuntimeCells(node.alternateNodes)) return true;
|
|
32673
|
+
}
|
|
32674
|
+
if (node instanceof OpaqueDynamicRegion) {
|
|
32675
|
+
if (callsIdentifier(node.condition.raw, "track")) return true;
|
|
32676
|
+
if (bodyNeedsRuntimeCells(node.consequentNodes)) return true;
|
|
32677
|
+
if (bodyNeedsRuntimeCells(node.alternateNodes)) return true;
|
|
32678
|
+
}
|
|
32679
|
+
if (node instanceof WhileLoop) {
|
|
32680
|
+
if (callsIdentifier(node.condition.raw, "track")) return true;
|
|
32681
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate)) return true;
|
|
32682
|
+
}
|
|
32683
|
+
if (node instanceof SwitchBlock) {
|
|
32684
|
+
if (callsIdentifier(node.discriminant.raw, "track")) return true;
|
|
32685
|
+
for (const c of node.cases) {
|
|
32686
|
+
if (c.test && callsIdentifier(c.test.raw, "track")) return true;
|
|
32687
|
+
if (bodyNeedsRuntimeCells(c.body)) return true;
|
|
32688
|
+
}
|
|
32689
|
+
}
|
|
32690
|
+
if (node instanceof TryCatch) {
|
|
32691
|
+
if (bodyNeedsRuntimeCells(node.bodyTemplate)) return true;
|
|
32692
|
+
if (bodyNeedsRuntimeCells(node.catchBody)) return true;
|
|
32693
|
+
}
|
|
32694
|
+
}
|
|
32695
|
+
return false;
|
|
32696
|
+
}
|
|
32238
32697
|
function buildComponentEntries(irRoot) {
|
|
32239
32698
|
const runtimeNames = extractRuntimeNames(irRoot.imports);
|
|
32240
32699
|
const localValueNames = localValueImportNames(irRoot.imports);
|
|
@@ -32242,7 +32701,7 @@ function buildComponentEntries(irRoot) {
|
|
|
32242
32701
|
const componentNames = new Set(irRoot.components.map((c) => c.name));
|
|
32243
32702
|
const topValueNames = topNames.filter((n) => !componentNames.has(n));
|
|
32244
32703
|
const importedNames = /* @__PURE__ */ new Set([...runtimeNames, ...localValueNames, ...topValueNames]);
|
|
32245
|
-
const hasTracked = irRoot.components.some((c) => c.body
|
|
32704
|
+
const hasTracked = irRoot.components.some((c) => bodyNeedsRuntimeCells(c.body));
|
|
32246
32705
|
const extraNames = hasTracked ? ["get", "set", "track"] : [];
|
|
32247
32706
|
const vskValueNames = vskImportValueNames(irRoot.imports);
|
|
32248
32707
|
const allNames = [.../* @__PURE__ */ new Set([...runtimeNames, ...topNames, ...extraNames, ...localValueNames, ...vskValueNames])];
|
|
@@ -32286,6 +32745,7 @@ var init_server_jsgen = __esm({
|
|
|
32286
32745
|
init_scan();
|
|
32287
32746
|
init_server_utils();
|
|
32288
32747
|
init_module_imports();
|
|
32748
|
+
init_server_jsx_lowering();
|
|
32289
32749
|
init_vsk_imports();
|
|
32290
32750
|
__currentCompName = "";
|
|
32291
32751
|
}
|
|
@@ -33050,8 +33510,8 @@ function installMdReadHook(publicDirs) {
|
|
|
33050
33510
|
while (rel.length > 0 && rel.charCodeAt(0) === 47) rel = rel.slice(1);
|
|
33051
33511
|
const abs = resolveWithin(dir, rel);
|
|
33052
33512
|
if (!abs) continue;
|
|
33053
|
-
const
|
|
33054
|
-
if (!
|
|
33513
|
+
const lower2 = abs.toLowerCase();
|
|
33514
|
+
if (!lower2.endsWith(".md") && !lower2.endsWith(".markdown")) continue;
|
|
33055
33515
|
if (existsSync12(abs) && statSync4(abs).isFile()) return readFileSync12(abs, "utf8");
|
|
33056
33516
|
} catch {
|
|
33057
33517
|
}
|
|
@@ -37478,8 +37938,8 @@ function isPublicMarkdownPath2(v) {
|
|
|
37478
37938
|
if (c === 63 || c === 35 || c === 92)
|
|
37479
37939
|
return false;
|
|
37480
37940
|
}
|
|
37481
|
-
const
|
|
37482
|
-
return stringEndsWith2(
|
|
37941
|
+
const lower2 = s.toLowerCase();
|
|
37942
|
+
return stringEndsWith2(lower2, ".md") || stringEndsWith2(lower2, ".markdown");
|
|
37483
37943
|
}
|
|
37484
37944
|
function getMdPathCell2(path) {
|
|
37485
37945
|
let cell = mdPathCells2.get(path);
|
|
@@ -38219,7 +38679,10 @@ var init_errors2 = __esm({
|
|
|
38219
38679
|
suggestions;
|
|
38220
38680
|
nextSteps;
|
|
38221
38681
|
tip;
|
|
38682
|
+
/** The V-diagnostic code, e.g. `V0501`. */
|
|
38222
38683
|
code;
|
|
38684
|
+
/** The rendered code frame. Used to be written into `code`, which silently replaced the V-code. */
|
|
38685
|
+
frame;
|
|
38223
38686
|
constructor(message, opts = {}) {
|
|
38224
38687
|
super(message);
|
|
38225
38688
|
this.name = "VeskError";
|
|
@@ -38229,8 +38692,10 @@ var init_errors2 = __esm({
|
|
|
38229
38692
|
this.suggestions = opts.suggestions || [];
|
|
38230
38693
|
this.nextSteps = opts.nextSteps || [];
|
|
38231
38694
|
this.tip = opts.tip || "";
|
|
38232
|
-
if (opts.code !== void 0)
|
|
38695
|
+
if (opts.code !== void 0 && !opts.code.includes("\n"))
|
|
38233
38696
|
this.code = opts.code;
|
|
38697
|
+
if (opts.frame !== void 0)
|
|
38698
|
+
this.frame = opts.frame;
|
|
38234
38699
|
}
|
|
38235
38700
|
static notFound(name, candidates = [], context = {}) {
|
|
38236
38701
|
const allCandidates = [.../* @__PURE__ */ new Set([...candidates, ...VESK_BUILTINS2])];
|
|
@@ -38303,6 +38768,75 @@ var init_errors2 = __esm({
|
|
|
38303
38768
|
tip: "Use plain objects for data and factory functions for constructors inside .vsk files."
|
|
38304
38769
|
});
|
|
38305
38770
|
}
|
|
38771
|
+
/**
|
|
38772
|
+
* A browser-only global used in code the SERVER evaluates.
|
|
38773
|
+
*
|
|
38774
|
+
* On the server these are either absent (`window is not defined`) or, worse,
|
|
38775
|
+
* silently present-but-wrong (`navigator` exists in modern Node, so
|
|
38776
|
+
* `navigator.onLine` is `undefined` and a page renders as if it were offline).
|
|
38777
|
+
* A raw `ReferenceError` at request time is the worst possible report: it
|
|
38778
|
+
* names neither the component nor the fix. This points at the line.
|
|
38779
|
+
*/
|
|
38780
|
+
static ssrUnsafeGlobal(name, context = {}) {
|
|
38781
|
+
return new _VeskError(`\`${name}\` is browser-only, and this component body runs during SSR.`, {
|
|
38782
|
+
...context,
|
|
38783
|
+
code: context.code || "V0501",
|
|
38784
|
+
suggestions: [
|
|
38785
|
+
`Wrap the part that needs the DOM in a {#client} block.`,
|
|
38786
|
+
`Move the code into an event handler \u2014 handlers never run on the server.`,
|
|
38787
|
+
`Do the setup in on_destroy(), which the compiler only emits on the client.`
|
|
38788
|
+
],
|
|
38789
|
+
nextSteps: [
|
|
38790
|
+
`component ${context.inComponent ?? "this component"}: wrap the \`${name}\` access in {#client}...{/client}.`,
|
|
38791
|
+
`Or guard it: if (typeof ${name} !== 'undefined') { ... }`
|
|
38792
|
+
],
|
|
38793
|
+
tip: "SSR renders this component before the client exists. Reading a browser global here either throws during the request or (for `navigator`) silently returns undefined."
|
|
38794
|
+
});
|
|
38795
|
+
}
|
|
38796
|
+
/**
|
|
38797
|
+
* The second name from `track()` called as a function.
|
|
38798
|
+
*
|
|
38799
|
+
* `const &[count, setCount] = track(0)` returns a CELL, not a setter function, so
|
|
38800
|
+
* `setCount(1)` throws `setCount is not a function` from generated code with
|
|
38801
|
+
* no line of user code in the message. The cell is the writer: `.set(v)`.
|
|
38802
|
+
*/
|
|
38803
|
+
static cellCalledAsFunction(name, context = {}) {
|
|
38804
|
+
return new _VeskError(`\`${name}\` is a cell, not a function \u2014 cells are written with \`.set()\`.`, {
|
|
38805
|
+
...context,
|
|
38806
|
+
code: context.code || "V0502",
|
|
38807
|
+
suggestions: [
|
|
38808
|
+
`Use \`${name}.set(...)\` instead of \`${name}(...)\`.`,
|
|
38809
|
+
`Or use the tracked spelling inside an event handler: set(${context.value ?? "value"}, ...)`
|
|
38810
|
+
],
|
|
38811
|
+
nextSteps: [
|
|
38812
|
+
`const &[${context.value ?? "value"}, ${name}] = track(0) \u2192 \`${name}.set(v)\``,
|
|
38813
|
+
"The value read in markup is the first name; the second is the cell object."
|
|
38814
|
+
],
|
|
38815
|
+
tip: `\`track()\` returns [value, cell]. \`${name}\` is the cell half.`
|
|
38816
|
+
});
|
|
38817
|
+
}
|
|
38818
|
+
/**
|
|
38819
|
+
* `set(value, …)` used outside a rewritten expression.
|
|
38820
|
+
*
|
|
38821
|
+
* The compiler rewrites `set(count, v)` to `countCell.set(v)` inside JSX and
|
|
38822
|
+
* event handlers — but a bare statement in the component body is NOT
|
|
38823
|
+
* rewritten, so the runtime `set` receives the value and throws
|
|
38824
|
+
* "Cannot read properties of undefined". Pass the CELL, not the value.
|
|
38825
|
+
*/
|
|
38826
|
+
static setWithValueName(name, context = {}) {
|
|
38827
|
+
return new _VeskError(`\`set(${name}, \u2026)\` needs the CELL, and \`${name}\` is the value half of track().`, {
|
|
38828
|
+
...context,
|
|
38829
|
+
code: context.code || "V0503",
|
|
38830
|
+
suggestions: [
|
|
38831
|
+
`Use \`set(${context.cell ?? "cell"}, \u2026)\` or \`${context.cell ?? "cell"}.set(\u2026)\`.`,
|
|
38832
|
+
`Or move the set() into an event handler, where the compiler rewrites it for you.`
|
|
38833
|
+
],
|
|
38834
|
+
nextSteps: [
|
|
38835
|
+
`const &[${name}, ${context.cell ?? "cell"}] = track(0) \u2192 \`${context.cell ?? "cell"}.set(v)\``
|
|
38836
|
+
],
|
|
38837
|
+
tip: "set(cell, value) is only rewritten inside JSX and handlers; in a body statement it reaches the runtime untouched."
|
|
38838
|
+
});
|
|
38839
|
+
}
|
|
38306
38840
|
static serverBlockInClient(compName, context = {}) {
|
|
38307
38841
|
return new _VeskError(`{#server} block found in client island "${compName}". Client islands render on both server and client, so {#server} blocks have no effect.`, {
|
|
38308
38842
|
...context,
|
|
@@ -50051,7 +50585,7 @@ import { WebSocketServer as WebSocketServer2 } from "ws";
|
|
|
50051
50585
|
// ../compiler/dist/strip-ts.js
|
|
50052
50586
|
init_parser();
|
|
50053
50587
|
import { walk as walk6 } from "zimmerframe";
|
|
50054
|
-
import { print as
|
|
50588
|
+
import { print as print7 } from "esrap";
|
|
50055
50589
|
import ts6 from "esrap/languages/ts";
|
|
50056
50590
|
var TS_NODE_TYPES2 = /* @__PURE__ */ new Set([
|
|
50057
50591
|
"TSAsExpression",
|
|
@@ -50248,7 +50782,7 @@ function stripCodeTypes2(code) {
|
|
|
50248
50782
|
stripped.body = stripped.body.filter((n) => !isTypeOnlyStatement2(n));
|
|
50249
50783
|
}
|
|
50250
50784
|
try {
|
|
50251
|
-
return
|
|
50785
|
+
return print7(stripped, ts6()).code;
|
|
50252
50786
|
} catch {
|
|
50253
50787
|
return code;
|
|
50254
50788
|
}
|
|
@@ -50387,7 +50921,7 @@ init_vsk_imports();
|
|
|
50387
50921
|
init_md_inline();
|
|
50388
50922
|
init_strip_ts();
|
|
50389
50923
|
import { walk as walk7 } from "zimmerframe";
|
|
50390
|
-
import { print as
|
|
50924
|
+
import { print as print8 } from "esrap";
|
|
50391
50925
|
import ts7 from "esrap/languages/ts";
|
|
50392
50926
|
import tsx2 from "esrap/languages/tsx";
|
|
50393
50927
|
function callExpr2(callee, args2 = []) {
|
|
@@ -50454,12 +50988,12 @@ function semicolonizeStatement2(code) {
|
|
|
50454
50988
|
return code;
|
|
50455
50989
|
return code + ";";
|
|
50456
50990
|
}
|
|
50457
|
-
function
|
|
50991
|
+
function containsJsx3(node, depth = 0) {
|
|
50458
50992
|
if (!node || typeof node !== "object" || depth > 40)
|
|
50459
50993
|
return false;
|
|
50460
50994
|
if (Array.isArray(node)) {
|
|
50461
50995
|
for (const item of node) {
|
|
50462
|
-
if (
|
|
50996
|
+
if (containsJsx3(item, depth + 1))
|
|
50463
50997
|
return true;
|
|
50464
50998
|
}
|
|
50465
50999
|
return false;
|
|
@@ -50468,13 +51002,13 @@ function containsJsx2(node, depth = 0) {
|
|
|
50468
51002
|
return true;
|
|
50469
51003
|
for (const key of Object.keys(node)) {
|
|
50470
51004
|
const v = node[key];
|
|
50471
|
-
if (v && typeof v === "object" &&
|
|
51005
|
+
if (v && typeof v === "object" && containsJsx3(v, depth + 1))
|
|
50472
51006
|
return true;
|
|
50473
51007
|
}
|
|
50474
51008
|
return false;
|
|
50475
51009
|
}
|
|
50476
51010
|
function printAst2(ast) {
|
|
50477
|
-
return
|
|
51011
|
+
return print8(ast, containsJsx3(ast) ? tsx2() : ts7()).code;
|
|
50478
51012
|
}
|
|
50479
51013
|
function effectBlockToHandlerExpr2(eff) {
|
|
50480
51014
|
try {
|
|
@@ -50595,7 +51129,7 @@ function transformTracked2(irNode, tracked2) {
|
|
|
50595
51129
|
return context.next();
|
|
50596
51130
|
}
|
|
50597
51131
|
});
|
|
50598
|
-
return
|
|
51132
|
+
return print8(transformed, containsJsx3(transformed) ? tsx2() : ts7()).code;
|
|
50599
51133
|
}
|
|
50600
51134
|
function collectTrackedNames2(body) {
|
|
50601
51135
|
const names = /* @__PURE__ */ new Map();
|
|
@@ -53730,8 +54264,8 @@ function looksLikeMarkdownPath2(value) {
|
|
|
53730
54264
|
return false;
|
|
53731
54265
|
if (v.includes("\n") || v.includes("\r"))
|
|
53732
54266
|
return false;
|
|
53733
|
-
const
|
|
53734
|
-
return
|
|
54267
|
+
const lower2 = v.toLowerCase();
|
|
54268
|
+
return lower2.endsWith(MD_EXT_MARKER2) || lower2.endsWith(".markdown");
|
|
53735
54269
|
}
|
|
53736
54270
|
function isRelativeSpecifier2(v) {
|
|
53737
54271
|
return v.startsWith("./") || v.startsWith("../");
|
|
@@ -54937,8 +55471,8 @@ function installMdReadHook2(publicDirs) {
|
|
|
54937
55471
|
const abs = resolveWithin2(dir, rel);
|
|
54938
55472
|
if (!abs)
|
|
54939
55473
|
continue;
|
|
54940
|
-
const
|
|
54941
|
-
if (!
|
|
55474
|
+
const lower2 = abs.toLowerCase();
|
|
55475
|
+
if (!lower2.endsWith(".md") && !lower2.endsWith(".markdown"))
|
|
54942
55476
|
continue;
|
|
54943
55477
|
if (existsSync29(abs) && statSync15(abs).isFile())
|
|
54944
55478
|
return readFileSync25(abs, "utf8");
|
|
@@ -62809,6 +63343,7 @@ __export(index_server_exports2, {
|
|
|
62809
63343
|
get: () => get,
|
|
62810
63344
|
getAction: () => getAction,
|
|
62811
63345
|
getActiveComponent: () => getActiveComponent,
|
|
63346
|
+
getIn: () => getIn,
|
|
62812
63347
|
getLoadingError: () => getLoadingError,
|
|
62813
63348
|
getLoadingProgress: () => getLoadingProgress,
|
|
62814
63349
|
getServerContext: () => getServerContext,
|
|
@@ -62862,6 +63397,7 @@ __export(index_server_exports2, {
|
|
|
62862
63397
|
server_locals: () => server_locals,
|
|
62863
63398
|
set: () => set,
|
|
62864
63399
|
setActiveComponent: () => setActiveComponent,
|
|
63400
|
+
setIn: () => setIn,
|
|
62865
63401
|
setServerContext: () => setServerContext,
|
|
62866
63402
|
setSignedCookie: () => setSignedCookie2,
|
|
62867
63403
|
setSsrData: () => setSsrData,
|
|
@@ -62876,6 +63412,7 @@ __export(index_server_exports2, {
|
|
|
62876
63412
|
unlink_block: () => unlink_block,
|
|
62877
63413
|
unsignCookie: () => unsignCookie2,
|
|
62878
63414
|
untrack: () => untrack2,
|
|
63415
|
+
updateIn: () => updateIn,
|
|
62879
63416
|
useBody: () => useBody,
|
|
62880
63417
|
useFetch: () => useFetch,
|
|
62881
63418
|
useLoadingIndicator: () => useLoadingIndicator,
|
|
@@ -62911,6 +63448,7 @@ init_primitive();
|
|
|
62911
63448
|
init_loading_indicator();
|
|
62912
63449
|
init_action();
|
|
62913
63450
|
init_metadata();
|
|
63451
|
+
init_nested_update();
|
|
62914
63452
|
|
|
62915
63453
|
// src/index.ts
|
|
62916
63454
|
var __filename2 = fileURLToPath9(import.meta.url);
|
|
@@ -63056,12 +63594,14 @@ if (cmd === "build") {
|
|
|
63056
63594
|
const l = err.line;
|
|
63057
63595
|
const c = err.column;
|
|
63058
63596
|
const code = err.code;
|
|
63597
|
+
const frame = err.frame;
|
|
63059
63598
|
let out = `vesk build: error \u2014 ${err.message}`;
|
|
63599
|
+
if (code) out = `vesk build: [${code}] ${err.message}`;
|
|
63060
63600
|
if (f) out += `
|
|
63061
63601
|
File: ${f}${l ? `:${l}${c ? `:${c}` : ""}` : ""}`;
|
|
63062
|
-
if (
|
|
63602
|
+
if (frame) out += `
|
|
63063
63603
|
|
|
63064
|
-
${
|
|
63604
|
+
${frame}`;
|
|
63065
63605
|
console.error(out);
|
|
63066
63606
|
if (err.stack && !String(err.stack).includes(err.message)) console.error(err.stack);
|
|
63067
63607
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/vesk-cli",
|
|
3
|
-
"version": "0.2.50
|
|
3
|
+
"version": "0.2.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk — compiler-first framework for the post-VDOM web. vesk dev, vesk build.",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/cli.js",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@vesk/adapter": "^0.2.50
|
|
12
|
-
"@vesk/compiler": "^0.2.50
|
|
13
|
-
"@vesk/plugin-tailwind": "^0.2.50
|
|
14
|
-
"@vesk/runtime": "^0.2.50
|
|
11
|
+
"@vesk/adapter": "^0.2.50",
|
|
12
|
+
"@vesk/compiler": "^0.2.50",
|
|
13
|
+
"@vesk/plugin-tailwind": "^0.2.50",
|
|
14
|
+
"@vesk/runtime": "^0.2.50",
|
|
15
15
|
"esrap": "^2.3.0",
|
|
16
16
|
"typescript": "^5.8.0",
|
|
17
17
|
"ws": "^8.18.0",
|