@statorjs/language-server 0.1.16 → 0.1.18
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/server.cjs +208 -109
- package/package.json +2 -2
package/dist/server.cjs
CHANGED
|
@@ -44177,50 +44177,14 @@ var import_volar_service_typescript = __toESM(require_volar_service_typescript()
|
|
|
44177
44177
|
// ../stator/src/compiler/client-emit.ts
|
|
44178
44178
|
var import_typescript = __toESM(require("typescript"), 1);
|
|
44179
44179
|
|
|
44180
|
-
// ../stator/src/
|
|
44181
|
-
var
|
|
44182
|
-
|
|
44183
|
-
|
|
44184
|
-
|
|
44185
|
-
this.name = "CompileError";
|
|
44186
|
-
this.loc = loc2;
|
|
44187
|
-
}
|
|
44188
|
-
};
|
|
44189
|
-
function offsetToLineCol(source, offset) {
|
|
44190
|
-
const clamped = Math.max(0, Math.min(offset, source.length));
|
|
44191
|
-
let line = 1;
|
|
44192
|
-
let lastNewline = -1;
|
|
44193
|
-
for (let i = 0; i < clamped; i++) {
|
|
44194
|
-
if (source.charCodeAt(i) === 10) {
|
|
44195
|
-
line++;
|
|
44196
|
-
lastNewline = i;
|
|
44197
|
-
}
|
|
44198
|
-
}
|
|
44199
|
-
return { line, column: clamped - lastNewline };
|
|
44200
|
-
}
|
|
44201
|
-
function codeFrame(source, line, column) {
|
|
44202
|
-
const lines = source.split("\n");
|
|
44203
|
-
const start = Math.max(1, line - 1);
|
|
44204
|
-
const end = Math.min(lines.length, line + 1);
|
|
44205
|
-
const gutterWidth = String(end).length;
|
|
44206
|
-
const out = [];
|
|
44207
|
-
for (let n = start; n <= end; n++) {
|
|
44208
|
-
const gutter = String(n).padStart(gutterWidth);
|
|
44209
|
-
const marker = n === line ? ">" : " ";
|
|
44210
|
-
out.push(`${marker} ${gutter} | ${lines[n - 1] ?? ""}`);
|
|
44211
|
-
if (n === line) {
|
|
44212
|
-
out.push(` ${" ".repeat(gutterWidth)} | ${" ".repeat(Math.max(0, column - 1))}^`);
|
|
44213
|
-
}
|
|
44214
|
-
}
|
|
44215
|
-
return out.join("\n");
|
|
44216
|
-
}
|
|
44217
|
-
function locAt(source, offset, file) {
|
|
44218
|
-
const { line, column } = offsetToLineCol(source, offset);
|
|
44219
|
-
return { file, line, column, frame: codeFrame(source, line, column) };
|
|
44220
|
-
}
|
|
44180
|
+
// ../stator/src/wire/island-markers.ts
|
|
44181
|
+
var ISLAND_MARKER_ATTR = "data-b";
|
|
44182
|
+
var elementMarker = (i) => `b${i}`;
|
|
44183
|
+
var slotMarker = (i) => `s${i}`;
|
|
44184
|
+
var elementMarkerSelector = (marker) => `[${ISLAND_MARKER_ATTR}="${marker}"]`;
|
|
44221
44185
|
|
|
44222
44186
|
// ../stator/src/compiler/client-emit.ts
|
|
44223
|
-
var PRIMITIVES = "import { StatorElement, defineElement, use, machine, bind, effect, dispatch } from '@statorjs/stator/client'";
|
|
44187
|
+
var PRIMITIVES = "import { StatorElement, defineElement, use, machine, bind, bindSlot, effect, dispatch, attrValue, setAttr } from '@statorjs/stator/client'";
|
|
44224
44188
|
function emitClientModule(input) {
|
|
44225
44189
|
const { script, element, directives, members } = input;
|
|
44226
44190
|
const impl = `__${element.className}Impl`;
|
|
@@ -44233,9 +44197,18 @@ function emitClientModule(input) {
|
|
|
44233
44197
|
const lines = [];
|
|
44234
44198
|
let i = 0;
|
|
44235
44199
|
for (const [marker, group] of byMarker) {
|
|
44200
|
+
if (group[0]?.kind === "slot") {
|
|
44201
|
+
for (const d of group) {
|
|
44202
|
+
const thunk = `() => (${rewriteMembers(d.expr, members)})`;
|
|
44203
|
+
const deps = `[${d.deps.map((dep) => `this.${dep}`).join(", ")}]`;
|
|
44204
|
+
lines.push(` this.track(bindSlot(this, ${JSON.stringify(marker)}, ${deps}, ${thunk}))`);
|
|
44205
|
+
}
|
|
44206
|
+
continue;
|
|
44207
|
+
}
|
|
44236
44208
|
const node = `n${i++}`;
|
|
44237
|
-
lines.push(
|
|
44238
|
-
|
|
44209
|
+
lines.push(
|
|
44210
|
+
` for (const ${node} of this.querySelectorAll(${JSON.stringify(elementMarkerSelector(marker))})) {`
|
|
44211
|
+
);
|
|
44239
44212
|
for (const d of group) lines.push(` ${wireDirective(node, d, members)}`);
|
|
44240
44213
|
lines.push(" }");
|
|
44241
44214
|
}
|
|
@@ -44261,27 +44234,9 @@ function wireDirective(node, d, members) {
|
|
|
44261
44234
|
const target = d.target ?? "text";
|
|
44262
44235
|
const thunk = `() => (${rewriteMembers(d.expr, members)})`;
|
|
44263
44236
|
const deps = `[${d.deps.map((dep) => `this.${dep}`).join(", ")}]`;
|
|
44264
|
-
if (target === "value" || target === "checked") {
|
|
44265
|
-
const path = parseTwoWayPath(d.expr);
|
|
44266
|
-
if (!path) {
|
|
44267
|
-
throw new CompileError(
|
|
44268
|
-
`stator: bind:${target}={${d.expr}} must bind to a settable context path like \`actor.key\` (a derived value can't be two-way bound).`
|
|
44269
|
-
);
|
|
44270
|
-
}
|
|
44271
|
-
const writer2 = emitWriter(node, target);
|
|
44272
|
-
const read = target === "checked" ? `${node}.checked` : `${node}.value`;
|
|
44273
|
-
const guard = target === "value" ? `if (e.isComposing) return; ` : "";
|
|
44274
|
-
const setter = `${node}.addEventListener(${JSON.stringify(target === "value" ? "input" : "change")}, (e) => { ${guard}this.${path.actor}.send({ type: '@set', key: ${JSON.stringify(path.key)}, value: ${read} }) })`;
|
|
44275
|
-
return `this.track(bind(${deps}, ${thunk}, ${writer2}));
|
|
44276
|
-
${setter}`;
|
|
44277
|
-
}
|
|
44278
44237
|
const writer = emitWriter(node, target);
|
|
44279
44238
|
return `this.track(bind(${deps}, ${thunk}, ${writer}))`;
|
|
44280
44239
|
}
|
|
44281
|
-
function parseTwoWayPath(expr) {
|
|
44282
|
-
const m = expr.trim().match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
|
|
44283
|
-
return m ? { actor: m[1], key: m[2] } : null;
|
|
44284
|
-
}
|
|
44285
44240
|
function emitHandler(expr, members) {
|
|
44286
44241
|
const t = expr.trim();
|
|
44287
44242
|
if (/^[A-Za-z_$][\w$]*$/.test(t) && members.has(t)) {
|
|
@@ -44291,18 +44246,11 @@ function emitHandler(expr, members) {
|
|
|
44291
44246
|
}
|
|
44292
44247
|
function emitWriter(node, target) {
|
|
44293
44248
|
switch (target) {
|
|
44294
|
-
case "text":
|
|
44295
|
-
return `(v) => { ${node}.textContent = v == null ? '' : String(v) }`;
|
|
44296
|
-
case "html":
|
|
44297
|
-
return `(v) => { ${node}.innerHTML = v == null ? '' : String(v) }`;
|
|
44298
|
-
case "value":
|
|
44299
|
-
return `(v) => { const s = v == null ? '' : String(v); if (${node}.value !== s) ${node}.value = s }`;
|
|
44300
44249
|
case "disabled":
|
|
44301
44250
|
case "hidden":
|
|
44302
|
-
case "checked":
|
|
44303
44251
|
return `(v) => { if (${node}.${target} !== !!v) ${node}.${target} = !!v }`;
|
|
44304
44252
|
default:
|
|
44305
|
-
return `(v) =>
|
|
44253
|
+
return `(v) => setAttr(${node}, ${JSON.stringify(target)}, attrValue(v))`;
|
|
44306
44254
|
}
|
|
44307
44255
|
}
|
|
44308
44256
|
function stripClientPrimitiveImports(script) {
|
|
@@ -44341,6 +44289,50 @@ function rewriteMembers(expr, members) {
|
|
|
44341
44289
|
|
|
44342
44290
|
// ../stator/src/compiler/client-script.ts
|
|
44343
44291
|
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
44292
|
+
|
|
44293
|
+
// ../stator/src/compiler/diagnostics.ts
|
|
44294
|
+
var CompileError = class extends Error {
|
|
44295
|
+
loc;
|
|
44296
|
+
constructor(message, loc2) {
|
|
44297
|
+
super(message);
|
|
44298
|
+
this.name = "CompileError";
|
|
44299
|
+
this.loc = loc2;
|
|
44300
|
+
}
|
|
44301
|
+
};
|
|
44302
|
+
function offsetToLineCol(source, offset) {
|
|
44303
|
+
const clamped = Math.max(0, Math.min(offset, source.length));
|
|
44304
|
+
let line = 1;
|
|
44305
|
+
let lastNewline = -1;
|
|
44306
|
+
for (let i = 0; i < clamped; i++) {
|
|
44307
|
+
if (source.charCodeAt(i) === 10) {
|
|
44308
|
+
line++;
|
|
44309
|
+
lastNewline = i;
|
|
44310
|
+
}
|
|
44311
|
+
}
|
|
44312
|
+
return { line, column: clamped - lastNewline };
|
|
44313
|
+
}
|
|
44314
|
+
function codeFrame(source, line, column) {
|
|
44315
|
+
const lines = source.split("\n");
|
|
44316
|
+
const start = Math.max(1, line - 1);
|
|
44317
|
+
const end = Math.min(lines.length, line + 1);
|
|
44318
|
+
const gutterWidth = String(end).length;
|
|
44319
|
+
const out = [];
|
|
44320
|
+
for (let n = start; n <= end; n++) {
|
|
44321
|
+
const gutter = String(n).padStart(gutterWidth);
|
|
44322
|
+
const marker = n === line ? ">" : " ";
|
|
44323
|
+
out.push(`${marker} ${gutter} | ${lines[n - 1] ?? ""}`);
|
|
44324
|
+
if (n === line) {
|
|
44325
|
+
out.push(` ${" ".repeat(gutterWidth)} | ${" ".repeat(Math.max(0, column - 1))}^`);
|
|
44326
|
+
}
|
|
44327
|
+
}
|
|
44328
|
+
return out.join("\n");
|
|
44329
|
+
}
|
|
44330
|
+
function locAt(source, offset, file) {
|
|
44331
|
+
const { line, column } = offsetToLineCol(source, offset);
|
|
44332
|
+
return { file, line, column, frame: codeFrame(source, line, column) };
|
|
44333
|
+
}
|
|
44334
|
+
|
|
44335
|
+
// ../stator/src/compiler/client-script.ts
|
|
44344
44336
|
function kebabToPascal(tag) {
|
|
44345
44337
|
return tag.split("-").map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
|
|
44346
44338
|
}
|
|
@@ -44492,7 +44484,7 @@ function cleanJsxText(raw) {
|
|
|
44492
44484
|
var WRAP_PREFIX_LEN = "const __t = (<>".length;
|
|
44493
44485
|
var INLINE_SCRIPT_RE = /<script\b([^>]*\bis:inline\b[^>]*)>([\s\S]*?)<\/script>/gi;
|
|
44494
44486
|
var inlineMarker = (i) => `\0statorInlineScript${i}\0`;
|
|
44495
|
-
var INLINE_MARKER_RE =
|
|
44487
|
+
var INLINE_MARKER_RE = /\0statorInlineScript(\d+)\0/g;
|
|
44496
44488
|
function eachItemParamsFor(jsx) {
|
|
44497
44489
|
let node = jsx.parent;
|
|
44498
44490
|
while (node && import_typescript3.default.isParenthesizedExpression(node)) node = node.parent;
|
|
@@ -44534,6 +44526,28 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44534
44526
|
let eachParams = null;
|
|
44535
44527
|
const enableItemBind = !opts.client;
|
|
44536
44528
|
const isItemRead = (n) => enableItemBind && eachParams !== null && import_typescript3.default.isCallExpression(n) && import_typescript3.default.isIdentifier(n.expression) && n.expression.text === "read" && n.arguments.length >= 2 && n.arguments[0] !== void 0 && import_typescript3.default.isIdentifier(n.arguments[0]) && n.arguments[0].text === eachParams.item;
|
|
44529
|
+
const isClientRead = (n) => opts.client !== void 0 && import_typescript3.default.isCallExpression(n) && import_typescript3.default.isIdentifier(n.expression) && n.expression.text === "read" && n.arguments.length >= 2 && n.arguments[0] !== void 0 && import_typescript3.default.isIdentifier(n.arguments[0]) && opts.client.useFields.has(n.arguments[0].text);
|
|
44530
|
+
const bindRemoved = (name, at) => new CompileError(
|
|
44531
|
+
`stator: bind:${name} was removed in 2.0. Display state with read() \u2014 \`{read(m, (s) => s.value)}\` in text position, \`attr={read(m, \u2026)}\` on an attribute \u2014 and capture input at a commit boundary with a typed event (ref:/FormData + send/dispatch). See the forms guide.`,
|
|
44532
|
+
at
|
|
44533
|
+
);
|
|
44534
|
+
const clientReadExpr = (call) => `(${call.arguments[1].getText(sf)})(${call.arguments[0].text})`;
|
|
44535
|
+
const allocSlotMarker = () => {
|
|
44536
|
+
const client = opts.client;
|
|
44537
|
+
if (!client) throw new CompileError("stator: internal \u2014 slot marker outside client mode");
|
|
44538
|
+
return slotMarker(client.directives.filter((d) => d.kind === "slot").length);
|
|
44539
|
+
};
|
|
44540
|
+
const assertNoClientRead = (n) => {
|
|
44541
|
+
if (!opts.client) return;
|
|
44542
|
+
if (import_typescript3.default.isJsxElement(n) || import_typescript3.default.isJsxSelfClosingElement(n) || import_typescript3.default.isJsxFragment(n)) return;
|
|
44543
|
+
if (isClientRead(n)) {
|
|
44544
|
+
throw new CompileError(
|
|
44545
|
+
`stator: read(${n.arguments[0].text}, \u2026) on a client machine must be the entire expression \u2014 text position (\`{read(m, s => \u2026)}\`) or attribute position (\`attr={read(m, s => \u2026)}\`). Compose derived values inside the selector.`,
|
|
44546
|
+
loc2(n)
|
|
44547
|
+
);
|
|
44548
|
+
}
|
|
44549
|
+
import_typescript3.default.forEachChild(n, assertNoClientRead);
|
|
44550
|
+
};
|
|
44537
44551
|
const loc2 = (node) => {
|
|
44538
44552
|
if (opts.source == null || opts.templateOffset == null) return void 0;
|
|
44539
44553
|
const orig = opts.templateOffset + doctypeLen + (node.getStart(sf) - WRAP_PREFIX_LEN);
|
|
@@ -44642,6 +44656,17 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44642
44656
|
if (import_typescript3.default.isJsxText(node)) return escapeText(cleanJsxText(node.getFullText(sf)));
|
|
44643
44657
|
if (import_typescript3.default.isJsxExpression(node)) {
|
|
44644
44658
|
if (!node.expression) return "";
|
|
44659
|
+
if (opts.client && isClientRead(node.expression)) {
|
|
44660
|
+
const marker = allocSlotMarker();
|
|
44661
|
+
const expr = clientReadExpr(node.expression);
|
|
44662
|
+
opts.client.directives.push({
|
|
44663
|
+
marker,
|
|
44664
|
+
kind: "slot",
|
|
44665
|
+
expr,
|
|
44666
|
+
deps: inferDeps(expr, opts.client.useFields)
|
|
44667
|
+
});
|
|
44668
|
+
return `<!--${marker}-->`;
|
|
44669
|
+
}
|
|
44645
44670
|
return `\${${lowerExprText(node.expression)}}`;
|
|
44646
44671
|
}
|
|
44647
44672
|
if (import_typescript3.default.isJsxElement(node)) {
|
|
@@ -44675,6 +44700,7 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44675
44700
|
if (import_typescript3.default.isJsxElement(expr) || import_typescript3.default.isJsxSelfClosingElement(expr) || import_typescript3.default.isJsxFragment(expr)) {
|
|
44676
44701
|
return `html\`${contentOfChild(expr)}\``;
|
|
44677
44702
|
}
|
|
44703
|
+
assertNoClientRead(expr);
|
|
44678
44704
|
if (isItemRead(expr)) {
|
|
44679
44705
|
return `itemBind(${lowerExprText(expr.arguments[1])})`;
|
|
44680
44706
|
}
|
|
@@ -44720,56 +44746,72 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44720
44746
|
);
|
|
44721
44747
|
}
|
|
44722
44748
|
}
|
|
44723
|
-
const
|
|
44749
|
+
const collected = opts.client ? collectClientDirectives(attrs) : void 0;
|
|
44724
44750
|
let out = "";
|
|
44725
44751
|
for (const attr of attrs.properties) {
|
|
44726
44752
|
if (import_typescript3.default.isJsxSpreadAttribute(attr)) {
|
|
44727
|
-
|
|
44728
|
-
}
|
|
44729
|
-
if (import_typescript3.default.isJsxAttribute(attr) && !import_typescript3.default.isJsxNamespacedName(attr.name) && attr.name.getText(sf) === "child") {
|
|
44753
|
+
out += ` \${spreadAttrs(${lowerExprText(attr.expression)})}`;
|
|
44730
44754
|
continue;
|
|
44731
44755
|
}
|
|
44732
|
-
if (
|
|
44756
|
+
if (import_typescript3.default.isJsxAttribute(attr) && !import_typescript3.default.isJsxNamespacedName(attr.name) && attr.name.getText(sf) === "child") {
|
|
44733
44757
|
continue;
|
|
44734
44758
|
}
|
|
44759
|
+
if (collected?.consumed.has(attr)) continue;
|
|
44735
44760
|
const lowered = lowerAttribute(attr);
|
|
44736
44761
|
if (lowered) out += ` ${lowered}`;
|
|
44737
44762
|
}
|
|
44738
|
-
if (
|
|
44763
|
+
if (collected?.marker) out += ` ${ISLAND_MARKER_ATTR}="${collected.marker}"`;
|
|
44739
44764
|
return out;
|
|
44740
44765
|
};
|
|
44741
44766
|
const collectClientDirectives = (attrs) => {
|
|
44767
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
44742
44768
|
const client = opts.client;
|
|
44743
|
-
if (!client) return
|
|
44769
|
+
if (!client) return { consumed };
|
|
44744
44770
|
const pending = [];
|
|
44745
44771
|
for (const attr of attrs.properties) {
|
|
44746
|
-
if (!import_typescript3.default.isJsxAttribute(attr)
|
|
44747
|
-
|
|
44748
|
-
|
|
44749
|
-
|
|
44750
|
-
|
|
44751
|
-
|
|
44752
|
-
|
|
44753
|
-
|
|
44754
|
-
|
|
44772
|
+
if (!import_typescript3.default.isJsxAttribute(attr)) continue;
|
|
44773
|
+
if (import_typescript3.default.isJsxNamespacedName(attr.name)) {
|
|
44774
|
+
const ns = attr.name.namespace.text;
|
|
44775
|
+
const name = attr.name.name.text;
|
|
44776
|
+
if (ns === "bind") throw bindRemoved(name, loc2(attr));
|
|
44777
|
+
if (ns !== "on") continue;
|
|
44778
|
+
const expr = attrExpr(attr);
|
|
44779
|
+
if (!expr) {
|
|
44780
|
+
throw new CompileError(`stator: on:${name} requires a handler ({...})`, loc2(attr));
|
|
44781
|
+
}
|
|
44755
44782
|
pending.push({ marker: "", kind: "on", event: name, expr, deps: [] });
|
|
44756
|
-
|
|
44783
|
+
consumed.add(attr);
|
|
44784
|
+
continue;
|
|
44785
|
+
}
|
|
44786
|
+
const init = attr.initializer;
|
|
44787
|
+
if (init && import_typescript3.default.isJsxExpression(init) && init.expression && isClientRead(init.expression)) {
|
|
44788
|
+
const target = attr.name.getText(sf);
|
|
44789
|
+
if (target === "value" || target === "checked") {
|
|
44790
|
+
throw new CompileError(
|
|
44791
|
+
`stator: read() can't live-drive ${target}= from a client machine \u2014 the control owns its draft. Pre-fill with a server-rendered ${target} attribute, populate/reset via ref: at safe moments, and capture input with a typed commit event. See the forms guide.`,
|
|
44792
|
+
loc2(attr)
|
|
44793
|
+
);
|
|
44794
|
+
}
|
|
44795
|
+
const expr = clientReadExpr(init.expression);
|
|
44757
44796
|
pending.push({
|
|
44758
44797
|
marker: "",
|
|
44759
44798
|
kind: "bind",
|
|
44760
|
-
target
|
|
44799
|
+
target,
|
|
44761
44800
|
expr,
|
|
44762
44801
|
deps: inferDeps(expr, client.useFields)
|
|
44763
44802
|
});
|
|
44803
|
+
consumed.add(attr);
|
|
44764
44804
|
}
|
|
44765
44805
|
}
|
|
44766
|
-
if (pending.length === 0) return
|
|
44767
|
-
const marker =
|
|
44806
|
+
if (pending.length === 0) return { consumed };
|
|
44807
|
+
const marker = elementMarker(
|
|
44808
|
+
new Set(client.directives.filter((d) => d.kind !== "slot").map((d) => d.marker)).size
|
|
44809
|
+
);
|
|
44768
44810
|
for (const d of pending) {
|
|
44769
44811
|
d.marker = marker;
|
|
44770
44812
|
client.directives.push(d);
|
|
44771
44813
|
}
|
|
44772
|
-
return marker;
|
|
44814
|
+
return { marker, consumed };
|
|
44773
44815
|
};
|
|
44774
44816
|
const lowerChildrenPlaceholder = (attrs) => {
|
|
44775
44817
|
if (meta) meta.usesChildren = true;
|
|
@@ -44823,10 +44865,8 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44823
44865
|
if (meta) meta.refs.add(name2);
|
|
44824
44866
|
return `data-ref=${JSON.stringify(name2)}`;
|
|
44825
44867
|
}
|
|
44826
|
-
throw
|
|
44827
|
-
|
|
44828
|
-
loc2(attr)
|
|
44829
|
-
);
|
|
44868
|
+
if (ns === "bind") throw bindRemoved(name2, loc2(attr));
|
|
44869
|
+
throw new CompileError(`stator: directive "${ns}:${name2}" is not supported`, loc2(attr));
|
|
44830
44870
|
}
|
|
44831
44871
|
const name = attr.name.getText(sf);
|
|
44832
44872
|
if (!attr.initializer) return name;
|
|
@@ -44844,18 +44884,31 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44844
44884
|
};
|
|
44845
44885
|
const lowerComponent = (tag, attrs, children) => {
|
|
44846
44886
|
const entries = [];
|
|
44887
|
+
const forwarded = [];
|
|
44847
44888
|
for (const attr of attrs.properties) {
|
|
44848
44889
|
if (import_typescript3.default.isJsxSpreadAttribute(attr)) {
|
|
44849
|
-
|
|
44850
|
-
|
|
44851
|
-
loc2(attr)
|
|
44852
|
-
);
|
|
44890
|
+
entries.push(`...${lowerExprText(attr.expression)}`);
|
|
44891
|
+
continue;
|
|
44853
44892
|
}
|
|
44854
44893
|
if (import_typescript3.default.isJsxNamespacedName(attr.name)) {
|
|
44855
|
-
|
|
44856
|
-
|
|
44857
|
-
|
|
44858
|
-
)
|
|
44894
|
+
const ns = attr.name.namespace.text;
|
|
44895
|
+
const dirName = attr.name.name.text;
|
|
44896
|
+
if (ns === "bind") throw bindRemoved(dirName, loc2(attr));
|
|
44897
|
+
if (ns !== "on") {
|
|
44898
|
+
throw new CompileError(
|
|
44899
|
+
`stator: forwarding "${ns}:${dirName}" to a component isn't supported yet \u2014 only on:* event directives forward. Apply ref: on an element directly.`,
|
|
44900
|
+
loc2(attr)
|
|
44901
|
+
);
|
|
44902
|
+
}
|
|
44903
|
+
const value = attrExpr(attr);
|
|
44904
|
+
if (!value) {
|
|
44905
|
+
throw new CompileError(
|
|
44906
|
+
`stator: on:${dirName} on <${tag}/> requires a handler ({...})`,
|
|
44907
|
+
loc2(attr)
|
|
44908
|
+
);
|
|
44909
|
+
}
|
|
44910
|
+
forwarded.push(`${JSON.stringify(`on:${dirName}`)}: ${value}`);
|
|
44911
|
+
continue;
|
|
44859
44912
|
}
|
|
44860
44913
|
const name = attr.name.getText(sf);
|
|
44861
44914
|
if (!attr.initializer) {
|
|
@@ -44892,6 +44945,7 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44892
44945
|
}
|
|
44893
44946
|
if (bag.length > 0) entries.push(`children: { ${bag.join(", ")} }`);
|
|
44894
44947
|
}
|
|
44948
|
+
if (forwarded.length > 0) entries.push(`$directives: { ${forwarded.join(", ")} }`);
|
|
44895
44949
|
return `${tag}({ ${entries.join(", ")} })`;
|
|
44896
44950
|
};
|
|
44897
44951
|
const body = `html\`${doctype}${contentOfChildren(fragment.children)}\``;
|
|
@@ -45145,7 +45199,7 @@ function isSubjectGlobal(sel) {
|
|
|
45145
45199
|
}
|
|
45146
45200
|
|
|
45147
45201
|
// ../stator/src/compiler/compile.ts
|
|
45148
|
-
var PRIMITIVES_IMPORT = "import { html, read, each, itemBind, when, match, defer, on, classList, styleList } from '@statorjs/stator/template'";
|
|
45202
|
+
var PRIMITIVES_IMPORT = "import { html, read, each, itemBind, when, match, defer, on, classList, styleList, spreadAttrs } from '@statorjs/stator/template'";
|
|
45149
45203
|
function compile(source, opts = {}) {
|
|
45150
45204
|
const { frontmatter, template, styles, scripts, scriptOffsets, templateOffset } = splitStator(source);
|
|
45151
45205
|
const kind = opts.kind ?? "component";
|
|
@@ -45222,7 +45276,7 @@ function compileClient(template, script, ctx) {
|
|
|
45222
45276
|
const attrDecl = `{ ${[...cls.staticAttrs].map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ")} }`;
|
|
45223
45277
|
const rootScope = ctx.scopeAttr ? ` data-s-${ctx.hash}` : "";
|
|
45224
45278
|
const serverCode = [
|
|
45225
|
-
"import { html, read, each, when, match, defer, on, classList, styleList, createHtmlFragment, clientShellAttrs } from '@statorjs/stator/template'",
|
|
45279
|
+
"import { html, read, each, when, match, defer, on, classList, styleList, spreadAttrs, createHtmlFragment, clientShellAttrs } from '@statorjs/stator/template'",
|
|
45226
45280
|
"",
|
|
45227
45281
|
`export default function (props = {}) {`,
|
|
45228
45282
|
` const __inner = ${innerExpr}`,
|
|
@@ -45351,6 +45405,23 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45351
45405
|
repls.push([n.getStart(sf), n.getEnd(), bound]);
|
|
45352
45406
|
return;
|
|
45353
45407
|
}
|
|
45408
|
+
if (import_typescript4.default.isCallExpression(n) && isStatorCall(n, "forwarded")) {
|
|
45409
|
+
if (kind === "route") {
|
|
45410
|
+
throw new CompileError(
|
|
45411
|
+
"stator: Stator.forwarded() is only available in a component \u2014 it reads a directive forwarded from a parent (`<Child on:click={h}/>`), and a route has no parent.",
|
|
45412
|
+
locInFm(n)
|
|
45413
|
+
);
|
|
45414
|
+
}
|
|
45415
|
+
const arg = n.arguments[0];
|
|
45416
|
+
if (!arg) {
|
|
45417
|
+
throw new CompileError(
|
|
45418
|
+
"stator: Stator.forwarded(name) takes a directive name, e.g. Stator.forwarded('on:click')",
|
|
45419
|
+
locInFm(n)
|
|
45420
|
+
);
|
|
45421
|
+
}
|
|
45422
|
+
repls.push([n.getStart(sf), n.getEnd(), `props.$directives?.[${arg.getText(sf)}]`]);
|
|
45423
|
+
return;
|
|
45424
|
+
}
|
|
45354
45425
|
if (import_typescript4.default.isPropertyAccessExpression(n) && isStatorMember(n, "request")) {
|
|
45355
45426
|
requireRoute("Stator.request", kind, locInFm(n));
|
|
45356
45427
|
repls.push([n.getStart(sf), n.getEnd(), "__req"]);
|
|
@@ -45449,6 +45520,26 @@ function isStatorMember(e, member) {
|
|
|
45449
45520
|
|
|
45450
45521
|
// ../stator/src/compiler/dts.ts
|
|
45451
45522
|
var import_typescript5 = __toESM(require("typescript"), 1);
|
|
45523
|
+
function statorPropsType(frontmatter, template, scripts) {
|
|
45524
|
+
const { propsType } = extractFrontmatterTypes(frontmatter);
|
|
45525
|
+
let propsT = componentPropsType(propsType, template);
|
|
45526
|
+
let needsReadResult = false;
|
|
45527
|
+
const classes = scripts.length > 0 ? analyzeScriptClasses(scripts.join("\n")) : [];
|
|
45528
|
+
if (!propsType && classes.length > 0) {
|
|
45529
|
+
const attrs = /* @__PURE__ */ new Map();
|
|
45530
|
+
for (const cls of classes) {
|
|
45531
|
+
for (const [key, kind] of cls.staticAttrs) attrs.set(key, kind);
|
|
45532
|
+
}
|
|
45533
|
+
if (attrs.size > 0) {
|
|
45534
|
+
needsReadResult = true;
|
|
45535
|
+
const fields = [...attrs].map(([key, kind]) => `${key}?: ${kind} | __SReadResult<${kind}>`).join("; ");
|
|
45536
|
+
propsT = `{ ${fields} } & { [prop: string]: unknown }`;
|
|
45537
|
+
} else {
|
|
45538
|
+
propsT = "{ [prop: string]: unknown }";
|
|
45539
|
+
}
|
|
45540
|
+
}
|
|
45541
|
+
return { propsT, needsReadResult };
|
|
45542
|
+
}
|
|
45452
45543
|
function componentPropsType(propsType, template) {
|
|
45453
45544
|
const usesChildren = /<children[\s/>]/.test(template);
|
|
45454
45545
|
if (propsType) return usesChildren ? `${propsType} & { children?: any }` : propsType;
|
|
@@ -45512,16 +45603,17 @@ function injectImports(globals, modulePath, userCode) {
|
|
|
45512
45603
|
return missing.length > 0 ? `import { ${missing.join(", ")} } from '${modulePath}';
|
|
45513
45604
|
` : "";
|
|
45514
45605
|
}
|
|
45515
|
-
var AMBIENT_TYPE_IMPORTS = "import type { AnyMachineDef as __SMachineDef } from '@statorjs/stator/machine';\nimport type { InstanceOf as __SInstanceOf } from '@statorjs/stator/template';\n";
|
|
45606
|
+
var AMBIENT_TYPE_IMPORTS = "import type { AnyMachineDef as __SMachineDef } from '@statorjs/stator/machine';\nimport type { InstanceOf as __SInstanceOf } from '@statorjs/stator/template';\nimport type { StatorIntrinsicElements as __SIntrinsics } from '@statorjs/stator/template';\n";
|
|
45516
45607
|
var STATOR_AMBIENT = `declare const Stator: {
|
|
45517
45608
|
props<P>(): P;
|
|
45518
45609
|
reads<const T extends readonly __SMachineDef[]>(defs: T): { -readonly [K in keyof T]: __SInstanceOf<T[K]> };
|
|
45610
|
+
forwarded(name: \`on:\${string}\`): (() => unknown) | undefined;
|
|
45519
45611
|
request: any;
|
|
45520
45612
|
response: { status: number; headers: Record<string, string>; cookies: any };
|
|
45521
45613
|
};
|
|
45522
45614
|
declare global {
|
|
45523
45615
|
namespace JSX {
|
|
45524
|
-
interface IntrinsicElements extends
|
|
45616
|
+
interface IntrinsicElements extends __SIntrinsics {}
|
|
45525
45617
|
}
|
|
45526
45618
|
}
|
|
45527
45619
|
`;
|
|
@@ -45553,7 +45645,14 @@ function buildServerTsx(regions) {
|
|
|
45553
45645
|
tplOffset += doctype[0].length;
|
|
45554
45646
|
tpl = tpl.slice(doctype[0].length);
|
|
45555
45647
|
}
|
|
45556
|
-
const propsT =
|
|
45648
|
+
const { propsT, needsReadResult } = statorPropsType(
|
|
45649
|
+
fm,
|
|
45650
|
+
regions.template.content,
|
|
45651
|
+
regions.scripts.map((s) => s.content)
|
|
45652
|
+
);
|
|
45653
|
+
if (needsReadResult) {
|
|
45654
|
+
code += "type __SReadResult<T> = import('@statorjs/stator/template').ReadResult<T>\n";
|
|
45655
|
+
}
|
|
45557
45656
|
code += `export default function (_props: ${propsT}) {
|
|
45558
45657
|
`;
|
|
45559
45658
|
for (const seg of body) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statorjs/language-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Volar-based language server for .stator files.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"volar-service-typescript": "0.0.71",
|
|
34
34
|
"vscode-css-languageservice": "^6.3.0",
|
|
35
35
|
"vscode-uri": "^3.0.8",
|
|
36
|
-
"@statorjs/stator": "
|
|
36
|
+
"@statorjs/stator": "2.0.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"typescript": "^5.6.0"
|