@wuchale/svelte 0.15.0 → 0.16.0

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 CHANGED
@@ -1,23 +1,15 @@
1
- // $$ cd .. && npm run test
2
1
  import { defaultGenerateLoadID, defaultHeuristic, deepMergeObjects } from 'wuchale';
3
2
  import { SvelteTransformer } from "./transformer.js";
4
3
  import { getDependencies, loaderPathResolver } from 'wuchale/adapter-utils';
5
- const topLevelDeclarationsInside = ['$derived', '$derived.by'];
6
- const ignoreElements = ['style', 'path', 'code', 'pre'];
7
- const svelteHeuristic = (msgStr, details) => {
8
- if (!defaultHeuristic(msgStr, details)) {
4
+ import { pluralPattern } from 'wuchale/adapter-vanilla';
5
+ const svelteHeuristic = msg => {
6
+ if (!defaultHeuristic(msg)) {
9
7
  return false;
10
8
  }
11
- if (ignoreElements.includes(details.element)) {
12
- return false;
13
- }
14
- if (details.scope !== 'script') {
9
+ if (msg.details.scope !== 'script') {
15
10
  return true;
16
11
  }
17
- if (details.declaring === 'variable' && !topLevelDeclarationsInside.includes(details.topLevelCall)) {
18
- return false;
19
- }
20
- if (details.call === '$inspect') {
12
+ if (msg.details.call === '$inspect') {
21
13
  return false;
22
14
  }
23
15
  return true;
@@ -25,7 +17,7 @@ const svelteHeuristic = (msgStr, details) => {
25
17
  const defaultArgs = {
26
18
  files: ['src/**/*.svelte', 'src/**/*.svelte.{js,ts}'],
27
19
  catalog: './src/locales/{locale}',
28
- pluralsFunc: 'plural',
20
+ patterns: [pluralPattern],
29
21
  heuristic: svelteHeuristic,
30
22
  granularLoad: false,
31
23
  bundleLoad: false,
@@ -54,10 +46,10 @@ const defaultArgs = {
54
46
  };
55
47
  const resolveLoaderPath = loaderPathResolver(import.meta.url, '../src/loaders', 'svelte.js');
56
48
  export const adapter = (args = defaultArgs) => {
57
- const { heuristic, pluralsFunc, runtime, ...rest } = deepMergeObjects(args, defaultArgs);
49
+ const { heuristic, patterns, runtime, ...rest } = deepMergeObjects(args, defaultArgs);
58
50
  return {
59
51
  transform: ({ content, filename, index, expr }) => {
60
- return new SvelteTransformer(content, filename, index, heuristic, pluralsFunc, expr, runtime).transformSv();
52
+ return new SvelteTransformer(content, filename, index, heuristic, patterns, expr, runtime).transformSv();
61
53
  },
62
54
  loaderExts: ['.svelte.js', '.svelte.ts', '.js', '.ts'],
63
55
  defaultLoaders: async () => {
@@ -75,7 +67,7 @@ export const adapter = (args = defaultArgs) => {
75
67
  if (loader === 'sveltekit') {
76
68
  return {
77
69
  client: resolveLoaderPath('svelte'),
78
- ssr: resolveLoaderPath('sveltekit.ssr'),
70
+ server: resolveLoaderPath('sveltekit.ssr'),
79
71
  };
80
72
  }
81
73
  return resolveLoaderPath(loader);
@@ -1,8 +1,8 @@
1
- import type { AnyNode } from "acorn";
1
+ import type { AnyNode, VariableDeclarator } 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, CatalogExpr, RuntimeConf } from 'wuchale';
5
+ import type { IndexTracker, HeuristicFunc, TransformOutput, CatalogExpr, RuntimeConf, CodePattern } from 'wuchale';
6
6
  import { MixedVisitor, type CommentDirectives } 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,8 +12,9 @@ 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, catalogExpr: CatalogExpr, rtConf: RuntimeConf);
15
+ constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf);
16
16
  visitExpressionTag: (node: AST.ExpressionTag) => Message[];
17
+ visitVariableDeclarator: (node: VariableDeclarator) => Message[];
17
18
  initMixedVisitor: () => MixedVisitor<MixedNodesTypes>;
18
19
  visitFragment: (node: AST.Fragment) => Message[];
19
20
  visitRegularElement: (node: AST.ElementLike) => Message[];
@@ -15,10 +15,30 @@ export class SvelteTransformer extends Transformer {
15
15
  lastVisitIsComment = false;
16
16
  currentSnippet = 0;
17
17
  mixedVisitor;
18
- constructor(content, filename, index, heuristic, pluralsFunc, catalogExpr, rtConf) {
19
- super(content, filename, index, heuristic, pluralsFunc, catalogExpr, rtConf, [varNames.rt, rtModuleVar]);
18
+ constructor(content, filename, index, heuristic, patterns, catalogExpr, rtConf) {
19
+ super(content, filename, index, heuristic, patterns, catalogExpr, rtConf, [varNames.rt, rtModuleVar]);
20
20
  }
21
21
  visitExpressionTag = (node) => this.visit(node.expression);
22
+ visitVariableDeclarator = (node) => {
23
+ const msgs = this.defaultVisitVariableDeclarator(node);
24
+ if (!msgs.length || this.declaring != null || ['ArrowFunctionExpression', 'FunctionExpression'].includes(node.init.type)) {
25
+ return msgs;
26
+ }
27
+ const needsWrapping = msgs.some(msg => {
28
+ if (['$derived', '$derived.by'].includes(msg.details.topLevelCall)) {
29
+ return false;
30
+ }
31
+ if (msg.details.declaring !== 'variable') {
32
+ return false;
33
+ }
34
+ return true;
35
+ });
36
+ if (needsWrapping) {
37
+ this.mstr.appendLeft(node.init.start, '$derived(');
38
+ this.mstr.appendRight(node.init.end, ')');
39
+ }
40
+ return msgs;
41
+ };
22
42
  initMixedVisitor = () => new MixedVisitor({
23
43
  mstr: this.mstr,
24
44
  vars: this.vars,
@@ -37,6 +57,7 @@ export class SvelteTransformer extends Transformer {
37
57
  return childTxts;
38
58
  },
39
59
  visitExpressionTag: this.visitExpressionTag,
60
+ fullHeuristicDetails: this.fullHeuristicDetails,
40
61
  checkHeuristic: this.checkHeuristicBool,
41
62
  index: this.index,
42
63
  wrapNested: (msgInfo, hasExprs, nestedRanges, lastChildEnd) => {
@@ -207,7 +228,7 @@ export class SvelteTransformer extends Transformer {
207
228
  msgs.push(...this.visitProgram(node.module.content));
208
229
  this.mstr.appendRight(
209
230
  // @ts-expect-error
210
- this.getRealBodyStart(node.module.content.body), this.initRuntime(this.filename, null, null, {}));
231
+ this.getRealBodyStart(node.module.content.body) ?? node.module.content.start, this.initRuntime(this.filename, null, null, {}));
211
232
  this.additionalState = {}; // reset
212
233
  this.currentRtVar = prevRtVar; // reset
213
234
  }
@@ -264,27 +285,28 @@ export class SvelteTransformer extends Transformer {
264
285
  const msgs = this.visitSv(ast);
265
286
  const initRuntime = this.initRuntime(this.filename, null, null, {});
266
287
  if (ast.type === 'Program') {
267
- const bodyStart = this.getRealBodyStart(ast.body);
288
+ const bodyStart = this.getRealBodyStart(ast.body) ?? 0;
268
289
  this.mstr.appendRight(bodyStart, initRuntime);
269
290
  return this.finalize(msgs, bodyStart);
270
291
  }
271
292
  let headerIndex = 0;
272
293
  if (ast.module) {
273
294
  // @ts-ignore
274
- headerIndex = this.getRealBodyStart(ast.module.content.body);
295
+ headerIndex = this.getRealBodyStart(ast.module.content.body) ?? ast.module.content.start;
275
296
  }
276
297
  if (ast.instance) {
298
+ // @ts-expect-error
299
+ const instanceBodyStart = this.getRealBodyStart(ast.instance.content.body) ?? ast.instance.content.start;
277
300
  if (!ast.module) {
278
- // @ts-expect-error
279
- headerIndex = this.getRealBodyStart(ast.instance.content.body);
301
+ headerIndex = instanceBodyStart;
280
302
  }
281
- // @ts-expect-error
282
- this.mstr.appendRight(this.getRealBodyStart(ast.instance.content.body), initRuntime);
303
+ this.mstr.appendRight(instanceBodyStart, initRuntime);
283
304
  }
284
305
  else {
285
- this.mstr.prepend('<script>');
306
+ const instanceStart = ast.module?.end ?? 0;
307
+ this.mstr.prependLeft(instanceStart, '\n<script>');
286
308
  // account index for hmr data here
287
- this.mstr.prependRight(0, `${initRuntime}\n</script>\n`);
309
+ this.mstr.prependRight(instanceStart, `${initRuntime}\n</script>\n`);
288
310
  // now hmr data can be prependRight(0, ...)
289
311
  }
290
312
  const headerAdd = `\nimport ${rtComponent} from "@wuchale/svelte/runtime.svelte"`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wuchale/svelte",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
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.16.0"
55
+ "wuchale": "^0.17.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "acorn": "^8.15.0",