@statorjs/language-server 0.1.15 → 0.1.17
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 +146 -38
- package/package.json +2 -2
package/dist/server.cjs
CHANGED
|
@@ -44220,7 +44220,7 @@ function locAt(source, offset, file) {
|
|
|
44220
44220
|
}
|
|
44221
44221
|
|
|
44222
44222
|
// ../stator/src/compiler/client-emit.ts
|
|
44223
|
-
var PRIMITIVES = "import { StatorElement, defineElement, use, machine, bind, effect, dispatch } from '@statorjs/stator/client'";
|
|
44223
|
+
var PRIMITIVES = "import { StatorElement, defineElement, use, machine, bind, bindSlot, effect, dispatch } from '@statorjs/stator/client'";
|
|
44224
44224
|
function emitClientModule(input) {
|
|
44225
44225
|
const { script, element, directives, members } = input;
|
|
44226
44226
|
const impl = `__${element.className}Impl`;
|
|
@@ -44233,9 +44233,16 @@ function emitClientModule(input) {
|
|
|
44233
44233
|
const lines = [];
|
|
44234
44234
|
let i = 0;
|
|
44235
44235
|
for (const [marker, group] of byMarker) {
|
|
44236
|
+
if (group[0]?.kind === "slot") {
|
|
44237
|
+
for (const d of group) {
|
|
44238
|
+
const thunk = `() => (${rewriteMembers(d.expr, members)})`;
|
|
44239
|
+
const deps = `[${d.deps.map((dep) => `this.${dep}`).join(", ")}]`;
|
|
44240
|
+
lines.push(` this.track(bindSlot(this, ${JSON.stringify(marker)}, ${deps}, ${thunk}))`);
|
|
44241
|
+
}
|
|
44242
|
+
continue;
|
|
44243
|
+
}
|
|
44236
44244
|
const node = `n${i++}`;
|
|
44237
|
-
lines.push(` const ${node}
|
|
44238
|
-
lines.push(` if (${node}) {`);
|
|
44245
|
+
lines.push(` for (const ${node} of this.querySelectorAll('[data-b="${marker}"]')) {`);
|
|
44239
44246
|
for (const d of group) lines.push(` ${wireDirective(node, d, members)}`);
|
|
44240
44247
|
lines.push(" }");
|
|
44241
44248
|
}
|
|
@@ -44472,10 +44479,27 @@ function scopeHash(input) {
|
|
|
44472
44479
|
|
|
44473
44480
|
// ../stator/src/compiler/lower.ts
|
|
44474
44481
|
var import_typescript3 = __toESM(require("typescript"), 1);
|
|
44482
|
+
function cleanJsxText(raw) {
|
|
44483
|
+
const lines = raw.split(/\r\n|\n|\r/);
|
|
44484
|
+
let lastNonEmpty = 0;
|
|
44485
|
+
for (let i = 0; i < lines.length; i++) {
|
|
44486
|
+
if (/[^ \t]/.test(lines[i])) lastNonEmpty = i;
|
|
44487
|
+
}
|
|
44488
|
+
let out = "";
|
|
44489
|
+
for (let i = 0; i < lines.length; i++) {
|
|
44490
|
+
let line = lines[i].replace(/\t/g, " ");
|
|
44491
|
+
if (i !== 0) line = line.replace(/^ +/, "");
|
|
44492
|
+
if (i !== lines.length - 1) line = line.replace(/ +$/, "");
|
|
44493
|
+
if (!line) continue;
|
|
44494
|
+
if (i !== lastNonEmpty) line += " ";
|
|
44495
|
+
out += line;
|
|
44496
|
+
}
|
|
44497
|
+
return out;
|
|
44498
|
+
}
|
|
44475
44499
|
var WRAP_PREFIX_LEN = "const __t = (<>".length;
|
|
44476
44500
|
var INLINE_SCRIPT_RE = /<script\b([^>]*\bis:inline\b[^>]*)>([\s\S]*?)<\/script>/gi;
|
|
44477
44501
|
var inlineMarker = (i) => `\0statorInlineScript${i}\0`;
|
|
44478
|
-
var INLINE_MARKER_RE =
|
|
44502
|
+
var INLINE_MARKER_RE = /\0statorInlineScript(\d+)\0/g;
|
|
44479
44503
|
function eachItemParamsFor(jsx) {
|
|
44480
44504
|
let node = jsx.parent;
|
|
44481
44505
|
while (node && import_typescript3.default.isParenthesizedExpression(node)) node = node.parent;
|
|
@@ -44517,6 +44541,24 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44517
44541
|
let eachParams = null;
|
|
44518
44542
|
const enableItemBind = !opts.client;
|
|
44519
44543
|
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
|
+
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);
|
|
44545
|
+
const clientReadExpr = (call) => `(${call.arguments[1].getText(sf)})(${call.arguments[0].text})`;
|
|
44546
|
+
const allocSlotMarker = () => {
|
|
44547
|
+
const client = opts.client;
|
|
44548
|
+
if (!client) throw new CompileError("stator: internal \u2014 slot marker outside client mode");
|
|
44549
|
+
return `s${client.directives.filter((d) => d.kind === "slot").length}`;
|
|
44550
|
+
};
|
|
44551
|
+
const assertNoClientRead = (n) => {
|
|
44552
|
+
if (!opts.client) return;
|
|
44553
|
+
if (import_typescript3.default.isJsxElement(n) || import_typescript3.default.isJsxSelfClosingElement(n) || import_typescript3.default.isJsxFragment(n)) return;
|
|
44554
|
+
if (isClientRead(n)) {
|
|
44555
|
+
throw new CompileError(
|
|
44556
|
+
`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.`,
|
|
44557
|
+
loc2(n)
|
|
44558
|
+
);
|
|
44559
|
+
}
|
|
44560
|
+
import_typescript3.default.forEachChild(n, assertNoClientRead);
|
|
44561
|
+
};
|
|
44520
44562
|
const loc2 = (node) => {
|
|
44521
44563
|
if (opts.source == null || opts.templateOffset == null) return void 0;
|
|
44522
44564
|
const orig = opts.templateOffset + doctypeLen + (node.getStart(sf) - WRAP_PREFIX_LEN);
|
|
@@ -44622,9 +44664,20 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44622
44664
|
return out;
|
|
44623
44665
|
};
|
|
44624
44666
|
const contentOfChild = (node) => {
|
|
44625
|
-
if (import_typescript3.default.isJsxText(node)) return escapeText(node.
|
|
44667
|
+
if (import_typescript3.default.isJsxText(node)) return escapeText(cleanJsxText(node.getFullText(sf)));
|
|
44626
44668
|
if (import_typescript3.default.isJsxExpression(node)) {
|
|
44627
44669
|
if (!node.expression) return "";
|
|
44670
|
+
if (opts.client && isClientRead(node.expression)) {
|
|
44671
|
+
const marker = allocSlotMarker();
|
|
44672
|
+
const expr = clientReadExpr(node.expression);
|
|
44673
|
+
opts.client.directives.push({
|
|
44674
|
+
marker,
|
|
44675
|
+
kind: "slot",
|
|
44676
|
+
expr,
|
|
44677
|
+
deps: inferDeps(expr, opts.client.useFields)
|
|
44678
|
+
});
|
|
44679
|
+
return `<!--${marker}-->`;
|
|
44680
|
+
}
|
|
44628
44681
|
return `\${${lowerExprText(node.expression)}}`;
|
|
44629
44682
|
}
|
|
44630
44683
|
if (import_typescript3.default.isJsxElement(node)) {
|
|
@@ -44658,6 +44711,7 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44658
44711
|
if (import_typescript3.default.isJsxElement(expr) || import_typescript3.default.isJsxSelfClosingElement(expr) || import_typescript3.default.isJsxFragment(expr)) {
|
|
44659
44712
|
return `html\`${contentOfChild(expr)}\``;
|
|
44660
44713
|
}
|
|
44714
|
+
assertNoClientRead(expr);
|
|
44661
44715
|
if (isItemRead(expr)) {
|
|
44662
44716
|
return `itemBind(${lowerExprText(expr.arguments[1])})`;
|
|
44663
44717
|
}
|
|
@@ -44703,56 +44757,79 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44703
44757
|
);
|
|
44704
44758
|
}
|
|
44705
44759
|
}
|
|
44706
|
-
const
|
|
44760
|
+
const collected = opts.client ? collectClientDirectives(attrs) : void 0;
|
|
44707
44761
|
let out = "";
|
|
44708
44762
|
for (const attr of attrs.properties) {
|
|
44709
44763
|
if (import_typescript3.default.isJsxSpreadAttribute(attr)) {
|
|
44710
|
-
|
|
44711
|
-
}
|
|
44712
|
-
if (import_typescript3.default.isJsxAttribute(attr) && !import_typescript3.default.isJsxNamespacedName(attr.name) && attr.name.getText(sf) === "child") {
|
|
44764
|
+
out += ` \${spreadAttrs(${lowerExprText(attr.expression)})}`;
|
|
44713
44765
|
continue;
|
|
44714
44766
|
}
|
|
44715
|
-
if (
|
|
44767
|
+
if (import_typescript3.default.isJsxAttribute(attr) && !import_typescript3.default.isJsxNamespacedName(attr.name) && attr.name.getText(sf) === "child") {
|
|
44716
44768
|
continue;
|
|
44717
44769
|
}
|
|
44770
|
+
if (collected?.consumed.has(attr)) continue;
|
|
44718
44771
|
const lowered = lowerAttribute(attr);
|
|
44719
44772
|
if (lowered) out += ` ${lowered}`;
|
|
44720
44773
|
}
|
|
44721
|
-
if (
|
|
44774
|
+
if (collected?.marker) out += ` data-b="${collected.marker}"`;
|
|
44722
44775
|
return out;
|
|
44723
44776
|
};
|
|
44724
44777
|
const collectClientDirectives = (attrs) => {
|
|
44778
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
44725
44779
|
const client = opts.client;
|
|
44726
|
-
if (!client) return
|
|
44780
|
+
if (!client) return { consumed };
|
|
44727
44781
|
const pending = [];
|
|
44728
44782
|
for (const attr of attrs.properties) {
|
|
44729
|
-
if (!import_typescript3.default.isJsxAttribute(attr)
|
|
44730
|
-
|
|
44731
|
-
|
|
44732
|
-
|
|
44733
|
-
|
|
44734
|
-
|
|
44735
|
-
|
|
44783
|
+
if (!import_typescript3.default.isJsxAttribute(attr)) continue;
|
|
44784
|
+
if (import_typescript3.default.isJsxNamespacedName(attr.name)) {
|
|
44785
|
+
const ns = attr.name.namespace.text;
|
|
44786
|
+
const name = attr.name.name.text;
|
|
44787
|
+
if (ns !== "on" && ns !== "bind") continue;
|
|
44788
|
+
const expr = attrExpr(attr);
|
|
44789
|
+
if (!expr) {
|
|
44790
|
+
throw new CompileError(`stator: ${ns}:${name} requires a value ({...})`, loc2(attr));
|
|
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
|
+
});
|
|
44802
|
+
}
|
|
44803
|
+
consumed.add(attr);
|
|
44804
|
+
continue;
|
|
44736
44805
|
}
|
|
44737
|
-
|
|
44738
|
-
|
|
44739
|
-
|
|
44806
|
+
const init = attr.initializer;
|
|
44807
|
+
if (init && import_typescript3.default.isJsxExpression(init) && init.expression && isClientRead(init.expression)) {
|
|
44808
|
+
const target = attr.name.getText(sf);
|
|
44809
|
+
if (target === "value" || target === "checked") {
|
|
44810
|
+
throw new CompileError(
|
|
44811
|
+
`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.`,
|
|
44812
|
+
loc2(attr)
|
|
44813
|
+
);
|
|
44814
|
+
}
|
|
44815
|
+
const expr = clientReadExpr(init.expression);
|
|
44740
44816
|
pending.push({
|
|
44741
44817
|
marker: "",
|
|
44742
44818
|
kind: "bind",
|
|
44743
|
-
target
|
|
44819
|
+
target,
|
|
44744
44820
|
expr,
|
|
44745
44821
|
deps: inferDeps(expr, client.useFields)
|
|
44746
44822
|
});
|
|
44823
|
+
consumed.add(attr);
|
|
44747
44824
|
}
|
|
44748
44825
|
}
|
|
44749
|
-
if (pending.length === 0) return
|
|
44750
|
-
const marker = `b${new Set(client.directives.map((d) => d.marker)).size}`;
|
|
44826
|
+
if (pending.length === 0) return { consumed };
|
|
44827
|
+
const marker = `b${new Set(client.directives.filter((d) => d.kind !== "slot").map((d) => d.marker)).size}`;
|
|
44751
44828
|
for (const d of pending) {
|
|
44752
44829
|
d.marker = marker;
|
|
44753
44830
|
client.directives.push(d);
|
|
44754
44831
|
}
|
|
44755
|
-
return marker;
|
|
44832
|
+
return { marker, consumed };
|
|
44756
44833
|
};
|
|
44757
44834
|
const lowerChildrenPlaceholder = (attrs) => {
|
|
44758
44835
|
if (meta) meta.usesChildren = true;
|
|
@@ -44827,18 +44904,30 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44827
44904
|
};
|
|
44828
44905
|
const lowerComponent = (tag, attrs, children) => {
|
|
44829
44906
|
const entries = [];
|
|
44907
|
+
const forwarded = [];
|
|
44830
44908
|
for (const attr of attrs.properties) {
|
|
44831
44909
|
if (import_typescript3.default.isJsxSpreadAttribute(attr)) {
|
|
44832
|
-
|
|
44833
|
-
|
|
44834
|
-
loc2(attr)
|
|
44835
|
-
);
|
|
44910
|
+
entries.push(`...${lowerExprText(attr.expression)}`);
|
|
44911
|
+
continue;
|
|
44836
44912
|
}
|
|
44837
44913
|
if (import_typescript3.default.isJsxNamespacedName(attr.name)) {
|
|
44838
|
-
|
|
44839
|
-
|
|
44840
|
-
|
|
44841
|
-
|
|
44914
|
+
const ns = attr.name.namespace.text;
|
|
44915
|
+
const dirName = attr.name.name.text;
|
|
44916
|
+
if (ns !== "on") {
|
|
44917
|
+
throw new CompileError(
|
|
44918
|
+
`stator: forwarding "${ns}:${dirName}" to a component isn't supported yet \u2014 only on:* event directives forward. Apply bind:/ref: on an element directly.`,
|
|
44919
|
+
loc2(attr)
|
|
44920
|
+
);
|
|
44921
|
+
}
|
|
44922
|
+
const value = attrExpr(attr);
|
|
44923
|
+
if (!value) {
|
|
44924
|
+
throw new CompileError(
|
|
44925
|
+
`stator: on:${dirName} on <${tag}/> requires a handler ({...})`,
|
|
44926
|
+
loc2(attr)
|
|
44927
|
+
);
|
|
44928
|
+
}
|
|
44929
|
+
forwarded.push(`${JSON.stringify(`on:${dirName}`)}: ${value}`);
|
|
44930
|
+
continue;
|
|
44842
44931
|
}
|
|
44843
44932
|
const name = attr.name.getText(sf);
|
|
44844
44933
|
if (!attr.initializer) {
|
|
@@ -44875,6 +44964,7 @@ function lowerTemplate(template, opts = {}) {
|
|
|
44875
44964
|
}
|
|
44876
44965
|
if (bag.length > 0) entries.push(`children: { ${bag.join(", ")} }`);
|
|
44877
44966
|
}
|
|
44967
|
+
if (forwarded.length > 0) entries.push(`$directives: { ${forwarded.join(", ")} }`);
|
|
44878
44968
|
return `${tag}({ ${entries.join(", ")} })`;
|
|
44879
44969
|
};
|
|
44880
44970
|
const body = `html\`${doctype}${contentOfChildren(fragment.children)}\``;
|
|
@@ -45128,7 +45218,7 @@ function isSubjectGlobal(sel) {
|
|
|
45128
45218
|
}
|
|
45129
45219
|
|
|
45130
45220
|
// ../stator/src/compiler/compile.ts
|
|
45131
|
-
var PRIMITIVES_IMPORT = "import { html, read, each, itemBind, when, match, defer, on, classList, styleList } from '@statorjs/stator/template'";
|
|
45221
|
+
var PRIMITIVES_IMPORT = "import { html, read, each, itemBind, when, match, defer, on, classList, styleList, spreadAttrs } from '@statorjs/stator/template'";
|
|
45132
45222
|
function compile(source, opts = {}) {
|
|
45133
45223
|
const { frontmatter, template, styles, scripts, scriptOffsets, templateOffset } = splitStator(source);
|
|
45134
45224
|
const kind = opts.kind ?? "component";
|
|
@@ -45205,7 +45295,7 @@ function compileClient(template, script, ctx) {
|
|
|
45205
45295
|
const attrDecl = `{ ${[...cls.staticAttrs].map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ")} }`;
|
|
45206
45296
|
const rootScope = ctx.scopeAttr ? ` data-s-${ctx.hash}` : "";
|
|
45207
45297
|
const serverCode = [
|
|
45208
|
-
"import { html, read, each, when, match, defer, on, classList, styleList, createHtmlFragment, clientShellAttrs } from '@statorjs/stator/template'",
|
|
45298
|
+
"import { html, read, each, when, match, defer, on, classList, styleList, spreadAttrs, createHtmlFragment, clientShellAttrs } from '@statorjs/stator/template'",
|
|
45209
45299
|
"",
|
|
45210
45300
|
`export default function (props = {}) {`,
|
|
45211
45301
|
` const __inner = ${innerExpr}`,
|
|
@@ -45334,6 +45424,23 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45334
45424
|
repls.push([n.getStart(sf), n.getEnd(), bound]);
|
|
45335
45425
|
return;
|
|
45336
45426
|
}
|
|
45427
|
+
if (import_typescript4.default.isCallExpression(n) && isStatorCall(n, "forwarded")) {
|
|
45428
|
+
if (kind === "route") {
|
|
45429
|
+
throw new CompileError(
|
|
45430
|
+
"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.",
|
|
45431
|
+
locInFm(n)
|
|
45432
|
+
);
|
|
45433
|
+
}
|
|
45434
|
+
const arg = n.arguments[0];
|
|
45435
|
+
if (!arg) {
|
|
45436
|
+
throw new CompileError(
|
|
45437
|
+
"stator: Stator.forwarded(name) takes a directive name, e.g. Stator.forwarded('on:click')",
|
|
45438
|
+
locInFm(n)
|
|
45439
|
+
);
|
|
45440
|
+
}
|
|
45441
|
+
repls.push([n.getStart(sf), n.getEnd(), `props.$directives?.[${arg.getText(sf)}]`]);
|
|
45442
|
+
return;
|
|
45443
|
+
}
|
|
45337
45444
|
if (import_typescript4.default.isPropertyAccessExpression(n) && isStatorMember(n, "request")) {
|
|
45338
45445
|
requireRoute("Stator.request", kind, locInFm(n));
|
|
45339
45446
|
repls.push([n.getStart(sf), n.getEnd(), "__req"]);
|
|
@@ -45495,16 +45602,17 @@ function injectImports(globals, modulePath, userCode) {
|
|
|
45495
45602
|
return missing.length > 0 ? `import { ${missing.join(", ")} } from '${modulePath}';
|
|
45496
45603
|
` : "";
|
|
45497
45604
|
}
|
|
45498
|
-
var AMBIENT_TYPE_IMPORTS = "import type { AnyMachineDef as __SMachineDef } from '@statorjs/stator/machine';\nimport type { InstanceOf as __SInstanceOf } from '@statorjs/stator/template';\n";
|
|
45605
|
+
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";
|
|
45499
45606
|
var STATOR_AMBIENT = `declare const Stator: {
|
|
45500
45607
|
props<P>(): P;
|
|
45501
45608
|
reads<const T extends readonly __SMachineDef[]>(defs: T): { -readonly [K in keyof T]: __SInstanceOf<T[K]> };
|
|
45609
|
+
forwarded(name: \`on:\${string}\`): (() => unknown) | undefined;
|
|
45502
45610
|
request: any;
|
|
45503
45611
|
response: { status: number; headers: Record<string, string>; cookies: any };
|
|
45504
45612
|
};
|
|
45505
45613
|
declare global {
|
|
45506
45614
|
namespace JSX {
|
|
45507
|
-
interface IntrinsicElements extends
|
|
45615
|
+
interface IntrinsicElements extends __SIntrinsics {}
|
|
45508
45616
|
}
|
|
45509
45617
|
}
|
|
45510
45618
|
`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statorjs/language-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
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": "1.
|
|
36
|
+
"@statorjs/stator": "1.9.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"typescript": "^5.6.0"
|