@statorjs/language-server 0.1.19 → 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 -14
- 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,11 +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) {
|
|
45253
|
+
const fm2 = processFrontmatter(frontmatter, "island", source, opts.id);
|
|
45212
45254
|
return compileClient(template, script, {
|
|
45213
45255
|
hash,
|
|
45214
45256
|
scopeAttr,
|
|
45215
45257
|
styles,
|
|
45216
|
-
file: opts.id
|
|
45258
|
+
file: opts.id,
|
|
45259
|
+
fm: fm2,
|
|
45260
|
+
source
|
|
45217
45261
|
});
|
|
45218
45262
|
}
|
|
45219
45263
|
throw new CompileError(
|
|
@@ -45254,6 +45298,17 @@ function compileClient(template, script, ctx) {
|
|
|
45254
45298
|
const tags = /* @__PURE__ */ new Set([root2.tag]);
|
|
45255
45299
|
analyzeClient(script, tags, { file: ctx.file });
|
|
45256
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
|
+
}
|
|
45257
45312
|
if (!cls) {
|
|
45258
45313
|
throw new CompileError(
|
|
45259
45314
|
`stator: internal \u2014 no exported class matches root <${root2.tag}> after name validation`
|
|
@@ -45276,9 +45331,13 @@ function compileClient(template, script, ctx) {
|
|
|
45276
45331
|
const attrDecl = `{ ${[...cls.staticAttrs].map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ")} }`;
|
|
45277
45332
|
const rootScope = ctx.scopeAttr ? ` data-s-${ctx.hash}` : "";
|
|
45278
45333
|
const serverCode = [
|
|
45279
|
-
|
|
45334
|
+
SHELL_PRIMITIVES_IMPORT,
|
|
45335
|
+
...ctx.fm?.hoisted ? [ctx.fm.hoisted] : [],
|
|
45280
45336
|
"",
|
|
45281
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] : [],
|
|
45282
45341
|
` const __inner = ${innerExpr}`,
|
|
45283
45342
|
` const __attrs = clientShellAttrs(props, ${attrDecl}, ${JSON.stringify(root2.rootAttrs)})`,
|
|
45284
45343
|
` return createHtmlFragment(\`<${root2.tag}\${__attrs}${rootScope}>\` + __inner.html + \`</${root2.tag}>\`)`,
|
|
@@ -45376,6 +45435,12 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45376
45435
|
const repls = [];
|
|
45377
45436
|
const visit = (n) => {
|
|
45378
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
|
+
}
|
|
45379
45444
|
if (kind === "route") {
|
|
45380
45445
|
throw new CompileError(
|
|
45381
45446
|
"stator: Stator.props() is not available in a route page (a route has no parent props). Use Stator.reads([...]) to access machines.",
|
|
@@ -45406,6 +45471,12 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45406
45471
|
return;
|
|
45407
45472
|
}
|
|
45408
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
|
+
}
|
|
45409
45480
|
if (kind === "route") {
|
|
45410
45481
|
throw new CompileError(
|
|
45411
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.",
|
|
@@ -45449,6 +45520,38 @@ function processFrontmatter(fm, kind, source, file) {
|
|
|
45449
45520
|
pragmas
|
|
45450
45521
|
};
|
|
45451
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
|
+
}
|
|
45452
45555
|
function emitComponent(fm, htmlExpr, meta) {
|
|
45453
45556
|
let param = "";
|
|
45454
45557
|
if (fm.propsType && meta.usesChildren) param = `props: ${fm.propsType} & { children?: any }`;
|
|
@@ -45572,16 +45675,8 @@ var import_typescript6 = __toESM(require("typescript"), 1);
|
|
|
45572
45675
|
|
|
45573
45676
|
// ../stator/src/compiler/virtual-code.ts
|
|
45574
45677
|
var import_typescript7 = __toESM(require("typescript"), 1);
|
|
45575
|
-
var TEMPLATE_GLOBALS =
|
|
45576
|
-
var CLIENT_GLOBALS =
|
|
45577
|
-
"StatorElement",
|
|
45578
|
-
"use",
|
|
45579
|
-
"machine",
|
|
45580
|
-
"defineElement",
|
|
45581
|
-
"bind",
|
|
45582
|
-
"effect",
|
|
45583
|
-
"dispatch"
|
|
45584
|
-
];
|
|
45678
|
+
var TEMPLATE_GLOBALS = TEMPLATE_AUTHOR_GLOBALS;
|
|
45679
|
+
var CLIENT_GLOBALS = CLIENT_AUTHOR_GLOBALS;
|
|
45585
45680
|
function userImportedLocals(code, modulePath) {
|
|
45586
45681
|
const locals = /* @__PURE__ */ new Set();
|
|
45587
45682
|
const re = new RegExp(
|
|
@@ -45783,6 +45878,25 @@ function buildClientTsx(regions) {
|
|
|
45783
45878
|
const mappings = [];
|
|
45784
45879
|
const userScript = regions.scripts.map((s) => s.content).join("\n");
|
|
45785
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
|
+
}
|
|
45786
45900
|
for (const script of regions.scripts) {
|
|
45787
45901
|
push(mappings, script.contentOffset, code.length, script.content.length);
|
|
45788
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"
|