@stacksjs/stx 0.2.174 → 0.2.176
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/a11y.d.ts +72 -2
- package/dist/a11y.js +25 -10
- package/dist/cli.js +1045 -930
- package/dist/client-script.js +1 -0
- package/dist/component-renderer.js +17 -0
- package/dist/craft.js +561 -453
- package/dist/includes.js +8 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/process.js +2 -1
- package/dist/props.d.ts +51 -8
- package/dist/pwa.js +512 -404
- package/dist/resolve-stx-targets.d.ts +49 -0
- package/dist/resolve-stx-targets.js +38 -0
- package/dist/runtime-globals.d.ts +24 -0
- package/dist/runtime-globals.js +16 -0
- package/dist/runtime-injection.d.ts +36 -0
- package/dist/runtime-injection.js +15 -0
- package/dist/server-bindings.js +3 -0
- package/dist/signal-processing.js +1 -1
- package/dist/signals.js +30 -27
- package/dist/ssg.d.ts +23 -0
- package/dist/ssg.js +509 -397
- package/dist/stx-virtual-ts.d.ts +27 -3
- package/dist/stx-virtual-ts.js +36 -0
- package/dist/typecheck.js +96 -62
- package/dist/types/config-types.d.ts +24 -0
- package/dist/utils.js +5 -4
- package/package.json +5 -5
package/dist/stx-virtual-ts.d.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Pull the script blocks out of a `.stx` source, with the line each body starts on.
|
|
3
3
|
*
|
|
4
4
|
* `<script server>` and `<script client>` are recognised by attribute. A bare
|
|
5
|
-
* `<script>` is reported as `plain
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* `<script>` is reported as `plain` so a caller can tell which tag the author
|
|
6
|
+
* actually wrote — NOT so it can be skipped. It is a client block; `client` is
|
|
7
|
+
* an explicit alias for the default, not a separate kind (stacksjs/stx#1920).
|
|
8
8
|
*/
|
|
9
9
|
export declare function extractScriptBlocks(source: string): ScriptBlock[];
|
|
10
10
|
/**
|
|
@@ -45,6 +45,30 @@ export declare function substituteInterpolations(value: string): string;
|
|
|
45
45
|
* fit and would shift the line.
|
|
46
46
|
*/
|
|
47
47
|
export declare function substituteInterpolationsInPlace(code: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Blank stx directives that a script body writes to generate JavaScript.
|
|
50
|
+
*
|
|
51
|
+
* A template can loop inside a script — building a lookup table from server
|
|
52
|
+
* data is the obvious use — and the directive is expanded away long before the
|
|
53
|
+
* browser sees it:
|
|
54
|
+
*
|
|
55
|
+
* const data = {
|
|
56
|
+
* @foreach(features as f)
|
|
57
|
+
* '{{ f.id }}': { title: '{{ f.title }}' },
|
|
58
|
+
* @endforeach
|
|
59
|
+
* }
|
|
60
|
+
*
|
|
61
|
+
* To TypeScript the directive line is a syntax error, and one of those mutes
|
|
62
|
+
* semantic checking for the WHOLE program, not just the file. So checking bare
|
|
63
|
+
* `<script>` blocks (#1920) made a valid page report 37 invented syntax errors
|
|
64
|
+
* — and a checker that invents errors gets muted, which is the failure mode
|
|
65
|
+
* this file exists to avoid.
|
|
66
|
+
*
|
|
67
|
+
* Blanked rather than removed so every line number after it still points at the
|
|
68
|
+
* line the author wrote. Only a directive ALONE on its line is matched: that is
|
|
69
|
+
* how they are written, and it cannot swallow code sharing the line.
|
|
70
|
+
*/
|
|
71
|
+
export declare function blankScriptDirectives(code: string): string;
|
|
48
72
|
/**
|
|
49
73
|
* Every checkable expression in the markup, with the position it occupies.
|
|
50
74
|
*
|
package/dist/stx-virtual-ts.js
CHANGED
|
@@ -105,6 +105,42 @@ export function substituteInterpolationsInPlace(code) {
|
|
|
105
105
|
`.repeat(newlines)}`;
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
|
+
const SCRIPT_BODY_DIRECTIVES = [
|
|
109
|
+
"foreach",
|
|
110
|
+
"endforeach",
|
|
111
|
+
"forelse",
|
|
112
|
+
"endforelse",
|
|
113
|
+
"for",
|
|
114
|
+
"endfor",
|
|
115
|
+
"while",
|
|
116
|
+
"endwhile",
|
|
117
|
+
"empty",
|
|
118
|
+
"if",
|
|
119
|
+
"elseif",
|
|
120
|
+
"else",
|
|
121
|
+
"endif",
|
|
122
|
+
"unless",
|
|
123
|
+
"endunless",
|
|
124
|
+
"isset",
|
|
125
|
+
"endisset",
|
|
126
|
+
"switch",
|
|
127
|
+
"case",
|
|
128
|
+
"default",
|
|
129
|
+
"endswitch",
|
|
130
|
+
"auth",
|
|
131
|
+
"endauth",
|
|
132
|
+
"guest",
|
|
133
|
+
"endguest",
|
|
134
|
+
"env",
|
|
135
|
+
"endenv",
|
|
136
|
+
"once",
|
|
137
|
+
"endonce",
|
|
138
|
+
"break",
|
|
139
|
+
"continue"
|
|
140
|
+
], SCRIPT_BODY_DIRECTIVE_RE = new RegExp(String.raw`^[ \t]*@(?:${SCRIPT_BODY_DIRECTIVES.join("|")})\b[ \t]*(\([^\n)]*\))?[ \t]*$`, "gm");
|
|
141
|
+
export function blankScriptDirectives(code) {
|
|
142
|
+
return code.replace(SCRIPT_BODY_DIRECTIVE_RE, (match) => match.replace(/[^\n]/g, " "));
|
|
143
|
+
}
|
|
108
144
|
const NON_EXPRESSION_ATTRS = new Set([
|
|
109
145
|
"x-cloak",
|
|
110
146
|
"x-ref",
|
package/dist/typecheck.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
clientPayloadDeclarations,
|
|
10
10
|
scrapedBridgeNames,
|
|
11
11
|
serverContextDeclarations,
|
|
12
|
+
blankScriptDirectives,
|
|
12
13
|
substituteInterpolationsInPlace
|
|
13
14
|
} from "./stx-virtual-ts.js";
|
|
14
15
|
export {
|
|
@@ -17,12 +18,27 @@ export {
|
|
|
17
18
|
} from "./stx-virtual-ts.js";
|
|
18
19
|
export function buildVirtualSource(block, serverCode = "") {
|
|
19
20
|
const leadingNewlines = block.startLine > 1 ? `
|
|
20
|
-
`.repeat(block.startLine - 1) : "", code = substituteInterpolationsInPlace(block.code), payload = block.kind === "client" || block.kind === "plain" ? clientPayloadDeclarations(serverCode) : "";
|
|
21
|
+
`.repeat(block.startLine - 1) : "", code = blankScriptDirectives(substituteInterpolationsInPlace(block.code)), payload = block.kind === "client" || block.kind === "plain" ? clientPayloadDeclarations(serverCode) : "";
|
|
21
22
|
return `${leadingNewlines + code}
|
|
22
23
|
${payload}
|
|
23
24
|
export {}
|
|
24
25
|
`;
|
|
25
26
|
}
|
|
27
|
+
function virtualStxModuleDeclaration(files) {
|
|
28
|
+
const anchor = files.length > 0 ? path.dirname(path.resolve(files[0])) : process.cwd();
|
|
29
|
+
try {
|
|
30
|
+
Bun.resolveSync("@stacksjs/stx", anchor);
|
|
31
|
+
} catch {
|
|
32
|
+
return "";
|
|
33
|
+
}
|
|
34
|
+
return [
|
|
35
|
+
"// Generated \u2014 `stx` is the virtual specifier client-script.ts strips.",
|
|
36
|
+
"declare module 'stx' {",
|
|
37
|
+
" export * from '@stacksjs/stx'",
|
|
38
|
+
"}"
|
|
39
|
+
].join(`
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
26
42
|
export function virtualPathFor(filePath, kind, index) {
|
|
27
43
|
return `${filePath}.__stx_${kind}${index}.ts`;
|
|
28
44
|
}
|
|
@@ -39,6 +55,9 @@ export function findRuntimeTypeDeclarations() {
|
|
|
39
55
|
return null;
|
|
40
56
|
}
|
|
41
57
|
const TSC_LINE_RE = /^(.*?)\((\d+),(\d+)\):\s+(error|warning)\s+TS(\d+):\s+(.*)$/;
|
|
58
|
+
function isSyntactic(code) {
|
|
59
|
+
return code >= 1000 && code < 2000;
|
|
60
|
+
}
|
|
42
61
|
function readProjectPathAliases(startDir) {
|
|
43
62
|
let dir = path.resolve(startDir), configPath;
|
|
44
63
|
for (;; ) {
|
|
@@ -130,15 +149,13 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
130
149
|
const source = await Bun.file(file).text(), blocks = extractScriptBlocks(source).filter((b) => {
|
|
131
150
|
if (b.kind === "server")
|
|
132
151
|
return checkServer;
|
|
133
|
-
|
|
134
|
-
return checkClient;
|
|
135
|
-
return !1;
|
|
152
|
+
return checkClient;
|
|
136
153
|
}), serverCode = extractScriptBlocks(source).filter((block) => block.kind === "server").map((block) => block.code).join(`
|
|
137
154
|
`);
|
|
138
155
|
if (checkClient && serverCode) {
|
|
139
|
-
const clientBlocks = blocks.filter((block) => block.kind
|
|
156
|
+
const clientBlocks = blocks.filter((block) => block.kind !== "server"), names = [...new Set(clientBlocks.flatMap((block) => scrapedBridgeNames(serverCode, block.code)))];
|
|
140
157
|
if (names.length > 0)
|
|
141
|
-
scrapedByFile.set(file, { names, line: clientBlocks[0].startLine });
|
|
158
|
+
scrapedByFile.set(file, { names, line: clientBlocks[0].startLine, kind: clientBlocks[0].kind });
|
|
142
159
|
}
|
|
143
160
|
const templateBuffer = checkTemplates ? buildVirtualTypeScript(source, { runtimeGlobals: !runtimeTypes }) : null, expressions = templateBuffer ? [...templateBuffer.lineMap.values()].filter((m) => m.expression).length : 0;
|
|
144
161
|
if (blocks.length === 0 && expressions === 0)
|
|
@@ -169,8 +186,9 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
169
186
|
const globalsDts = `${stateDir()}/typecheck/__stx_globals.d.ts`, globalDecls = [
|
|
170
187
|
"// Generated \u2014 the context serve.ts injects into <script server> blocks.",
|
|
171
188
|
serverContextDeclarations(),
|
|
172
|
-
...runtimeTypes ? [] : ["declare const window: any", ...STX_RUNTIME_GLOBALS.map((name) => `declare const ${name}: any`)]
|
|
173
|
-
|
|
189
|
+
...runtimeTypes ? [] : ["declare const window: any", ...STX_RUNTIME_GLOBALS.map((name) => `declare const ${name}: any`)],
|
|
190
|
+
virtualStxModuleDeclaration(files)
|
|
191
|
+
].filter(Boolean).join(`
|
|
174
192
|
`), workDir = `${stateDir()}/typecheck`;
|
|
175
193
|
await Bun.$`rm -rf ${workDir}`.quiet().nothrow();
|
|
176
194
|
await Bun.$`mkdir -p ${workDir}`.quiet().nothrow();
|
|
@@ -182,64 +200,80 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
182
200
|
await Bun.write(`${workDir}/${safe}`, meta.source);
|
|
183
201
|
writtenToOrigin.set(safe, meta);
|
|
184
202
|
}
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
const compilerOptions = {
|
|
204
|
+
target: "ESNext",
|
|
205
|
+
module: "ESNext",
|
|
206
|
+
moduleResolution: "bundler",
|
|
207
|
+
strict: !0,
|
|
208
|
+
noEmit: !0,
|
|
209
|
+
skipLibCheck: !0,
|
|
210
|
+
allowJs: !0,
|
|
211
|
+
esModuleInterop: !0,
|
|
212
|
+
resolveJsonModule: !0,
|
|
213
|
+
lib: ["ESNext", "DOM", "DOM.Iterable"],
|
|
214
|
+
types: [],
|
|
215
|
+
...readProjectPathAliases(files.length > 0 ? path.dirname(path.resolve(files[0])) : process.cwd()),
|
|
216
|
+
...options.compilerOptions ?? {}
|
|
217
|
+
}, runTsc = async (names, pass) => {
|
|
218
|
+
const tsconfigPath = `${workDir}/tsconfig${pass === 1 ? "" : `.${pass}`}.json`;
|
|
219
|
+
await Bun.write(tsconfigPath, JSON.stringify({
|
|
220
|
+
compilerOptions,
|
|
221
|
+
files: names.map((name) => `${workDir}/${name}`).concat(globalsDts, ...ambient)
|
|
222
|
+
}, null, 2));
|
|
223
|
+
const proc = Bun.spawnSync(["bun", "x", "tsc", "-p", tsconfigPath, "--pretty", "false"], {
|
|
224
|
+
stdout: "pipe",
|
|
225
|
+
stderr: "pipe"
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
output: new TextDecoder().decode(proc.stdout) + new TextDecoder().decode(proc.stderr),
|
|
229
|
+
exitCode: proc.exitCode ?? 0
|
|
230
|
+
};
|
|
231
|
+
}, first = await runTsc([...writtenToOrigin.keys()], 1), output = first.output, diagnostics = [], exitCode = first.exitCode;
|
|
208
232
|
let printedDiagnostics = 0;
|
|
209
233
|
const ambientBasenames = new Set(ambient.map((lib) => lib.split("/").pop()));
|
|
210
234
|
let ambientDiagnostics = 0;
|
|
211
|
-
|
|
235
|
+
const unparseable = new Set, parseTscOutput = (text) => {
|
|
236
|
+
for (const rawLine of text.split(`
|
|
212
237
|
`)) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
continue;
|
|
216
|
-
printedDiagnostics++;
|
|
217
|
-
if (ambientBasenames.has(m[1].split("/").pop()))
|
|
218
|
-
ambientDiagnostics++;
|
|
219
|
-
const [, filePart, lineStr, colStr, category, code, message] = m, entry = writtenToOrigin.get(filePart.split("/").pop());
|
|
220
|
-
if (!entry)
|
|
221
|
-
continue;
|
|
222
|
-
let line = Number(lineStr), column = Number(colStr), expression;
|
|
223
|
-
if (entry.virtual) {
|
|
224
|
-
const at = resolvePosition(entry.virtual, line, column);
|
|
225
|
-
if (!at?.expression)
|
|
238
|
+
const m = rawLine.match(TSC_LINE_RE);
|
|
239
|
+
if (!m)
|
|
226
240
|
continue;
|
|
227
|
-
|
|
241
|
+
printedDiagnostics++;
|
|
242
|
+
if (ambientBasenames.has(m[1].split("/").pop()))
|
|
243
|
+
ambientDiagnostics++;
|
|
244
|
+
const [, filePart, lineStr, colStr, category, code, message] = m, written = filePart.split("/").pop(), entry = writtenToOrigin.get(written);
|
|
245
|
+
if (!entry)
|
|
228
246
|
continue;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
247
|
+
if (isSyntactic(Number(code)))
|
|
248
|
+
unparseable.add(written);
|
|
249
|
+
let line = Number(lineStr), column = Number(colStr), expression;
|
|
250
|
+
if (entry.virtual) {
|
|
251
|
+
const at = resolvePosition(entry.virtual, line, column);
|
|
252
|
+
if (!at?.expression)
|
|
253
|
+
continue;
|
|
254
|
+
if (Number(code) === 2774)
|
|
255
|
+
continue;
|
|
256
|
+
line = at.line;
|
|
257
|
+
column = at.column;
|
|
258
|
+
expression = at.expression.code.trim();
|
|
259
|
+
}
|
|
260
|
+
diagnostics.push({
|
|
261
|
+
file: entry.origin,
|
|
262
|
+
line,
|
|
263
|
+
column,
|
|
264
|
+
code: Number(code),
|
|
265
|
+
message,
|
|
266
|
+
category: category === "error" ? "error" : "warning",
|
|
267
|
+
blockKind: entry.kind,
|
|
268
|
+
expression
|
|
269
|
+
});
|
|
232
270
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
category: category === "error" ? "error" : "warning",
|
|
240
|
-
blockKind: entry.kind,
|
|
241
|
-
expression
|
|
242
|
-
});
|
|
271
|
+
};
|
|
272
|
+
parseTscOutput(output);
|
|
273
|
+
const firstPassPrinted = printedDiagnostics, firstPassAmbient = ambientDiagnostics;
|
|
274
|
+
if (unparseable.size > 0 && unparseable.size < writtenToOrigin.size) {
|
|
275
|
+
const survivors = [...writtenToOrigin.keys()].filter((name) => !unparseable.has(name));
|
|
276
|
+
parseTscOutput((await runTsc(survivors, 2)).output);
|
|
243
277
|
}
|
|
244
278
|
if (checkClient)
|
|
245
279
|
for (const [file, scraped] of scrapedByFile) {
|
|
@@ -252,7 +286,7 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
252
286
|
code: 0,
|
|
253
287
|
message: `${scraped.names.length === 1 ? "1 value reaches" : `${scraped.names.length} values reach`} this block on the implicit bridge and ${scraped.names.length === 1 ? "is" : "are"} untyped: ${scraped.names.join(", ")}. Declare them with defineClientPayload({ ${scraped.names.join(", ")} }) in the server block to have them checked.`,
|
|
254
288
|
category: "warning",
|
|
255
|
-
blockKind:
|
|
289
|
+
blockKind: scraped.kind
|
|
256
290
|
});
|
|
257
291
|
}
|
|
258
292
|
const seen = new Set, unique = diagnostics.filter((d) => {
|
|
@@ -263,7 +297,7 @@ export async function typecheckStxFiles(files, options = {}) {
|
|
|
263
297
|
return !0;
|
|
264
298
|
});
|
|
265
299
|
unique.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.column - b.column);
|
|
266
|
-
const brokenLib =
|
|
300
|
+
const brokenLib = firstPassAmbient > 0 && unique.length === 0, failure = brokenLib || exitCode !== 0 && firstPassPrinted === 0 ? `${brokenLib ? "a file passed with --lib has errors of its own, so nothing in your code was checked" : `tsc exited ${exitCode} without reporting any diagnostic, so nothing was checked`}. ` + "A syntax error in an ambient declaration file does this \u2014 skipLibCheck suppresses " + `SEMANTIC diagnostics only. tsc said:
|
|
267
301
|
${output.trim().split(`
|
|
268
302
|
`).slice(0, 12).join(`
|
|
269
303
|
`) || "(no output)"}` : void 0;
|
|
@@ -271,7 +305,7 @@ ${output.trim().split(`
|
|
|
271
305
|
}
|
|
272
306
|
export function formatTypecheckDiagnostics(diagnostics) {
|
|
273
307
|
return diagnostics.map((d) => {
|
|
274
|
-
const where = d.blockKind === "template" ? `[template: ${d.expression ?? ""}]` : `[<script ${d.blockKind}
|
|
308
|
+
const where = d.blockKind === "template" ? `[template: ${d.expression ?? ""}]` : `[${d.blockKind === "plain" ? "<script>" : `<script ${d.blockKind}>`}]`;
|
|
275
309
|
return `${d.file}:${d.line}:${d.column} ${d.category} TS${d.code} ${d.message} ${where}`;
|
|
276
310
|
}).join(`
|
|
277
311
|
`);
|
|
@@ -594,6 +594,30 @@ export interface StxConfig {
|
|
|
594
594
|
enabled: boolean;
|
|
595
595
|
/** Path to partials directory, defaults to 'partials' in the same directory as the template */
|
|
596
596
|
partialsDir: string;
|
|
597
|
+
/**
|
|
598
|
+
* Called when an `@include` fails, instead of the failure being silent.
|
|
599
|
+
*
|
|
600
|
+
* A failed include renders the error where the markup should have been. In dev
|
|
601
|
+
* that is the right call — you see it as soon as you look. In a build it
|
|
602
|
+
* produces a file nobody would knowingly deploy, and nothing else can see it:
|
|
603
|
+
* one app shipped pre-rendered pages whose header, footer, hero and CTA were
|
|
604
|
+
* all replaced by an ENOENT banner while the build printed `Failed: 0` and
|
|
605
|
+
* exited 0 (stacksjs/stx#1921).
|
|
606
|
+
*
|
|
607
|
+
* The rendered output is unchanged — this only carries the fact out, so a
|
|
608
|
+
* caller that builds files can decide to fail. `partialsDir` is included
|
|
609
|
+
* because "it looked in the wrong place" is the usual cause and the resolved
|
|
610
|
+
* path is what makes it a ten-second fix.
|
|
611
|
+
*/
|
|
612
|
+
onIncludeError?: (failure: {
|
|
613
|
+
/** The path as written in the directive, e.g. `Bench/ConfirmHost`. */
|
|
614
|
+
includePath: string;
|
|
615
|
+
/** The template the directive appeared in. */
|
|
616
|
+
templatePath: string;
|
|
617
|
+
message: string;
|
|
618
|
+
/** The directory the include was resolved against. */
|
|
619
|
+
partialsDir: string;
|
|
620
|
+
}) => void;
|
|
597
621
|
/** Path to components directory, defaults to 'components' in the same directory as the template */
|
|
598
622
|
componentsDir: string;
|
|
599
623
|
/** @internal Configured component root retained while nested components resolve locally. */
|
package/dist/utils.js
CHANGED
|
@@ -558,7 +558,8 @@ ${triedPaths.map((p) => ` - ${p}`).join(`
|
|
|
558
558
|
const internalKeysToPreserve = new Set([
|
|
559
559
|
"__originalFilePath",
|
|
560
560
|
"__importedComponents",
|
|
561
|
-
COMPONENT_CLIENT_FACTORIES_CONTEXT_KEY
|
|
561
|
+
COMPONENT_CLIENT_FACTORIES_CONTEXT_KEY,
|
|
562
|
+
"__stx_client_signal_names"
|
|
562
563
|
]), filteredParentContext = {};
|
|
563
564
|
for (const [key, val] of Object.entries(parentContext))
|
|
564
565
|
if (!key.startsWith("__") || internalKeysToPreserve.has(key))
|
|
@@ -648,9 +649,9 @@ ${triedPaths.map((p) => ` - ${p}`).join(`
|
|
|
648
649
|
templateContent = templateContent.replace(/\{\{\s*text\s*\|\|\s*slot\s*\}\}/g, () => slotContent);
|
|
649
650
|
const { applySlots } = await importOnce("stx/slots", () => import("./slots.js")), { defaultSlot, namedSlots } = parsedSlotContent;
|
|
650
651
|
templateContent = await applySlots(templateContent, defaultSlot, namedSlots, componentContext);
|
|
651
|
-
const hasSignalScripts = clientScripts.some((s) => /\b(?:state|derived|effect|ref|reactive|computed|watch|watchEffect|useReactiveProp|defineProps|withDefaults|defineEmits|defineExpose|defineSlots)\s*(?:<[^<>()]*>)?\s*\(/.test(s)), clientSignalNames = componentClientSignalNames(clientScripts);
|
|
652
|
-
if (clientSignalNames.length > 0)
|
|
653
|
-
componentContext.__stx_client_signal_names = clientSignalNames;
|
|
652
|
+
const hasSignalScripts = clientScripts.some((s) => /\b(?:state|derived|effect|ref|reactive|computed|watch|watchEffect|useReactiveProp|defineProps|withDefaults|defineEmits|defineExpose|defineSlots)\s*(?:<[^<>()]*>)?\s*\(/.test(s)), clientSignalNames = componentClientSignalNames(clientScripts), inheritedClientSignalNames = Array.isArray(componentContext.__stx_client_signal_names) ? componentContext.__stx_client_signal_names : [];
|
|
653
|
+
if (clientSignalNames.length > 0 || inheritedClientSignalNames.length > 0)
|
|
654
|
+
componentContext.__stx_client_signal_names = [...new Set([...inheritedClientSignalNames, ...clientSignalNames])];
|
|
654
655
|
const componentOptions = {
|
|
655
656
|
...options,
|
|
656
657
|
_rootComponentsDir: options._rootComponentsDir || options.componentsDir,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/stx",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.176",
|
|
5
5
|
"description": "A performant UI Framework. Powered by Bun.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -117,12 +117,12 @@
|
|
|
117
117
|
"dependencies": {
|
|
118
118
|
"@cwcss/crosswind": "^0.2.14",
|
|
119
119
|
"@stacksjs/clapp": "^0.2.0",
|
|
120
|
-
"@stacksjs/desktop": "0.2.
|
|
121
|
-
"@stacksjs/sanitizer": "0.2.
|
|
120
|
+
"@stacksjs/desktop": "0.2.176",
|
|
121
|
+
"@stacksjs/sanitizer": "0.2.176",
|
|
122
122
|
"@stacksjs/ts-i18n": "^0.1.11",
|
|
123
|
-
"bun-plugin-stx": "0.2.
|
|
123
|
+
"bun-plugin-stx": "0.2.176",
|
|
124
124
|
"bunfig": "^0.15.17",
|
|
125
|
-
"stx-router": "0.2.
|
|
125
|
+
"stx-router": "0.2.176",
|
|
126
126
|
"ts-broadcasting": "^0.0.9",
|
|
127
127
|
"ts-images": "^0.1.9",
|
|
128
128
|
"ts-syntax-highlighter": "^0.2.1"
|