@wuchale/svelte 0.13.5 → 0.14.1
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.js +32 -8
- package/dist/transformer.d.ts +3 -3
- package/dist/transformer.js +27 -32
- package/package.json +2 -2
- package/src/loaders/bundle.svelte.js +5 -1
- package/src/loaders/{reactive.svelte.js → svelte.svelte.js} +5 -1
- package/src/loaders/sveltekit.ssr.svelte.js +15 -0
- package/src/runtime.svelte +5 -5
- package/src/loaders/sveltekit.svelte.js +0 -21
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// $$ cd .. && npm run test
|
|
1
2
|
import { defaultGenerateLoadID, defaultHeuristic, deepMergeObjects } from 'wuchale';
|
|
2
|
-
import { initRuntimeStmt, adapter as vanillaAdapter } from 'wuchale/adapter-vanilla';
|
|
3
3
|
import { SvelteTransformer } from "./transformer.js";
|
|
4
4
|
import { getDependencies } from 'wuchale/adapter-utils';
|
|
5
5
|
const topLevelDeclarationsInside = ['$derived', '$derived.by'];
|
|
@@ -31,12 +31,32 @@ const defaultArgs = {
|
|
|
31
31
|
bundleLoad: false,
|
|
32
32
|
generateLoadID: defaultGenerateLoadID,
|
|
33
33
|
writeFiles: {},
|
|
34
|
+
runtime: {
|
|
35
|
+
useReactive: ({ file, funcName, additional }) => {
|
|
36
|
+
const inTopLevel = funcName == null;
|
|
37
|
+
const inModule = file.endsWith('.svelte.js') || additional.module;
|
|
38
|
+
return {
|
|
39
|
+
init: inModule ? inTopLevel : (inTopLevel ? true : null),
|
|
40
|
+
use: inModule ? inTopLevel : true,
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
reactive: {
|
|
44
|
+
importName: 'default',
|
|
45
|
+
wrapInit: expr => `$derived(${expr})`,
|
|
46
|
+
wrapUse: expr => expr,
|
|
47
|
+
},
|
|
48
|
+
plain: {
|
|
49
|
+
importName: 'get',
|
|
50
|
+
wrapInit: expr => expr,
|
|
51
|
+
wrapUse: expr => expr,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
34
54
|
};
|
|
35
55
|
export const adapter = (args = defaultArgs) => {
|
|
36
|
-
const { heuristic, pluralsFunc, ...rest } = deepMergeObjects(args, defaultArgs);
|
|
56
|
+
const { heuristic, pluralsFunc, runtime, ...rest } = deepMergeObjects(args, defaultArgs);
|
|
37
57
|
return {
|
|
38
|
-
transform: ({ content, filename, index,
|
|
39
|
-
return new SvelteTransformer(content, filename, index, heuristic, pluralsFunc,
|
|
58
|
+
transform: ({ content, filename, index, expr }) => {
|
|
59
|
+
return new SvelteTransformer(content, filename, index, heuristic, pluralsFunc, expr, runtime).transformSv();
|
|
40
60
|
},
|
|
41
61
|
loaderExts: ['.svelte.js', '.svelte.ts', '.js', '.ts'],
|
|
42
62
|
defaultLoaders: async () => {
|
|
@@ -44,18 +64,22 @@ export const adapter = (args = defaultArgs) => {
|
|
|
44
64
|
return ['bundle'];
|
|
45
65
|
}
|
|
46
66
|
const deps = await getDependencies();
|
|
47
|
-
const available = ['
|
|
67
|
+
const available = ['svelte'];
|
|
48
68
|
if (deps.has('@sveltejs/kit')) {
|
|
49
69
|
available.unshift('sveltekit');
|
|
50
70
|
}
|
|
51
71
|
return available;
|
|
52
72
|
},
|
|
53
|
-
defaultLoaderPath:
|
|
54
|
-
if (loader === '
|
|
55
|
-
return
|
|
73
|
+
defaultLoaderPath: loader => {
|
|
74
|
+
if (loader === 'sveltekit') {
|
|
75
|
+
return {
|
|
76
|
+
client: new URL(`../src/loaders/svelte.svelte.js`, import.meta.url).pathname,
|
|
77
|
+
ssr: new URL(`../src/loaders/sveltekit.ssr.svelte.js`, import.meta.url).pathname
|
|
78
|
+
};
|
|
56
79
|
}
|
|
57
80
|
return new URL(`../src/loaders/${loader}.svelte.js`, import.meta.url).pathname;
|
|
58
81
|
},
|
|
82
|
+
runtime,
|
|
59
83
|
...rest,
|
|
60
84
|
docsUrl: 'https://wuchale.dev/adapters/svelte'
|
|
61
85
|
};
|
package/dist/transformer.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AnyNode } from "acorn";
|
|
|
2
2
|
import { type AST } from "svelte/compiler";
|
|
3
3
|
import { Message } from 'wuchale';
|
|
4
4
|
import { Transformer } from 'wuchale/adapter-vanilla';
|
|
5
|
-
import type { IndexTracker, HeuristicFunc, TransformOutput, CommentDirectives } from 'wuchale';
|
|
5
|
+
import type { IndexTracker, HeuristicFunc, TransformOutput, CommentDirectives, CatalogExpr, RuntimeConf } from 'wuchale';
|
|
6
6
|
import { MixedVisitor } from "wuchale/adapter-utils";
|
|
7
7
|
type MixedNodesTypes = AST.Text | AST.Tag | AST.ElementLike | AST.Block | AST.Comment;
|
|
8
8
|
export declare class SvelteTransformer extends Transformer {
|
|
@@ -12,7 +12,7 @@ export declare class SvelteTransformer extends Transformer {
|
|
|
12
12
|
lastVisitIsComment: boolean;
|
|
13
13
|
currentSnippet: number;
|
|
14
14
|
mixedVisitor: MixedVisitor<MixedNodesTypes>;
|
|
15
|
-
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, pluralsFunc: string,
|
|
15
|
+
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, pluralsFunc: string, catalogExpr: CatalogExpr, rtConf: RuntimeConf);
|
|
16
16
|
visitExpressionTag: (node: AST.ExpressionTag) => Message[];
|
|
17
17
|
initMixedVisitor: () => MixedVisitor<MixedNodesTypes>;
|
|
18
18
|
visitFragment: (node: AST.Fragment) => Message[];
|
|
@@ -34,6 +34,6 @@ export declare class SvelteTransformer extends Transformer {
|
|
|
34
34
|
visitSvelteWindow: (node: AST.SvelteWindow) => Message[];
|
|
35
35
|
visitRoot: (node: AST.Root) => Message[];
|
|
36
36
|
visitSv: (node: AST.SvelteNode | AnyNode) => Message[];
|
|
37
|
-
transformSv: (
|
|
37
|
+
transformSv: () => TransformOutput;
|
|
38
38
|
}
|
|
39
39
|
export {};
|
package/dist/transformer.js
CHANGED
|
@@ -2,10 +2,10 @@ import MagicString from "magic-string";
|
|
|
2
2
|
import { parse } from "svelte/compiler";
|
|
3
3
|
import { Message } from 'wuchale';
|
|
4
4
|
import { Transformer, parseScript } from 'wuchale/adapter-vanilla';
|
|
5
|
-
import { MixedVisitor, nonWhitespaceText
|
|
5
|
+
import { MixedVisitor, nonWhitespaceText } from "wuchale/adapter-utils";
|
|
6
6
|
const nodesWithChildren = ['RegularElement', 'Component'];
|
|
7
|
-
const rtComponent = '
|
|
8
|
-
const snipPrefix = '
|
|
7
|
+
const rtComponent = 'W_tx_';
|
|
8
|
+
const snipPrefix = '_w_snippet_';
|
|
9
9
|
export class SvelteTransformer extends Transformer {
|
|
10
10
|
// state
|
|
11
11
|
currentElement;
|
|
@@ -14,12 +14,13 @@ export class SvelteTransformer extends Transformer {
|
|
|
14
14
|
lastVisitIsComment = false;
|
|
15
15
|
currentSnippet = 0;
|
|
16
16
|
mixedVisitor;
|
|
17
|
-
constructor(content, filename, index, heuristic, pluralsFunc,
|
|
18
|
-
super(content, filename, index, heuristic, pluralsFunc,
|
|
17
|
+
constructor(content, filename, index, heuristic, pluralsFunc, catalogExpr, rtConf) {
|
|
18
|
+
super(content, filename, index, heuristic, pluralsFunc, catalogExpr, rtConf);
|
|
19
19
|
}
|
|
20
20
|
visitExpressionTag = (node) => this.visit(node.expression);
|
|
21
21
|
initMixedVisitor = () => new MixedVisitor({
|
|
22
22
|
mstr: this.mstr,
|
|
23
|
+
vars: this.vars,
|
|
23
24
|
getRange: node => ({ start: node.start, end: node.end }),
|
|
24
25
|
isText: node => node.type === 'Text',
|
|
25
26
|
isComment: node => node.type === 'Comment',
|
|
@@ -44,21 +45,25 @@ export class SvelteTransformer extends Transformer {
|
|
|
44
45
|
const snippetName = `${snipPrefix}${this.currentSnippet}`;
|
|
45
46
|
snippets.push(snippetName);
|
|
46
47
|
this.currentSnippet++;
|
|
47
|
-
const snippetBegin = `\n{#snippet ${snippetName}(${haveCtx ?
|
|
48
|
+
const snippetBegin = `\n{#snippet ${snippetName}(${haveCtx ? this.vars().nestCtx : ''})}\n`;
|
|
48
49
|
this.mstr.appendRight(childStart, snippetBegin);
|
|
49
50
|
this.mstr.prependLeft(childEnd, '\n{/snippet}');
|
|
50
51
|
}
|
|
51
|
-
let begin = `\n<${rtComponent}
|
|
52
|
+
let begin = `\n<${rtComponent}`;
|
|
53
|
+
if (snippets.length) {
|
|
54
|
+
begin += ` t={[${snippets.join(', ')}]}`;
|
|
55
|
+
}
|
|
56
|
+
begin += ' x=';
|
|
52
57
|
if (this.inCompoundText) {
|
|
53
|
-
begin += `{${
|
|
58
|
+
begin += `{${this.vars().nestCtx}} n`;
|
|
54
59
|
}
|
|
55
60
|
else {
|
|
56
61
|
const index = this.index.get(msgInfo.toKey());
|
|
57
|
-
begin += `{${
|
|
62
|
+
begin += `{${this.vars().rtCtx}(${index})}`;
|
|
58
63
|
}
|
|
59
64
|
let end = ' />\n';
|
|
60
65
|
if (hasExprs) {
|
|
61
|
-
begin += '
|
|
66
|
+
begin += ' a={[';
|
|
62
67
|
end = ']}' + end;
|
|
63
68
|
}
|
|
64
69
|
this.mstr.appendLeft(lastChildEnd, begin);
|
|
@@ -93,7 +98,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
93
98
|
if (!pass) {
|
|
94
99
|
return [];
|
|
95
100
|
}
|
|
96
|
-
this.mstr.update(node.start + startWh, node.end - endWh, `{${
|
|
101
|
+
this.mstr.update(node.start + startWh, node.end - endWh, `{${this.vars().rtTrans}(${this.index.get(msgInfo.toKey())})}`);
|
|
97
102
|
return [msgInfo];
|
|
98
103
|
};
|
|
99
104
|
visitSpreadAttribute = (node) => this.visit(node.expression);
|
|
@@ -130,7 +135,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
130
135
|
if (!pass) {
|
|
131
136
|
return [];
|
|
132
137
|
}
|
|
133
|
-
this.mstr.update(value.start, value.end, `{${
|
|
138
|
+
this.mstr.update(value.start, value.end, `{${this.vars().rtTrans}(${this.index.get(msgInfo.toKey())})}`);
|
|
134
139
|
if (`'"`.includes(this.content[value.start - 1])) {
|
|
135
140
|
this.mstr.remove(value.start - 1, value.start);
|
|
136
141
|
this.mstr.remove(value.end, value.end + 1);
|
|
@@ -191,21 +196,17 @@ export class SvelteTransformer extends Transformer {
|
|
|
191
196
|
const msgs = [];
|
|
192
197
|
// @ts-ignore: module is a reserved keyword, not sure how to specify the type
|
|
193
198
|
if (node.module) {
|
|
199
|
+
this.additionalState = { module: true };
|
|
194
200
|
this.commentDirectives = {}; // reset
|
|
195
201
|
// @ts-ignore
|
|
196
202
|
msgs.push(...this.visitProgram(node.module.content));
|
|
203
|
+
this.additionalState = {}; // reset
|
|
197
204
|
}
|
|
198
|
-
// no need to init runtime inside components outside <script module>s
|
|
199
|
-
// they run everytime they are rendered instead of once at startup
|
|
200
|
-
const initRuntime = this.initRuntime;
|
|
201
|
-
this.initRuntime = null;
|
|
202
205
|
if (node.instance) {
|
|
203
206
|
this.commentDirectives = {}; // reset
|
|
204
207
|
msgs.push(...this.visitProgram(node.instance.content));
|
|
205
208
|
}
|
|
206
209
|
msgs.push(...this.visitFragment(node.fragment));
|
|
207
|
-
// restore just in case
|
|
208
|
-
this.initRuntime = initRuntime;
|
|
209
210
|
return msgs;
|
|
210
211
|
};
|
|
211
212
|
visitSv = (node) => {
|
|
@@ -235,7 +236,7 @@ export class SvelteTransformer extends Transformer {
|
|
|
235
236
|
this.commentDirectives = commentDirectivesPrev;
|
|
236
237
|
return msgs;
|
|
237
238
|
};
|
|
238
|
-
transformSv = (
|
|
239
|
+
transformSv = () => {
|
|
239
240
|
const isComponent = this.filename.endsWith('.svelte');
|
|
240
241
|
let ast;
|
|
241
242
|
if (isComponent) {
|
|
@@ -249,36 +250,30 @@ export class SvelteTransformer extends Transformer {
|
|
|
249
250
|
this.mstr = new MagicString(this.content);
|
|
250
251
|
this.mixedVisitor = this.initMixedVisitor();
|
|
251
252
|
const msgs = this.visitSv(ast);
|
|
252
|
-
if (!msgs.length) {
|
|
253
|
-
return this.finalize(msgs, 0);
|
|
254
|
-
}
|
|
255
253
|
const headerLines = [
|
|
256
254
|
isComponent ? `\nimport ${rtComponent} from "@wuchale/svelte/runtime.svelte"` : '',
|
|
257
|
-
|
|
258
|
-
`const ${runtimeVars.rtConst} = $derived(${runtimeVars.rtWrap}(${headerExpr}))\n`,
|
|
255
|
+
this.initRuntime(this.filename, null, null, {}),
|
|
259
256
|
];
|
|
260
257
|
const headerFin = headerLines.join('\n');
|
|
261
258
|
if (ast.type === 'Program') {
|
|
262
|
-
this.
|
|
263
|
-
return this.finalize(msgs,
|
|
259
|
+
const bodyStart = this.getRealBodyStart(ast.body);
|
|
260
|
+
return this.finalize(msgs, bodyStart, headerFin);
|
|
264
261
|
}
|
|
265
262
|
let hmrHeaderIndex = 0;
|
|
266
263
|
if (ast.module) {
|
|
267
264
|
// @ts-ignore
|
|
268
|
-
hmrHeaderIndex = ast.module.content.
|
|
269
|
-
this.mstr.appendRight(hmrHeaderIndex, headerFin);
|
|
265
|
+
hmrHeaderIndex = this.getRealBodyStart(ast.module.content.body);
|
|
270
266
|
}
|
|
271
267
|
else if (ast.instance) {
|
|
272
268
|
// @ts-ignore
|
|
273
|
-
hmrHeaderIndex = ast.instance.content.
|
|
274
|
-
this.mstr.appendRight(hmrHeaderIndex, headerFin);
|
|
269
|
+
hmrHeaderIndex = this.getRealBodyStart(ast.instance.content.body);
|
|
275
270
|
}
|
|
276
271
|
else {
|
|
277
272
|
this.mstr.prepend('<script>');
|
|
278
273
|
// account index for hmr data here
|
|
279
|
-
this.mstr.prependRight(0,
|
|
274
|
+
this.mstr.prependRight(0, `</script>\n`);
|
|
280
275
|
// now hmr data can be prependRight(0, ...)
|
|
281
276
|
}
|
|
282
|
-
return this.finalize(msgs, hmrHeaderIndex);
|
|
277
|
+
return this.finalize(msgs, hmrHeaderIndex, headerFin);
|
|
283
278
|
};
|
|
284
279
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wuchale/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Protobuf-like i18n from plain code: Svelte adapter",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "tsc --watch",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"license": "MIT",
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"svelte": "^5.37.0",
|
|
55
|
-
"wuchale": "^0.
|
|
55
|
+
"wuchale": "^0.15.4"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"acorn": "^8.15.0",
|
|
@@ -10,7 +10,11 @@ export function setLocale(newLocale) {
|
|
|
10
10
|
locale = newLocale
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// for non-reactive
|
|
13
14
|
/**
|
|
14
15
|
* @param {{ [locale: string]: import("wuchale/runtime").CatalogModule }} catalogs
|
|
15
16
|
*/
|
|
16
|
-
export
|
|
17
|
+
export const get = catalogs => catalogs[locale]
|
|
18
|
+
|
|
19
|
+
// same function, only will be inside $derived when used
|
|
20
|
+
export default get
|
|
@@ -8,4 +8,8 @@ import { registerLoaders, defaultCollection } from 'wuchale/load-utils'
|
|
|
8
8
|
|
|
9
9
|
const catalogs = $state({})
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
// for non-reactive
|
|
12
|
+
export const get = registerLoaders(key, loadCatalog, loadIDs, defaultCollection(catalogs))
|
|
13
|
+
|
|
14
|
+
// same function, only will be inside $derived when used
|
|
15
|
+
export default get
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// This is just the default loader.
|
|
2
|
+
// You can customize it however you want, it will not be overwritten once it exists and is not empty.
|
|
3
|
+
|
|
4
|
+
/// <reference types="wuchale/virtual" />
|
|
5
|
+
|
|
6
|
+
import { loadCatalog, loadIDs, key } from 'virtual:wuchale/proxy/sync' // because it's on the server
|
|
7
|
+
import { currentCatalog } from 'wuchale/load-utils/server'
|
|
8
|
+
|
|
9
|
+
export { loadCatalog, loadIDs, key } // for hooks.server.{js,ts}
|
|
10
|
+
|
|
11
|
+
// for non-reactive
|
|
12
|
+
export const get = (/** @type {string} */ loadID) => currentCatalog(key, loadID)
|
|
13
|
+
|
|
14
|
+
// same function, only will be inside $derived when used
|
|
15
|
+
export default get
|
package/src/runtime.svelte
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
const {
|
|
2
|
+
const {n = false, x, t, a} = $props()
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
|
-
{#each
|
|
5
|
+
{#each x as fragment, i}
|
|
6
6
|
{#if typeof fragment === 'string'}
|
|
7
7
|
{fragment}
|
|
8
8
|
{:else if typeof fragment === 'number'}
|
|
9
|
-
{#if !
|
|
10
|
-
{
|
|
9
|
+
{#if !n || i > 0}
|
|
10
|
+
{a[fragment]}
|
|
11
11
|
{/if}
|
|
12
12
|
{:else}
|
|
13
|
-
{@const tag =
|
|
13
|
+
{@const tag = t[fragment[0]]}
|
|
14
14
|
{#if tag == null}
|
|
15
15
|
[i18n-404:tag]
|
|
16
16
|
{:else}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// This is just the default loader.
|
|
2
|
-
// You can customize it however you want, it will not be overwritten once it exists and is not empty.
|
|
3
|
-
|
|
4
|
-
/// <reference types="wuchale/virtual" />
|
|
5
|
-
|
|
6
|
-
import { loadCatalog, loadIDs, key } from 'virtual:wuchale/proxy' // or proxy/sync
|
|
7
|
-
import { registerLoaders, defaultCollection } from 'wuchale/load-utils'
|
|
8
|
-
|
|
9
|
-
export { loadCatalog, loadIDs, key } // for +layout.{js,ts} and hooks.server.{js,ts}
|
|
10
|
-
|
|
11
|
-
let loadC
|
|
12
|
-
|
|
13
|
-
if (import.meta.env.SSR) { // stripped from production client builds
|
|
14
|
-
const { currentCatalog } = await import('wuchale/load-utils/server')
|
|
15
|
-
loadC = (/** @type {string} */ loadID) => currentCatalog(key, loadID)
|
|
16
|
-
} else { // client
|
|
17
|
-
const catalogs = $state({})
|
|
18
|
-
loadC = registerLoaders(key, loadCatalog, loadIDs, defaultCollection(catalogs))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default loadC
|