@wuchale/svelte 0.19.2 → 0.19.4
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/index.d.ts +3 -3
- package/dist/index.js +12 -6
- package/dist/transformer.d.ts +11 -7
- package/dist/transformer.js +31 -20
- package/package.json +4 -3
- package/src/loaders/sveltekit.ssr.svelte.js +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Adapter, AdapterArgs, CreateHeuristicOpts, HeuristicFunc, LoaderChoice } from 'wuchale';
|
|
1
|
+
import type { Adapter, AdapterArgs, CreateHeuristicOpts, DeepPartial, HeuristicFunc, LoaderChoice } from 'wuchale';
|
|
2
2
|
import { type RuntimeCtxSv } from './transformer.js';
|
|
3
3
|
export type { RuntimeCtxSv };
|
|
4
4
|
export declare function createSvelteHeuristic(opts: CreateHeuristicOpts): HeuristicFunc;
|
|
@@ -8,10 +8,10 @@ export declare const svelteKitDefaultHeuristic: HeuristicFunc;
|
|
|
8
8
|
/** Default Svelte heuristic which requires `$derived` or `$derived.by` for top level variable assignments */
|
|
9
9
|
export declare const svelteDefaultHeuristicDerivedReq: HeuristicFunc;
|
|
10
10
|
type LoadersAvailable = 'svelte' | 'sveltekit';
|
|
11
|
-
export type SvelteArgs = AdapterArgs<LoadersAvailable
|
|
11
|
+
export type SvelteArgs = AdapterArgs<LoadersAvailable>;
|
|
12
12
|
export declare const defaultArgs: SvelteArgs;
|
|
13
13
|
export declare function getDefaultLoaderPath(loader: LoaderChoice<LoadersAvailable>, bundle: boolean): string | {
|
|
14
14
|
client: string;
|
|
15
15
|
server: string;
|
|
16
16
|
} | null;
|
|
17
|
-
export declare const adapter: (args?:
|
|
17
|
+
export declare const adapter: (args?: DeepPartial<SvelteArgs>) => Adapter;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHeuristic,
|
|
1
|
+
import { createHeuristic, defaultGenerateLoadID, defaultHeuristicOpts, fillDefaults, pofile } from 'wuchale';
|
|
2
2
|
import { loaderPathResolver } from 'wuchale/adapter-utils';
|
|
3
3
|
import { pluralPattern } from 'wuchale/adapter-vanilla';
|
|
4
4
|
import { SvelteTransformer } from './transformer.js';
|
|
@@ -20,7 +20,10 @@ export function createSvelteHeuristic(opts) {
|
|
|
20
20
|
}
|
|
21
21
|
/** Default Svelte heuristic which extracts top level variable assignments as well, leading to `$derived` being auto added when needed */
|
|
22
22
|
export const svelteDefaultHeuristic = createSvelteHeuristic(defaultHeuristicOpts);
|
|
23
|
-
export const svelteKitDefaultHeuristic = createSvelteHeuristic({
|
|
23
|
+
export const svelteKitDefaultHeuristic = createSvelteHeuristic({
|
|
24
|
+
...defaultHeuristicOpts,
|
|
25
|
+
urlCalls: ['asset', 'goto', 'pushState', 'replaceState', 'resolve'],
|
|
26
|
+
});
|
|
24
27
|
/** Default Svelte heuristic which requires `$derived` or `$derived.by` for top level variable assignments */
|
|
25
28
|
export const svelteDefaultHeuristicDerivedReq = msg => {
|
|
26
29
|
const defRes = svelteDefaultHeuristic(msg);
|
|
@@ -42,17 +45,17 @@ export const defaultArgs = {
|
|
|
42
45
|
files: ['src/**/*.svelte', 'src/**/*.svelte.{js,ts}'],
|
|
43
46
|
storage: pofile(),
|
|
44
47
|
patterns: [pluralPattern],
|
|
45
|
-
heuristic:
|
|
48
|
+
heuristic: svelteDefaultHeuristic,
|
|
46
49
|
granularLoad: false,
|
|
47
50
|
bundleLoad: false,
|
|
48
51
|
generateLoadID: defaultGenerateLoadID,
|
|
49
52
|
loader: 'svelte',
|
|
50
53
|
runtime: {
|
|
51
|
-
initReactive: ({ file, funcName, module }) => {
|
|
54
|
+
initReactive: ({ file, funcName, ctx: { module } }) => {
|
|
52
55
|
const inTopLevel = funcName == null;
|
|
53
56
|
return file.endsWith('.svelte.js') || module ? inTopLevel : inTopLevel ? true : null;
|
|
54
57
|
},
|
|
55
|
-
useReactive: ({ file, funcName, module }) => {
|
|
58
|
+
useReactive: ({ file, funcName, ctx: { module } }) => {
|
|
56
59
|
const inTopLevel = funcName == null;
|
|
57
60
|
return file.endsWith('.svelte.js') || module ? inTopLevel : true;
|
|
58
61
|
},
|
|
@@ -83,7 +86,10 @@ export function getDefaultLoaderPath(loader, bundle) {
|
|
|
83
86
|
return resolveLoaderPath(loader);
|
|
84
87
|
}
|
|
85
88
|
export const adapter = (args = defaultArgs) => {
|
|
86
|
-
|
|
89
|
+
if (args.loader === 'sveltekit' && args.heuristic == null) {
|
|
90
|
+
args.heuristic = svelteKitDefaultHeuristic;
|
|
91
|
+
}
|
|
92
|
+
const { heuristic, patterns, runtime, loader, ...rest } = fillDefaults(args, defaultArgs);
|
|
87
93
|
return {
|
|
88
94
|
transform: ({ content, filename, index, expr, matchUrl }) => {
|
|
89
95
|
return new SvelteTransformer(content, filename, index, heuristic, patterns, expr, runtime, matchUrl).transformSv();
|
package/dist/transformer.d.ts
CHANGED
|
@@ -4,19 +4,20 @@ import type { CatalogExpr, CodePattern, HeuristicFunc, IndexTracker, Message, Ru
|
|
|
4
4
|
import { MixedVisitor } from 'wuchale/adapter-utils';
|
|
5
5
|
import { Transformer } from 'wuchale/adapter-vanilla';
|
|
6
6
|
type MixedNodesTypes = AST.Text | AST.Tag | AST.ElementLike | AST.Block | AST.Comment;
|
|
7
|
+
type MixedVisitorSvelte = MixedVisitor<MixedNodesTypes, AST.Text, AST.Comment, AST.ExpressionTag>;
|
|
7
8
|
export type RuntimeCtxSv = {
|
|
8
9
|
module: boolean;
|
|
9
10
|
};
|
|
10
|
-
export declare class SvelteTransformer extends Transformer
|
|
11
|
-
currentElement?: string;
|
|
11
|
+
export declare class SvelteTransformer extends Transformer {
|
|
12
|
+
currentElement?: string | undefined;
|
|
12
13
|
inCompoundText: boolean;
|
|
13
14
|
currentSnippet: number;
|
|
14
|
-
|
|
15
|
-
mixedVisitor:
|
|
16
|
-
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf
|
|
15
|
+
moduleExportExprs: AnyNode[];
|
|
16
|
+
mixedVisitor: MixedVisitorSvelte;
|
|
17
|
+
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf, matchUrl: UrlMatcher);
|
|
17
18
|
visitExpressionTag: (node: AST.ExpressionTag) => Message[];
|
|
18
19
|
visitVariableDeclarator: (node: VariableDeclarator) => Message[];
|
|
19
|
-
initMixedVisitor: () =>
|
|
20
|
+
initMixedVisitor: () => MixedVisitorSvelte;
|
|
20
21
|
visitFragment: (node: AST.Fragment) => Message[];
|
|
21
22
|
visitRegularElement: (node: AST.ElementLike) => Message[];
|
|
22
23
|
visitComponent: (node: AST.ElementLike) => Message[];
|
|
@@ -25,6 +26,9 @@ export declare class SvelteTransformer extends Transformer<RuntimeCtxSv> {
|
|
|
25
26
|
visitAttribute: (node: AST.Attribute) => Message[];
|
|
26
27
|
visitConstTag: (node: AST.ConstTag) => Message[];
|
|
27
28
|
visitRenderTag: (node: AST.RenderTag) => Message[];
|
|
29
|
+
visitHtmlTag: (node: AST.HtmlTag) => Message[];
|
|
30
|
+
visitOnDirective: (node: AST.OnDirective) => Message[];
|
|
31
|
+
hasIdentifier: (node: AnyNode | AnyNode[], name: string) => boolean;
|
|
28
32
|
visitSnippetBlock: (node: AST.SnippetBlock) => Message[];
|
|
29
33
|
visitIfBlock: (node: AST.IfBlock) => Message[];
|
|
30
34
|
visitEachBlock: (node: AST.EachBlock) => Message[];
|
|
@@ -40,7 +44,7 @@ export declare class SvelteTransformer extends Transformer<RuntimeCtxSv> {
|
|
|
40
44
|
visitRoot: (node: AST.Root) => Message[];
|
|
41
45
|
visitSv: (node: AST.SvelteNode | AnyNode) => Message[];
|
|
42
46
|
/** collects the ranges that will be checked if a snippet identifier is exported using RegExp test to simplify */
|
|
43
|
-
|
|
47
|
+
collectModuleExportExprs: (script: AST.Script) => void;
|
|
44
48
|
transformSv: () => Promise<TransformOutput>;
|
|
45
49
|
}
|
|
46
50
|
export {};
|
package/dist/transformer.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import MagicString from 'magic-string';
|
|
2
1
|
import { parse, preprocess } from 'svelte/compiler';
|
|
3
2
|
import { getKey } from 'wuchale';
|
|
4
3
|
import { MixedVisitor, nonWhitespaceText, varNames } from 'wuchale/adapter-utils';
|
|
@@ -8,7 +7,7 @@ const noWrapTopCalls = ['$props', '$state', '$derived', '$effect'];
|
|
|
8
7
|
const rtComponent = 'W_tx_';
|
|
9
8
|
const headerAdd = `\nimport ${rtComponent} from "@wuchale/svelte/runtime.svelte"`;
|
|
10
9
|
const snipPrefix = '_w_snippet_';
|
|
11
|
-
const rtModuleVar = varNames.rt
|
|
10
|
+
const rtModuleVar = `${varNames.rt}mod_`;
|
|
12
11
|
// for use before actually parsing the code,
|
|
13
12
|
// to remove the contents of e.g. <style lang="scss"> which can cause parse errors
|
|
14
13
|
// without messing up indices for magic-string
|
|
@@ -20,11 +19,12 @@ export class SvelteTransformer extends Transformer {
|
|
|
20
19
|
currentElement;
|
|
21
20
|
inCompoundText = false;
|
|
22
21
|
currentSnippet = 0;
|
|
23
|
-
|
|
22
|
+
moduleExportExprs = []; // to choose which runtime var to use for snippets
|
|
24
23
|
mixedVisitor;
|
|
25
24
|
constructor(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl) {
|
|
26
25
|
super(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl, [varNames.rt, rtModuleVar]);
|
|
27
26
|
this.heuristciDetails.insideProgram = false;
|
|
27
|
+
this.mixedVisitor = this.initMixedVisitor();
|
|
28
28
|
}
|
|
29
29
|
visitExpressionTag = (node) => this.visit(node.expression);
|
|
30
30
|
visitVariableDeclarator = (node) => {
|
|
@@ -37,6 +37,9 @@ export class SvelteTransformer extends Transformer {
|
|
|
37
37
|
return msgs;
|
|
38
38
|
}
|
|
39
39
|
const needsWrapping = msgs.some(msg => {
|
|
40
|
+
if (msg.details.leftSide) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
40
43
|
const topCall = msg.details.topLevelCall ?? '';
|
|
41
44
|
if (noWrapTopCalls.includes(topCall) || noWrapTopCalls.some(c => topCall.startsWith(`${c}.`))) {
|
|
42
45
|
return false;
|
|
@@ -49,7 +52,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
49
52
|
if (!needsWrapping) {
|
|
50
53
|
return msgs;
|
|
51
54
|
}
|
|
52
|
-
const isExported = this.
|
|
55
|
+
const isExported = this.moduleExportExprs.some(node => init.start >= node.start && init.end <= node.end);
|
|
53
56
|
if (!isExported) {
|
|
54
57
|
this.mstr.appendLeft(init.start, '$derived(');
|
|
55
58
|
this.mstr.appendRight(init.end, ')');
|
|
@@ -64,9 +67,9 @@ export class SvelteTransformer extends Transformer {
|
|
|
64
67
|
isComment: node => node.type === 'Comment',
|
|
65
68
|
leaveInPlace: node => ['ConstTag', 'SnippetBlock'].includes(node.type),
|
|
66
69
|
isExpression: node => node.type === 'ExpressionTag',
|
|
67
|
-
getTextContent:
|
|
68
|
-
getCommentData:
|
|
69
|
-
canHaveChildren:
|
|
70
|
+
getTextContent: node => node.data,
|
|
71
|
+
getCommentData: node => node.data.trim(),
|
|
72
|
+
canHaveChildren: node => nodesWithChildren.includes(node.type),
|
|
70
73
|
visitFunc: (child, inCompoundText) => {
|
|
71
74
|
const inCompoundTextPrev = this.inCompoundText;
|
|
72
75
|
this.inCompoundText = inCompoundText;
|
|
@@ -104,7 +107,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
104
107
|
let end = ' />\n';
|
|
105
108
|
if (hasExprs) {
|
|
106
109
|
begin += ' a={[';
|
|
107
|
-
end =
|
|
110
|
+
end = `]}${end}`;
|
|
108
111
|
}
|
|
109
112
|
this.mstr.appendLeft(lastChildEnd, begin);
|
|
110
113
|
this.mstr.appendRight(lastChildEnd, end);
|
|
@@ -197,15 +200,25 @@ export class SvelteTransformer extends Transformer {
|
|
|
197
200
|
// @ts-expect-error
|
|
198
201
|
return this.visitVariableDeclaration(node.declaration);
|
|
199
202
|
};
|
|
200
|
-
visitRenderTag = (node) =>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
+
visitRenderTag = (node) => this.visit(node.expression);
|
|
204
|
+
visitHtmlTag = (node) => this.visit(node.expression);
|
|
205
|
+
visitOnDirective = (node) => this.visit(node.expression);
|
|
206
|
+
hasIdentifier = (node, name) => {
|
|
207
|
+
if (!node || typeof node !== 'object') {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
if (Array.isArray(node)) {
|
|
211
|
+
return node.some(child => this.hasIdentifier(child, name));
|
|
212
|
+
}
|
|
213
|
+
if (node.type === 'Identifier') {
|
|
214
|
+
return node.name === name;
|
|
215
|
+
}
|
|
216
|
+
return Object.values(node).some(value => this.hasIdentifier(value, name));
|
|
203
217
|
};
|
|
204
218
|
visitSnippetBlock = (node) => {
|
|
205
219
|
// use module runtime var because the snippet may be exported from the module
|
|
206
220
|
const prevRtVar = this.currentRtVar;
|
|
207
|
-
|
|
208
|
-
if (this.moduleExportRanges.some(([start, end]) => pattern.test(this.content.slice(start, end)))) {
|
|
221
|
+
if (this.hasIdentifier(this.moduleExportExprs, node.expression.name)) {
|
|
209
222
|
this.currentRtVar = rtModuleVar;
|
|
210
223
|
}
|
|
211
224
|
const msgs = this.visitFragment(node.body);
|
|
@@ -283,7 +296,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
283
296
|
};
|
|
284
297
|
visitSv = (node) => this.visit(node);
|
|
285
298
|
/** collects the ranges that will be checked if a snippet identifier is exported using RegExp test to simplify */
|
|
286
|
-
|
|
299
|
+
collectModuleExportExprs = (script) => {
|
|
287
300
|
for (const stmt of script.content.body) {
|
|
288
301
|
if (stmt.type !== 'ExportNamedDeclaration') {
|
|
289
302
|
continue;
|
|
@@ -291,7 +304,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
291
304
|
for (const spec of stmt.specifiers) {
|
|
292
305
|
if (spec.local.type === 'Identifier') {
|
|
293
306
|
const local = spec.local;
|
|
294
|
-
this.
|
|
307
|
+
this.moduleExportExprs.push(local);
|
|
295
308
|
}
|
|
296
309
|
}
|
|
297
310
|
const declaration = stmt.declaration;
|
|
@@ -299,14 +312,14 @@ export class SvelteTransformer extends Transformer {
|
|
|
299
312
|
continue;
|
|
300
313
|
}
|
|
301
314
|
if (declaration.type === 'FunctionDeclaration' || declaration.type === 'ClassDeclaration') {
|
|
302
|
-
this.
|
|
315
|
+
this.moduleExportExprs.push(declaration);
|
|
303
316
|
continue;
|
|
304
317
|
}
|
|
305
318
|
for (const decl of declaration?.declarations ?? []) {
|
|
306
319
|
if (!decl.init) {
|
|
307
320
|
continue;
|
|
308
321
|
}
|
|
309
|
-
this.
|
|
322
|
+
this.moduleExportExprs.push(decl.init);
|
|
310
323
|
}
|
|
311
324
|
}
|
|
312
325
|
};
|
|
@@ -321,10 +334,8 @@ export class SvelteTransformer extends Transformer {
|
|
|
321
334
|
;
|
|
322
335
|
[ast, this.comments] = parseScript(this.content);
|
|
323
336
|
}
|
|
324
|
-
this.mstr = new MagicString(this.content);
|
|
325
|
-
this.mixedVisitor = this.initMixedVisitor();
|
|
326
337
|
if (ast.type === 'Root' && ast.module) {
|
|
327
|
-
this.
|
|
338
|
+
this.collectModuleExportExprs(ast.module);
|
|
328
339
|
}
|
|
329
340
|
const msgs = this.visitSv(ast);
|
|
330
341
|
const initRuntime = this.initRuntime();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wuchale/svelte",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.4",
|
|
4
4
|
"description": "Protobuf-like i18n from plain code: Svelte adapter",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "tsc --watch",
|
|
@@ -53,11 +53,12 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"magic-string": "^0.30.21",
|
|
55
55
|
"svelte": "^5",
|
|
56
|
-
"wuchale": "^0.
|
|
56
|
+
"wuchale": "^0.23.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
+
"@types/node": "~24.12.2",
|
|
59
60
|
"acorn": "^8.16.0",
|
|
60
|
-
"typescript": "^
|
|
61
|
+
"typescript": "^6.0.3"
|
|
61
62
|
},
|
|
62
63
|
"type": "module"
|
|
63
64
|
}
|
|
@@ -3,7 +3,7 @@ import { loadCatalog, loadIDs } from '${PROXY_SYNC}'
|
|
|
3
3
|
|
|
4
4
|
const key = '${KEY}'
|
|
5
5
|
|
|
6
|
-
export { loadCatalog, loadIDs
|
|
6
|
+
export { key, loadCatalog, loadIDs } // for hooks.server.{js,ts}
|
|
7
7
|
|
|
8
8
|
// for non-reactive
|
|
9
9
|
export const getRuntime = (/** @type {string} */ loadID) => currentRuntime(key, loadID)
|