@statorjs/language-server 0.1.20 → 0.1.21
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 +128 -20
- package/package.json +2 -2
package/dist/server.cjs
CHANGED
|
@@ -44183,8 +44183,38 @@ var elementMarker = (i) => `b${i}`;
|
|
|
44183
44183
|
var slotMarker = (i) => `s${i}`;
|
|
44184
44184
|
var elementMarkerSelector = (marker) => `[${ISLAND_MARKER_ATTR}="${marker}"]`;
|
|
44185
44185
|
|
|
44186
|
+
// ../stator/src/compiler/emit-names.ts
|
|
44187
|
+
var TEMPLATE_AUTHOR_GLOBALS = [
|
|
44188
|
+
"read",
|
|
44189
|
+
"each",
|
|
44190
|
+
"when",
|
|
44191
|
+
"match",
|
|
44192
|
+
"defer",
|
|
44193
|
+
"on",
|
|
44194
|
+
"classList",
|
|
44195
|
+
"styleList"
|
|
44196
|
+
];
|
|
44197
|
+
var TEMPLATE_LOWERING_TARGETS = ["html", "itemBind", "spreadAttrs"];
|
|
44198
|
+
var ISLAND_SHELL_EXTRAS = ["createHtmlFragment", "clientShellAttrs"];
|
|
44199
|
+
var CLIENT_AUTHOR_GLOBALS = [
|
|
44200
|
+
"StatorElement",
|
|
44201
|
+
"use",
|
|
44202
|
+
"machine",
|
|
44203
|
+
"defineElement",
|
|
44204
|
+
"bind",
|
|
44205
|
+
"effect",
|
|
44206
|
+
"dispatch"
|
|
44207
|
+
];
|
|
44208
|
+
var CLIENT_LOWERING_TARGETS = ["bindSlot", "attrValue", "setAttr"];
|
|
44209
|
+
function importLine(names, from) {
|
|
44210
|
+
return `import { ${names.join(", ")} } from '${from}'`;
|
|
44211
|
+
}
|
|
44212
|
+
|
|
44186
44213
|
// ../stator/src/compiler/client-emit.ts
|
|
44187
|
-
var PRIMITIVES =
|
|
44214
|
+
var PRIMITIVES = importLine(
|
|
44215
|
+
[...CLIENT_AUTHOR_GLOBALS, ...CLIENT_LOWERING_TARGETS],
|
|
44216
|
+
"@statorjs/stator/client"
|
|
44217
|
+
);
|
|
44188
44218
|
function emitClientModule(input) {
|
|
44189
44219
|
const { script, element, directives, members } = input;
|
|
44190
44220
|
const impl = `__${element.className}Impl`;
|
|
@@ -45199,7 +45229,18 @@ function isSubjectGlobal(sel) {
|
|
|
45199
45229
|
}
|
|
45200
45230
|
|
|
45201
45231
|
// ../stator/src/compiler/compile.ts
|
|
45202
|
-
var PRIMITIVES_IMPORT =
|
|
45232
|
+
var PRIMITIVES_IMPORT = importLine(
|
|
45233
|
+
[...TEMPLATE_AUTHOR_GLOBALS, ...TEMPLATE_LOWERING_TARGETS],
|
|
45234
|
+
"@statorjs/stator/template"
|
|
45235
|
+
);
|
|
45236
|
+
var SHELL_PRIMITIVES_IMPORT = importLine(
|
|
45237
|
+
[
|
|
45238
|
+
...TEMPLATE_AUTHOR_GLOBALS,
|
|
45239
|
+
...TEMPLATE_LOWERING_TARGETS.filter((n) => n !== "itemBind"),
|
|
45240
|
+
...ISLAND_SHELL_EXTRAS
|
|
45241
|
+
],
|
|
45242
|
+
"@statorjs/stator/template"
|
|
45243
|
+
);
|
|
45203
45244
|
function compile(source, opts = {}) {
|
|
45204
45245
|
const { frontmatter, template, styles, scripts, scriptOffsets, templateOffset } = splitStator(source);
|
|
45205
45246
|
const kind = opts.kind ?? "component";
|
|
@@ -45209,17 +45250,14 @@ function compile(source, opts = {}) {
|
|
|
45209
45250
|
const script = scripts.join("\n");
|
|
45210
45251
|
if (script.trim()) {
|
|
45211
45252
|
if (analyzeScriptClasses(script).length > 0) {
|
|
45212
|
-
|
|
45213
|
-
throw new CompileError(
|
|
45214
|
-
`stator: an island file (a template with a StatorElement <script>) can't have frontmatter \u2014 the fence would never run: the island's shell renders from props. Move the server work into the route or component that renders this island and pass the results as props.`,
|
|
45215
|
-
locAt(source, 0, opts.id)
|
|
45216
|
-
);
|
|
45217
|
-
}
|
|
45253
|
+
const fm2 = processFrontmatter(frontmatter, "island", source, opts.id);
|
|
45218
45254
|
return compileClient(template, script, {
|
|
45219
45255
|
hash,
|
|
45220
45256
|
scopeAttr,
|
|
45221
45257
|
styles,
|
|
45222
|
-
file: opts.id
|
|
45258
|
+
file: opts.id,
|
|
45259
|
+
fm: fm2,
|
|
45260
|
+
source
|
|
45223
45261
|
});
|
|
45224
45262
|
}
|
|
45225
45263
|
throw new CompileError(
|
|
@@ -45260,6 +45298,17 @@ function compileClient(template, script, ctx) {
|
|
|
45260
45298
|
const tags = /* @__PURE__ */ new Set([root2.tag]);
|
|
45261
45299
|
analyzeClient(script, tags, { file: ctx.file });
|
|
45262
45300
|
const cls = classes.find((c) => pascalToKebab(c.name) === root2.tag);
|
|
45301
|
+
if (ctx.fm && cls) {
|
|
45302
|
+
const fenceNames = fenceBindingNames(ctx.fm);
|
|
45303
|
+
for (const field of cls.useFields.keys()) {
|
|
45304
|
+
if (fenceNames.has(field)) {
|
|
45305
|
+
throw new CompileError(
|
|
45306
|
+
`stator: "${field}" is both a fence binding and a use() field \u2014 the template couldn't tell the server value from the client machine. Rename one.`,
|
|
45307
|
+
ctx.source ? locAt(ctx.source, 0, ctx.file) : void 0
|
|
45308
|
+
);
|
|
45309
|
+
}
|
|
45310
|
+
}
|
|
45311
|
+
}
|
|
45263
45312
|
if (!cls) {
|
|
45264
45313
|
throw new CompileError(
|
|
45265
45314
|
`stator: internal \u2014 no exported class matches root <${root2.tag}> after name validation`
|
|
@@ -45282,9 +45331,13 @@ function compileClient(template, script, ctx) {
|
|
|
45282
45331
|
const attrDecl = `{ ${[...cls.staticAttrs].map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ")} }`;
|
|
45283
45332
|
const rootScope = ctx.scopeAttr ? ` data-s-${ctx.hash}` : "";
|
|
45284
45333
|
const serverCode = [
|
|
45285
|
-
|
|
45334
|
+
SHELL_PRIMITIVES_IMPORT,
|
|
45335
|
+
...ctx.fm?.hoisted ? [ctx.fm.hoisted] : [],
|
|
45286
45336
|
"",
|
|
45287
45337
|
`export default function (props = {}) {`,
|
|
45338
|
+
// The fence body runs here — per shell render, server only, ahead of
|
|
45339
|
+
// the template so its bindings are in scope for the interpolations.
|
|
45340
|
+
...ctx.fm?.body ? [ctx.fm.body] : [],
|
|
45288
45341
|
` const __inner = ${innerExpr}`,
|
|
45289
45342
|
` const __attrs = clientShellAttrs(props, ${attrDecl}, ${JSON.stringify(root2.rootAttrs)})`,
|
|
45290
45343
|
` return createHtmlFragment(\`<${root2.tag}\${__attrs}${rootScope}>\` + __inner.html + \`</${root2.tag}>\`)`,
|
|
@@ -45382,6 +45435,12 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45382
45435
|
const repls = [];
|
|
45383
45436
|
const visit = (n) => {
|
|
45384
45437
|
if (import_typescript4.default.isCallExpression(n) && isStatorCall(n, "props")) {
|
|
45438
|
+
if (kind === "island") {
|
|
45439
|
+
throw new CompileError(
|
|
45440
|
+
"stator: Stator.props() is not available in an island's fence \u2014 island props are declared by `static attrs` on the element class, and richer values arrive through the hydrate pattern (the shell renders with the props of its use site).",
|
|
45441
|
+
locInFm(n)
|
|
45442
|
+
);
|
|
45443
|
+
}
|
|
45385
45444
|
if (kind === "route") {
|
|
45386
45445
|
throw new CompileError(
|
|
45387
45446
|
"stator: Stator.props() is not available in a route page (a route has no parent props). Use Stator.reads([...]) to access machines.",
|
|
@@ -45412,6 +45471,12 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45412
45471
|
return;
|
|
45413
45472
|
}
|
|
45414
45473
|
if (import_typescript4.default.isCallExpression(n) && isStatorCall(n, "forwarded")) {
|
|
45474
|
+
if (kind === "island") {
|
|
45475
|
+
throw new CompileError(
|
|
45476
|
+
"stator: Stator.forwarded() is not available in an island's fence.",
|
|
45477
|
+
locInFm(n)
|
|
45478
|
+
);
|
|
45479
|
+
}
|
|
45415
45480
|
if (kind === "route") {
|
|
45416
45481
|
throw new CompileError(
|
|
45417
45482
|
"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.",
|
|
@@ -45455,6 +45520,38 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45455
45520
|
pragmas
|
|
45456
45521
|
};
|
|
45457
45522
|
}
|
|
45523
|
+
function fenceBindingNames(fm) {
|
|
45524
|
+
const names = /* @__PURE__ */ new Set();
|
|
45525
|
+
const sf = import_typescript4.default.createSourceFile(
|
|
45526
|
+
"fence.ts",
|
|
45527
|
+
`${fm.hoisted}
|
|
45528
|
+
${fm.body}`,
|
|
45529
|
+
import_typescript4.default.ScriptTarget.Latest,
|
|
45530
|
+
true,
|
|
45531
|
+
import_typescript4.default.ScriptKind.TS
|
|
45532
|
+
);
|
|
45533
|
+
const bind = (n) => {
|
|
45534
|
+
if (import_typescript4.default.isIdentifier(n)) names.add(n.text);
|
|
45535
|
+
else for (const el of n.elements) if (import_typescript4.default.isBindingElement(el)) bind(el.name);
|
|
45536
|
+
};
|
|
45537
|
+
for (const stmt of sf.statements) {
|
|
45538
|
+
if (import_typescript4.default.isImportDeclaration(stmt) && stmt.importClause) {
|
|
45539
|
+
const c = stmt.importClause;
|
|
45540
|
+
if (c.name) names.add(c.name.text);
|
|
45541
|
+
if (c.namedBindings) {
|
|
45542
|
+
if (import_typescript4.default.isNamespaceImport(c.namedBindings)) names.add(c.namedBindings.name.text);
|
|
45543
|
+
else for (const s of c.namedBindings.elements) names.add(s.name.text);
|
|
45544
|
+
}
|
|
45545
|
+
} else if (import_typescript4.default.isVariableStatement(stmt)) {
|
|
45546
|
+
for (const d of stmt.declarationList.declarations) bind(d.name);
|
|
45547
|
+
} else if (import_typescript4.default.isFunctionDeclaration(stmt) && stmt.name) {
|
|
45548
|
+
names.add(stmt.name.text);
|
|
45549
|
+
} else if (import_typescript4.default.isClassDeclaration(stmt) && stmt.name) {
|
|
45550
|
+
names.add(stmt.name.text);
|
|
45551
|
+
}
|
|
45552
|
+
}
|
|
45553
|
+
return names;
|
|
45554
|
+
}
|
|
45458
45555
|
function emitComponent(fm, htmlExpr, meta) {
|
|
45459
45556
|
let param = "";
|
|
45460
45557
|
if (fm.propsType && meta.usesChildren) param = `props: ${fm.propsType} & { children?: any }`;
|
|
@@ -45578,16 +45675,8 @@ var import_typescript6 = __toESM(require("typescript"), 1);
|
|
|
45578
45675
|
|
|
45579
45676
|
// ../stator/src/compiler/virtual-code.ts
|
|
45580
45677
|
var import_typescript7 = __toESM(require("typescript"), 1);
|
|
45581
|
-
var TEMPLATE_GLOBALS =
|
|
45582
|
-
var CLIENT_GLOBALS =
|
|
45583
|
-
"StatorElement",
|
|
45584
|
-
"use",
|
|
45585
|
-
"machine",
|
|
45586
|
-
"defineElement",
|
|
45587
|
-
"bind",
|
|
45588
|
-
"effect",
|
|
45589
|
-
"dispatch"
|
|
45590
|
-
];
|
|
45678
|
+
var TEMPLATE_GLOBALS = TEMPLATE_AUTHOR_GLOBALS;
|
|
45679
|
+
var CLIENT_GLOBALS = CLIENT_AUTHOR_GLOBALS;
|
|
45591
45680
|
function userImportedLocals(code, modulePath) {
|
|
45592
45681
|
const locals = /* @__PURE__ */ new Set();
|
|
45593
45682
|
const re = new RegExp(
|
|
@@ -45789,6 +45878,25 @@ function buildClientTsx(regions) {
|
|
|
45789
45878
|
const mappings = [];
|
|
45790
45879
|
const userScript = regions.scripts.map((s) => s.content).join("\n");
|
|
45791
45880
|
let code = injectImports(TEMPLATE_GLOBALS, "@statorjs/stator/template", userScript) + injectImports(CLIENT_GLOBALS, "@statorjs/stator/client", userScript) + AMBIENT_TYPE_IMPORTS + STATOR_AMBIENT;
|
|
45881
|
+
const fm = regions.frontmatter?.content ?? "";
|
|
45882
|
+
if (fm.trim()) {
|
|
45883
|
+
const fmOffset2 = regions.frontmatter?.contentOffset ?? 0;
|
|
45884
|
+
const { hoisted, body } = splitFrontmatter(fm, fmOffset2);
|
|
45885
|
+
for (const seg of hoisted) {
|
|
45886
|
+
if (userScript.includes(seg.text.trim())) continue;
|
|
45887
|
+
push(mappings, seg.sourceOffset, code.length, seg.text.length);
|
|
45888
|
+
code += `${seg.text}
|
|
45889
|
+
`;
|
|
45890
|
+
}
|
|
45891
|
+
code += "function __statorFence(props: Record<string, unknown>) {\n";
|
|
45892
|
+
for (const seg of body) {
|
|
45893
|
+
code += " ";
|
|
45894
|
+
push(mappings, seg.sourceOffset, code.length, seg.text.length);
|
|
45895
|
+
code += `${seg.text}
|
|
45896
|
+
`;
|
|
45897
|
+
}
|
|
45898
|
+
code += "}\nvoid __statorFence\n";
|
|
45899
|
+
}
|
|
45792
45900
|
for (const script of regions.scripts) {
|
|
45793
45901
|
push(mappings, script.contentOffset, code.length, script.content.length);
|
|
45794
45902
|
code += `${script.content}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statorjs/language-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
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": "2.0
|
|
36
|
+
"@statorjs/stator": "2.1.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"typescript": "^5.6.0"
|