@wuchale/svelte 0.17.9 → 0.18.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.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { HeuristicFunc, Adapter, AdapterArgs, LoaderChoice, CreateHeuristicOpts } from 'wuchale';
1
+ import type { Adapter, AdapterArgs, CreateHeuristicOpts, HeuristicFunc, LoaderChoice } from 'wuchale';
2
+ import { type RuntimeCtxSv } from './transformer.js';
3
+ export type { RuntimeCtxSv };
2
4
  export declare function createSvelteHeuristic(opts: CreateHeuristicOpts): HeuristicFunc;
3
5
  /** Default Svelte heuristic which extracts top level variable assignments as well, leading to `$derived` being auto added when needed */
4
6
  export declare const svelteDefaultHeuristic: HeuristicFunc;
@@ -6,10 +8,9 @@ export declare const svelteKitDefaultHeuristic: HeuristicFunc;
6
8
  /** Default Svelte heuristic which requires `$derived` or `$derived.by` for top level variable assignments */
7
9
  export declare const svelteDefaultHeuristicDerivedReq: HeuristicFunc;
8
10
  type LoadersAvailable = 'svelte' | 'sveltekit';
9
- export type SvelteArgs = AdapterArgs<LoadersAvailable>;
11
+ export type SvelteArgs = AdapterArgs<LoadersAvailable, RuntimeCtxSv>;
10
12
  export declare function getDefaultLoaderPath(loader: LoaderChoice<LoadersAvailable>, bundle: boolean): string | {
11
13
  client: string;
12
14
  server: string;
13
15
  } | null;
14
16
  export declare const adapter: (args?: Partial<SvelteArgs>) => Adapter;
15
- export {};
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { defaultGenerateLoadID, deepMergeObjects, createHeuristic, defaultHeuristicOpts } from 'wuchale';
2
- import { SvelteTransformer } from "./transformer.js";
1
+ import { createHeuristic, deepMergeObjects, defaultGenerateLoadID, defaultHeuristicOpts } from 'wuchale';
3
2
  import { loaderPathResolver } from 'wuchale/adapter-utils';
4
3
  import { pluralPattern } from 'wuchale/adapter-vanilla';
4
+ import { SvelteTransformer } from './transformer.js';
5
5
  export function createSvelteHeuristic(opts) {
6
6
  const defaultHeuristic = createHeuristic(opts);
7
- return msg => {
7
+ return (msg) => {
8
8
  const defRes = defaultHeuristic(msg);
9
9
  if (!defRes) {
10
10
  return false;
@@ -22,7 +22,7 @@ export function createSvelteHeuristic(opts) {
22
22
  export const svelteDefaultHeuristic = createSvelteHeuristic(defaultHeuristicOpts);
23
23
  export const svelteKitDefaultHeuristic = createSvelteHeuristic({ ...defaultHeuristicOpts, urlCalls: ['goto'] });
24
24
  /** Default Svelte heuristic which requires `$derived` or `$derived.by` for top level variable assignments */
25
- export const svelteDefaultHeuristicDerivedReq = msg => {
25
+ export const svelteDefaultHeuristicDerivedReq = (msg) => {
26
26
  const defRes = svelteDefaultHeuristic(msg);
27
27
  if (!defRes) {
28
28
  return false;
@@ -48,21 +48,21 @@ const defaultArgs = {
48
48
  generateLoadID: defaultGenerateLoadID,
49
49
  loader: 'svelte',
50
50
  runtime: {
51
- useReactive: ({ file, funcName, additional }) => {
51
+ initReactive: ({ file, funcName, module }) => {
52
52
  const inTopLevel = funcName == null;
53
- const inModule = file.endsWith('.svelte.js') || additional.module;
54
- return {
55
- init: inModule ? inTopLevel : (inTopLevel ? true : null),
56
- use: inModule ? inTopLevel : true,
57
- };
53
+ return file.endsWith('.svelte.js') || module ? inTopLevel : inTopLevel ? true : null;
54
+ },
55
+ useReactive: ({ file, funcName, module }) => {
56
+ const inTopLevel = funcName == null;
57
+ return file.endsWith('.svelte.js') || module ? inTopLevel : true;
58
58
  },
59
59
  reactive: {
60
- wrapInit: expr => `$derived(${expr})`,
61
- wrapUse: expr => expr,
60
+ wrapInit: (expr) => `$derived(${expr})`,
61
+ wrapUse: (expr) => expr,
62
62
  },
63
63
  plain: {
64
- wrapInit: expr => expr,
65
- wrapUse: expr => expr,
64
+ wrapInit: (expr) => expr,
65
+ wrapUse: (expr) => expr,
66
66
  },
67
67
  },
68
68
  };
@@ -1,19 +1,19 @@
1
- import type { AnyNode, VariableDeclarator } from "acorn";
2
- import { type AST } from "svelte/compiler";
3
- import { Message } from 'wuchale';
1
+ import type { AnyNode, VariableDeclarator } from 'acorn';
2
+ import { type AST } from 'svelte/compiler';
3
+ import type { CatalogExpr, CodePattern, HeuristicFunc, IndexTracker, Message, RuntimeConf, TransformOutput, UrlMatcher } from 'wuchale';
4
+ import { MixedVisitor } from 'wuchale/adapter-utils';
4
5
  import { Transformer } from 'wuchale/adapter-vanilla';
5
- import type { IndexTracker, HeuristicFunc, TransformOutput, CatalogExpr, RuntimeConf, CodePattern, UrlMatcher } from 'wuchale';
6
- import { MixedVisitor, type CommentDirectives } from "wuchale/adapter-utils";
7
6
  type MixedNodesTypes = AST.Text | AST.Tag | AST.ElementLike | AST.Block | AST.Comment;
8
- export declare class SvelteTransformer extends Transformer {
7
+ export type RuntimeCtxSv = {
8
+ module: boolean;
9
+ };
10
+ export declare class SvelteTransformer extends Transformer<RuntimeCtxSv> {
9
11
  currentElement?: string;
10
12
  inCompoundText: boolean;
11
- commentDirectivesStack: CommentDirectives[];
12
- lastVisitIsComment: boolean;
13
13
  currentSnippet: number;
14
14
  moduleExportRanges: [number, number][];
15
15
  mixedVisitor: MixedVisitor<MixedNodesTypes>;
16
- constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf, matchUrl: UrlMatcher);
16
+ constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf<RuntimeCtxSv>, matchUrl: UrlMatcher);
17
17
  visitExpressionTag: (node: AST.ExpressionTag) => Message[];
18
18
  visitVariableDeclarator: (node: VariableDeclarator) => Message[];
19
19
  initMixedVisitor: () => MixedVisitor<MixedNodesTypes>;
@@ -1,10 +1,10 @@
1
- import MagicString from "magic-string";
2
- import { parse, preprocess } from "svelte/compiler";
3
- import { Message } from 'wuchale';
4
- import { Transformer, parseScript } from 'wuchale/adapter-vanilla';
5
- import { MixedVisitor, nonWhitespaceText, processCommentDirectives, varNames } from "wuchale/adapter-utils";
1
+ import MagicString from 'magic-string';
2
+ import { parse, preprocess } from 'svelte/compiler';
3
+ import { MixedVisitor, nonWhitespaceText, varNames } from 'wuchale/adapter-utils';
4
+ import { parseScript, Transformer } from 'wuchale/adapter-vanilla';
6
5
  const nodesWithChildren = ['RegularElement', 'Component'];
7
6
  const rtComponent = 'W_tx_';
7
+ const headerAdd = `\nimport ${rtComponent} from "@wuchale/svelte/runtime.svelte"`;
8
8
  const snipPrefix = '_w_snippet_';
9
9
  const rtModuleVar = varNames.rt + 'mod_';
10
10
  // for use before actually parsing the code,
@@ -21,23 +21,26 @@ export class SvelteTransformer extends Transformer {
21
21
  // state
22
22
  currentElement;
23
23
  inCompoundText = false;
24
- commentDirectivesStack = [];
25
- lastVisitIsComment = false;
26
24
  currentSnippet = 0;
27
25
  moduleExportRanges = []; // to choose which runtime var to use for snippets
28
26
  mixedVisitor;
29
27
  constructor(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl) {
30
28
  super(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl, [varNames.rt, rtModuleVar]);
29
+ this.heuristciDetails.insideProgram = false;
31
30
  }
32
31
  visitExpressionTag = (node) => this.visit(node.expression);
33
32
  visitVariableDeclarator = (node) => {
34
33
  const msgs = this.defaultVisitVariableDeclarator(node);
35
34
  const init = node.init;
36
- if (!msgs.length || this.declaring != null || init == null || ['ArrowFunctionExpression', 'FunctionExpression'].includes(init.type)) {
35
+ if (!msgs.length ||
36
+ this.heuristciDetails.declaring != null ||
37
+ init == null ||
38
+ ['ArrowFunctionExpression', 'FunctionExpression'].includes(init.type)) {
37
39
  return msgs;
38
40
  }
39
- const needsWrapping = msgs.some(msg => {
40
- if (msg.details.topLevelCall && ['$props', '$state', '$derived', '$derived.by'].includes(msg.details.topLevelCall)) {
41
+ const needsWrapping = msgs.some((msg) => {
42
+ if (msg.details.topLevelCall &&
43
+ ['$props', '$state', '$derived', '$derived.by'].includes(msg.details.topLevelCall)) {
41
44
  return false;
42
45
  }
43
46
  if (msg.details.declaring !== 'variable') {
@@ -58,13 +61,13 @@ export class SvelteTransformer extends Transformer {
58
61
  initMixedVisitor = () => new MixedVisitor({
59
62
  mstr: this.mstr,
60
63
  vars: this.vars,
61
- getRange: node => ({ start: node.start, end: node.end }),
62
- isText: node => node.type === 'Text',
63
- isComment: node => node.type === 'Comment',
64
- leaveInPlace: node => ['ConstTag', 'SnippetBlock'].includes(node.type),
65
- isExpression: node => node.type === 'ExpressionTag',
64
+ getRange: (node) => ({ start: node.start, end: node.end }),
65
+ isText: (node) => node.type === 'Text',
66
+ isComment: (node) => node.type === 'Comment',
67
+ leaveInPlace: (node) => ['ConstTag', 'SnippetBlock'].includes(node.type),
68
+ isExpression: (node) => node.type === 'ExpressionTag',
66
69
  getTextContent: (node) => node.data,
67
- getCommentData: (node) => node.data,
70
+ getCommentData: (node) => node.data.trim(),
68
71
  canHaveChildren: (node) => nodesWithChildren.includes(node.type),
69
72
  visitFunc: (child, inCompoundText) => {
70
73
  const inCompoundTextPrev = this.inCompoundText;
@@ -115,7 +118,7 @@ export class SvelteTransformer extends Transformer {
115
118
  inCompoundText: this.inCompoundText,
116
119
  scope: 'markup',
117
120
  element: this.currentElement,
118
- useComponent: this.currentElement !== 'title'
121
+ useComponent: this.currentElement !== 'title',
119
122
  });
120
123
  visitRegularElement = (node) => {
121
124
  const currentElement = this.currentElement;
@@ -220,10 +223,7 @@ export class SvelteTransformer extends Transformer {
220
223
  return msgs;
221
224
  };
222
225
  visitEachBlock = (node) => {
223
- const msgs = [
224
- ...this.visit(node.expression),
225
- ...this.visitSv(node.body),
226
- ];
226
+ const msgs = [...this.visit(node.expression), ...this.visitSv(node.body)];
227
227
  if (node.key) {
228
228
  msgs.push(...this.visit(node.key));
229
229
  }
@@ -233,10 +233,7 @@ export class SvelteTransformer extends Transformer {
233
233
  return msgs;
234
234
  };
235
235
  visitKeyBlock = (node) => {
236
- return [
237
- ...this.visit(node.expression),
238
- ...this.visitSv(node.fragment),
239
- ];
236
+ return [...this.visit(node.expression), ...this.visitSv(node.fragment)];
240
237
  };
241
238
  visitAwaitBlock = (node) => {
242
239
  const msgs = this.visit(node.expression);
@@ -251,32 +248,32 @@ export class SvelteTransformer extends Transformer {
251
248
  }
252
249
  return msgs;
253
250
  };
254
- visitSvelteBody = (node) => node.attributes.map(this.visitSv).flat();
255
- visitSvelteDocument = (node) => node.attributes.map(this.visitSv).flat();
256
- visitSvelteElement = (node) => node.attributes.map(this.visitSv).flat();
251
+ visitSvelteBody = (node) => node.attributes.flatMap(this.visitSv);
252
+ visitSvelteDocument = (node) => node.attributes.flatMap(this.visitSv);
253
+ visitSvelteElement = (node) => node.attributes.flatMap(this.visitSv);
257
254
  visitSvelteBoundary = (node) => [
258
- ...node.attributes.map(this.visitSv).flat(),
255
+ ...node.attributes.flatMap(this.visitSv),
259
256
  ...this.visitSv(node.fragment),
260
257
  ];
261
258
  visitSvelteHead = (node) => this.visitSv(node.fragment);
262
259
  visitTitleElement = (node) => this.visitRegularElement(node);
263
- visitSvelteWindow = (node) => node.attributes.map(this.visitSv).flat();
260
+ visitSvelteWindow = (node) => node.attributes.flatMap(this.visitSv);
264
261
  visitRoot = (node) => {
265
262
  const msgs = [];
266
263
  if (node.module) {
267
264
  const prevRtVar = this.currentRtVar;
268
265
  this.currentRtVar = rtModuleVar;
269
- this.additionalState = { module: true };
266
+ this.runtimeCtx = { module: true };
270
267
  this.commentDirectives = {}; // reset
271
268
  // @ts-expect-error
272
269
  msgs.push(...this.visitProgram(node.module.content));
273
- const runtimeInit = this.initRuntime(this.filename);
270
+ const runtimeInit = this.initRuntime();
274
271
  if (runtimeInit) {
275
272
  this.mstr.appendRight(
276
273
  // @ts-expect-error
277
274
  this.getRealBodyStart(node.module.content.body) ?? node.module.content.start, runtimeInit);
278
275
  }
279
- this.additionalState = {}; // reset
276
+ this.runtimeCtx = { module: false }; // reset
280
277
  this.currentRtVar = prevRtVar; // reset
281
278
  }
282
279
  if (node.instance) {
@@ -286,36 +283,7 @@ export class SvelteTransformer extends Transformer {
286
283
  msgs.push(...this.visitFragment(node.fragment));
287
284
  return msgs;
288
285
  };
289
- visitSv = (node) => {
290
- if (node.type === 'Comment') {
291
- this.commentDirectives = processCommentDirectives(node.data.trim(), this.commentDirectives);
292
- if (this.lastVisitIsComment) {
293
- this.commentDirectivesStack[this.commentDirectivesStack.length - 1] = this.commentDirectives;
294
- }
295
- else {
296
- this.commentDirectivesStack.push(this.commentDirectives);
297
- }
298
- this.lastVisitIsComment = true;
299
- return [];
300
- }
301
- if (node.type === 'Text' && !node.data.trim()) {
302
- return [];
303
- }
304
- let msgs = [];
305
- const commentDirectivesPrev = this.commentDirectives;
306
- if (this.lastVisitIsComment) {
307
- this.commentDirectives = this.commentDirectivesStack.pop();
308
- this.lastVisitIsComment = false;
309
- }
310
- if (this.commentDirectives.ignoreFile) {
311
- return [];
312
- }
313
- if (this.commentDirectives.forceType !== false) {
314
- msgs = this.visit(node);
315
- }
316
- this.commentDirectives = commentDirectivesPrev;
317
- return msgs;
318
- };
286
+ visitSv = (node) => this.visit(node);
319
287
  /** collects the ranges that will be checked if a snippet identifier is exported using RegExp test to simplify */
320
288
  collectModuleExportRanges = (script) => {
321
289
  for (const stmt of script.content.body) {
@@ -345,16 +313,15 @@ export class SvelteTransformer extends Transformer {
345
313
  }
346
314
  };
347
315
  transformSv = async () => {
348
- const isComponent = this.filename.endsWith('.svelte');
316
+ const isComponent = this.heuristciDetails.file.endsWith('.svelte');
349
317
  let ast;
350
318
  if (isComponent) {
351
319
  const prepd = await preprocess(this.content, { style: removeSCSS });
352
320
  ast = parse(prepd.code, { modern: true });
353
321
  }
354
322
  else {
355
- const [pAst, comments] = parseScript(this.content);
356
- ast = pAst;
357
- this.comments = comments;
323
+ ;
324
+ [ast, this.comments] = parseScript(this.content);
358
325
  }
359
326
  this.mstr = new MagicString(this.content);
360
327
  this.mixedVisitor = this.initMixedVisitor();
@@ -362,7 +329,7 @@ export class SvelteTransformer extends Transformer {
362
329
  this.collectModuleExportRanges(ast.module);
363
330
  }
364
331
  const msgs = this.visitSv(ast);
365
- const initRuntime = this.initRuntime(this.filename);
332
+ const initRuntime = this.initRuntime();
366
333
  if (ast.type === 'Program') {
367
334
  const bodyStart = this.getRealBodyStart(ast.body) ?? 0;
368
335
  if (initRuntime) {
@@ -392,7 +359,6 @@ export class SvelteTransformer extends Transformer {
392
359
  this.mstr.prependRight(instanceStart, `${initRuntime}\n</script>\n`);
393
360
  // now hmr data can be prependRight(0, ...)
394
361
  }
395
- const headerAdd = `\nimport ${rtComponent} from "@wuchale/svelte/runtime.svelte"`;
396
362
  return this.finalize(msgs, headerIndex, headerAdd);
397
363
  };
398
364
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wuchale/svelte",
3
- "version": "0.17.9",
3
+ "version": "0.18.1",
4
4
  "description": "Protobuf-like i18n from plain code: Svelte adapter",
5
5
  "scripts": {
6
6
  "dev": "tsc --watch",
@@ -53,7 +53,7 @@
53
53
  "dependencies": {
54
54
  "svelte": "^5.37.0",
55
55
  "magic-string": "^0.30.21",
56
- "wuchale": "^0.18.8"
56
+ "wuchale": "^0.19.1"
57
57
  },
58
58
  "devDependencies": {
59
59
  "acorn": "^8.15.0",
@@ -1,11 +1,11 @@
1
- import toRuntime from "wuchale/runtime"
1
+ import toRuntime from 'wuchale/runtime'
2
2
  import { locales } from '${DATA}'
3
3
 
4
4
  let locale = $state(locales[0])
5
5
 
6
6
  /**
7
7
  * @param {string} newLocale
8
- */
8
+ */
9
9
  export function setLocale(newLocale) {
10
10
  locale = newLocale
11
11
  }
@@ -13,8 +13,8 @@ export function setLocale(newLocale) {
13
13
  // for non-reactive
14
14
  /**
15
15
  * @param {{ [locale: string]: import("wuchale/runtime").CatalogModule }} catalogs
16
- */
17
- export const getRuntime = catalogs => toRuntime(catalogs[locale], locale)
16
+ */
17
+ export const getRuntime = (catalogs) => toRuntime(catalogs[locale], locale)
18
18
 
19
19
  // same function, only will be inside $derived when used
20
20
  export const getRuntimeRx = getRuntime
@@ -1,5 +1,5 @@
1
+ import { defaultCollection, registerLoaders } from 'wuchale/load-utils'
1
2
  import { loadCatalog, loadIDs } from '${PROXY}'
2
- import { registerLoaders, defaultCollection } from 'wuchale/load-utils'
3
3
 
4
4
  const key = '${KEY}'
5
5
 
@@ -1,5 +1,5 @@
1
- import { loadCatalog, loadIDs } from '${PROXY_SYNC}'
2
1
  import { currentRuntime } from 'wuchale/load-utils/server'
2
+ import { loadCatalog, loadIDs } from '${PROXY_SYNC}'
3
3
 
4
4
  const key = '${KEY}'
5
5
 
@@ -1,5 +1,5 @@
1
1
  <script>
2
- const {n = false, x, t, a} = $props()
2
+ const { n = false, x, t, a } = $props()
3
3
  </script>
4
4
 
5
5
  {#each x as fragment, i}