@statorjs/language-server 0.1.17 → 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 +99 -91
- 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, bindSlot, 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`;
|
|
@@ -44242,7 +44206,9 @@ function emitClientModule(input) {
|
|
|
44242
44206
|
continue;
|
|
44243
44207
|
}
|
|
44244
44208
|
const node = `n${i++}`;
|
|
44245
|
-
lines.push(
|
|
44209
|
+
lines.push(
|
|
44210
|
+
` for (const ${node} of this.querySelectorAll(${JSON.stringify(elementMarkerSelector(marker))})) {`
|
|
44211
|
+
);
|
|
44246
44212
|
for (const d of group) lines.push(` ${wireDirective(node, d, members)}`);
|
|
44247
44213
|
lines.push(" }");
|
|
44248
44214
|
}
|
|
@@ -44268,27 +44234,9 @@ function wireDirective(node, d, members) {
|
|
|
44268
44234
|
const target = d.target ?? "text";
|
|
44269
44235
|
const thunk = `() => (${rewriteMembers(d.expr, members)})`;
|
|
44270
44236
|
const deps = `[${d.deps.map((dep) => `this.${dep}`).join(", ")}]`;
|
|
44271
|
-
if (target === "value" || target === "checked") {
|
|
44272
|
-
const path = parseTwoWayPath(d.expr);
|
|
44273
|
-
if (!path) {
|
|
44274
|
-
throw new CompileError(
|
|
44275
|
-
`stator: bind:${target}={${d.expr}} must bind to a settable context path like \`actor.key\` (a derived value can't be two-way bound).`
|
|
44276
|
-
);
|
|
44277
|
-
}
|
|
44278
|
-
const writer2 = emitWriter(node, target);
|
|
44279
|
-
const read = target === "checked" ? `${node}.checked` : `${node}.value`;
|
|
44280
|
-
const guard = target === "value" ? `if (e.isComposing) return; ` : "";
|
|
44281
|
-
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} }) })`;
|
|
44282
|
-
return `this.track(bind(${deps}, ${thunk}, ${writer2}));
|
|
44283
|
-
${setter}`;
|
|
44284
|
-
}
|
|
44285
44237
|
const writer = emitWriter(node, target);
|
|
44286
44238
|
return `this.track(bind(${deps}, ${thunk}, ${writer}))`;
|
|
44287
44239
|
}
|
|
44288
|
-
function parseTwoWayPath(expr) {
|
|
44289
|
-
const m = expr.trim().match(/^([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)$/);
|
|
44290
|
-
return m ? { actor: m[1], key: m[2] } : null;
|
|
44291
|
-
}
|
|
44292
44240
|
function emitHandler(expr, members) {
|
|
44293
44241
|
const t = expr.trim();
|
|
44294
44242
|
if (/^[A-Za-z_$][\w$]*$/.test(t) && members.has(t)) {
|
|
@@ -44298,18 +44246,11 @@ function emitHandler(expr, members) {
|
|
|
44298
44246
|
}
|
|
44299
44247
|
function emitWriter(node, target) {
|
|
44300
44248
|
switch (target) {
|
|
44301
|
-
case "text":
|
|
44302
|
-
return `(v) => { ${node}.textContent = v == null ? '' : String(v) }`;
|
|
44303
|
-
case "html":
|
|
44304
|
-
return `(v) => { ${node}.innerHTML = v == null ? '' : String(v) }`;
|
|
44305
|
-
case "value":
|
|
44306
|
-
return `(v) => { const s = v == null ? '' : String(v); if (${node}.value !== s) ${node}.value = s }`;
|
|
44307
44249
|
case "disabled":
|
|
44308
44250
|
case "hidden":
|
|
44309
|
-
case "checked":
|
|
44310
44251
|
return `(v) => { if (${node}.${target} !== !!v) ${node}.${target} = !!v }`;
|
|
44311
44252
|
default:
|
|
44312
|
-
return `(v) =>
|
|
44253
|
+
return `(v) => setAttr(${node}, ${JSON.stringify(target)}, attrValue(v))`;
|
|
44313
44254
|
}
|
|
44314
44255
|
}
|
|
44315
44256
|
function stripClientPrimitiveImports(script) {
|
|
@@ -44348,6 +44289,50 @@ function rewriteMembers(expr, members) {
|
|
|
44348
44289
|
|
|
44349
44290
|
// ../stator/src/compiler/client-script.ts
|
|
44350
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
|
|
44351
44336
|
function kebabToPascal(tag) {
|
|
44352
44337
|
return tag.split("-").map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
|
|
44353
44338
|
}
|
|
@@ -44542,11 +44527,15 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44542
44527
|
const enableItemBind = !opts.client;
|
|
44543
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;
|
|
44544
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
|
+
);
|
|
44545
44534
|
const clientReadExpr = (call) => `(${call.arguments[1].getText(sf)})(${call.arguments[0].text})`;
|
|
44546
44535
|
const allocSlotMarker = () => {
|
|
44547
44536
|
const client = opts.client;
|
|
44548
44537
|
if (!client) throw new CompileError("stator: internal \u2014 slot marker outside client mode");
|
|
44549
|
-
return
|
|
44538
|
+
return slotMarker(client.directives.filter((d) => d.kind === "slot").length);
|
|
44550
44539
|
};
|
|
44551
44540
|
const assertNoClientRead = (n) => {
|
|
44552
44541
|
if (!opts.client) return;
|
|
@@ -44771,7 +44760,7 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44771
44760
|
const lowered = lowerAttribute(attr);
|
|
44772
44761
|
if (lowered) out += ` ${lowered}`;
|
|
44773
44762
|
}
|
|
44774
|
-
if (collected?.marker) out += `
|
|
44763
|
+
if (collected?.marker) out += ` ${ISLAND_MARKER_ATTR}="${collected.marker}"`;
|
|
44775
44764
|
return out;
|
|
44776
44765
|
};
|
|
44777
44766
|
const collectClientDirectives = (attrs) => {
|
|
@@ -44784,22 +44773,13 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44784
44773
|
if (import_typescript3.default.isJsxNamespacedName(attr.name)) {
|
|
44785
44774
|
const ns = attr.name.namespace.text;
|
|
44786
44775
|
const name = attr.name.name.text;
|
|
44787
|
-
if (ns
|
|
44776
|
+
if (ns === "bind") throw bindRemoved(name, loc2(attr));
|
|
44777
|
+
if (ns !== "on") continue;
|
|
44788
44778
|
const expr = attrExpr(attr);
|
|
44789
44779
|
if (!expr) {
|
|
44790
|
-
throw new CompileError(`stator:
|
|
44791
|
-
}
|
|
44792
|
-
if (ns === "on") {
|
|
44793
|
-
pending.push({ marker: "", kind: "on", event: name, expr, deps: [] });
|
|
44794
|
-
} else {
|
|
44795
|
-
pending.push({
|
|
44796
|
-
marker: "",
|
|
44797
|
-
kind: "bind",
|
|
44798
|
-
target: name,
|
|
44799
|
-
expr,
|
|
44800
|
-
deps: inferDeps(expr, client.useFields)
|
|
44801
|
-
});
|
|
44780
|
+
throw new CompileError(`stator: on:${name} requires a handler ({...})`, loc2(attr));
|
|
44802
44781
|
}
|
|
44782
|
+
pending.push({ marker: "", kind: "on", event: name, expr, deps: [] });
|
|
44803
44783
|
consumed.add(attr);
|
|
44804
44784
|
continue;
|
|
44805
44785
|
}
|
|
@@ -44824,7 +44804,9 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44824
44804
|
}
|
|
44825
44805
|
}
|
|
44826
44806
|
if (pending.length === 0) return { consumed };
|
|
44827
|
-
const marker =
|
|
44807
|
+
const marker = elementMarker(
|
|
44808
|
+
new Set(client.directives.filter((d) => d.kind !== "slot").map((d) => d.marker)).size
|
|
44809
|
+
);
|
|
44828
44810
|
for (const d of pending) {
|
|
44829
44811
|
d.marker = marker;
|
|
44830
44812
|
client.directives.push(d);
|
|
@@ -44883,10 +44865,8 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44883
44865
|
if (meta) meta.refs.add(name2);
|
|
44884
44866
|
return `data-ref=${JSON.stringify(name2)}`;
|
|
44885
44867
|
}
|
|
44886
|
-
throw
|
|
44887
|
-
|
|
44888
|
-
loc2(attr)
|
|
44889
|
-
);
|
|
44868
|
+
if (ns === "bind") throw bindRemoved(name2, loc2(attr));
|
|
44869
|
+
throw new CompileError(`stator: directive "${ns}:${name2}" is not supported`, loc2(attr));
|
|
44890
44870
|
}
|
|
44891
44871
|
const name = attr.name.getText(sf);
|
|
44892
44872
|
if (!attr.initializer) return name;
|
|
@@ -44913,9 +44893,10 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44913
44893
|
if (import_typescript3.default.isJsxNamespacedName(attr.name)) {
|
|
44914
44894
|
const ns = attr.name.namespace.text;
|
|
44915
44895
|
const dirName = attr.name.name.text;
|
|
44896
|
+
if (ns === "bind") throw bindRemoved(dirName, loc2(attr));
|
|
44916
44897
|
if (ns !== "on") {
|
|
44917
44898
|
throw new CompileError(
|
|
44918
|
-
`stator: forwarding "${ns}:${dirName}" to a component isn't supported yet \u2014 only on:* event directives forward. Apply
|
|
44899
|
+
`stator: forwarding "${ns}:${dirName}" to a component isn't supported yet \u2014 only on:* event directives forward. Apply ref: on an element directly.`,
|
|
44919
44900
|
loc2(attr)
|
|
44920
44901
|
);
|
|
44921
44902
|
}
|
|
@@ -45539,6 +45520,26 @@ function isStatorMember(e, member) {
|
|
|
45539
45520
|
|
|
45540
45521
|
// ../stator/src/compiler/dts.ts
|
|
45541
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
|
+
}
|
|
45542
45543
|
function componentPropsType(propsType, template) {
|
|
45543
45544
|
const usesChildren = /<children[\s/>]/.test(template);
|
|
45544
45545
|
if (propsType) return usesChildren ? `${propsType} & { children?: any }` : propsType;
|
|
@@ -45644,7 +45645,14 @@ function buildServerTsx(regions) {
|
|
|
45644
45645
|
tplOffset += doctype[0].length;
|
|
45645
45646
|
tpl = tpl.slice(doctype[0].length);
|
|
45646
45647
|
}
|
|
45647
|
-
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
|
+
}
|
|
45648
45656
|
code += `export default function (_props: ${propsT}) {
|
|
45649
45657
|
`;
|
|
45650
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"
|