@wuchale/jsx 0.8.1 → 0.9.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.d.ts +8 -2
- package/dist/index.js +35 -44
- package/dist/transformer.d.ts +2 -2
- package/dist/transformer.js +26 -14
- package/package.json +3 -3
- package/src/loaders/react.bundle.js +6 -7
- package/src/loaders/react.js +12 -13
- package/src/loaders/solidjs.bundle.js +3 -2
- package/src/loaders/solidjs.js +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import type { HeuristicFunc, Adapter, AdapterArgs } from 'wuchale';
|
|
1
|
+
import type { HeuristicFunc, Adapter, AdapterArgs, LoaderChoice, CreateHeuristicOpts } from 'wuchale';
|
|
2
2
|
import { type JSXLib } from "./transformer.js";
|
|
3
|
+
export declare function createJsxHeuristic(opts: CreateHeuristicOpts): HeuristicFunc;
|
|
3
4
|
export declare const jsxDefaultHeuristic: HeuristicFunc;
|
|
4
|
-
type
|
|
5
|
+
type LoadersAvailable = 'default' | 'react' | 'solidjs';
|
|
6
|
+
type JSXArgs = AdapterArgs<LoadersAvailable> & {
|
|
5
7
|
variant?: JSXLib;
|
|
6
8
|
};
|
|
9
|
+
export declare function getDefaultLoaderPath(loader: LoaderChoice<LoadersAvailable>, bundle: boolean): string | {
|
|
10
|
+
client: string;
|
|
11
|
+
server: string;
|
|
12
|
+
};
|
|
7
13
|
export declare const adapter: (args?: JSXArgs) => Adapter;
|
|
8
14
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import { defaultGenerateLoadID,
|
|
2
|
-
import { pluralPattern,
|
|
1
|
+
import { defaultGenerateLoadID, deepMergeObjects, createHeuristic, defaultHeuristicOpts } from 'wuchale';
|
|
2
|
+
import { pluralPattern, getDefaultLoaderPath as getDefaultLoaderPathVanilla } from 'wuchale/adapter-vanilla';
|
|
3
3
|
import { JSXTransformer } from "./transformer.js";
|
|
4
|
-
import {
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
import { loaderPathResolver } from 'wuchale/adapter-utils';
|
|
5
|
+
export function createJsxHeuristic(opts) {
|
|
6
|
+
const defaultHeuristic = createHeuristic(opts);
|
|
7
|
+
return msg => {
|
|
8
|
+
const defRes = defaultHeuristic(msg);
|
|
9
|
+
if (!defRes) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
if (msg.details.scope !== 'script') {
|
|
13
|
+
return defRes;
|
|
14
|
+
}
|
|
15
|
+
if (msg.details.declaring === 'variable') {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return defRes;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export const jsxDefaultHeuristic = createJsxHeuristic(defaultHeuristicOpts);
|
|
17
22
|
const defaultRuntime = {
|
|
18
23
|
useReactive: ({ funcName, nested }) => {
|
|
19
24
|
const inTopLevel = funcName == null;
|
|
@@ -24,12 +29,10 @@ const defaultRuntime = {
|
|
|
24
29
|
};
|
|
25
30
|
},
|
|
26
31
|
reactive: {
|
|
27
|
-
importName: 'default',
|
|
28
32
|
wrapInit: expr => expr,
|
|
29
33
|
wrapUse: expr => expr,
|
|
30
34
|
},
|
|
31
35
|
plain: {
|
|
32
|
-
importName: 'get',
|
|
33
36
|
wrapInit: expr => expr,
|
|
34
37
|
wrapUse: expr => expr,
|
|
35
38
|
},
|
|
@@ -44,56 +47,44 @@ const defaultRuntimeSolid = {
|
|
|
44
47
|
};
|
|
45
48
|
},
|
|
46
49
|
reactive: {
|
|
47
|
-
importName: 'default',
|
|
48
50
|
wrapInit: expr => `() => ${expr}`,
|
|
49
51
|
wrapUse: expr => `${expr}()`
|
|
50
52
|
}
|
|
51
53
|
};
|
|
52
54
|
const defaultArgs = {
|
|
53
55
|
files: { include: 'src/**/*.{js,ts,jsx,tsx}', ignore: '**/*.d.ts' },
|
|
54
|
-
|
|
56
|
+
localesDir: './src/locales',
|
|
55
57
|
patterns: [pluralPattern],
|
|
56
58
|
heuristic: jsxDefaultHeuristic,
|
|
57
59
|
granularLoad: false,
|
|
58
60
|
bundleLoad: false,
|
|
61
|
+
loader: 'default',
|
|
59
62
|
generateLoadID: defaultGenerateLoadID,
|
|
60
|
-
writeFiles: {},
|
|
61
63
|
runtime: defaultRuntime,
|
|
62
64
|
variant: 'default',
|
|
63
65
|
};
|
|
64
66
|
const resolveLoaderPath = loaderPathResolver(import.meta.url, '../src/loaders', 'js');
|
|
67
|
+
export function getDefaultLoaderPath(loader, bundle) {
|
|
68
|
+
if (loader === 'default') {
|
|
69
|
+
return getDefaultLoaderPathVanilla('bundle', bundle);
|
|
70
|
+
}
|
|
71
|
+
if (bundle) {
|
|
72
|
+
loader += '.bundle';
|
|
73
|
+
}
|
|
74
|
+
return resolveLoaderPath(loader);
|
|
75
|
+
}
|
|
65
76
|
export const adapter = (args = defaultArgs) => {
|
|
66
|
-
let { heuristic, patterns, variant, runtime, ...rest } = deepMergeObjects(args, defaultArgs);
|
|
77
|
+
let { heuristic, patterns, variant, runtime, loader, ...rest } = deepMergeObjects(args, defaultArgs);
|
|
67
78
|
if (variant === 'solidjs' && args.runtime == null) {
|
|
68
79
|
runtime = defaultRuntimeSolid;
|
|
69
80
|
}
|
|
70
81
|
return {
|
|
71
|
-
transform: ({ content, filename, index, expr }) => {
|
|
72
|
-
return new JSXTransformer(content, filename, index, heuristic, patterns, expr, runtime).transformJx(variant);
|
|
82
|
+
transform: ({ content, filename, index, expr, matchUrl }) => {
|
|
83
|
+
return new JSXTransformer(content, filename, index, heuristic, patterns, expr, runtime, matchUrl).transformJx(variant);
|
|
73
84
|
},
|
|
74
85
|
loaderExts: ['.js', '.ts'],
|
|
75
|
-
|
|
76
|
-
const deps = await getDependencies();
|
|
77
|
-
const loaders = ['default'];
|
|
78
|
-
if (deps.has('react') || deps.has('preact')) {
|
|
79
|
-
loaders.unshift('react');
|
|
80
|
-
}
|
|
81
|
-
if (deps.has('solid-js')) {
|
|
82
|
-
loaders.unshift('solidjs');
|
|
83
|
-
}
|
|
84
|
-
return loaders;
|
|
85
|
-
},
|
|
86
|
-
defaultLoaderPath: (loader) => {
|
|
87
|
-
if (loader === 'default') {
|
|
88
|
-
return vanillaAdapter({ bundleLoad: rest.bundleLoad }).defaultLoaderPath('vite');
|
|
89
|
-
}
|
|
90
|
-
if (rest.bundleLoad) {
|
|
91
|
-
loader += '.bundle';
|
|
92
|
-
}
|
|
93
|
-
return resolveLoaderPath(loader);
|
|
94
|
-
},
|
|
86
|
+
defaultLoaderPath: getDefaultLoaderPath(loader, rest.bundleLoad),
|
|
95
87
|
runtime,
|
|
96
88
|
...rest,
|
|
97
|
-
docsUrl: 'https://wuchale.dev/adapters/jsx'
|
|
98
89
|
};
|
|
99
90
|
};
|
package/dist/transformer.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Message } from 'wuchale';
|
|
|
2
2
|
import type * as JX from 'estree-jsx';
|
|
3
3
|
import type * as Estree from 'acorn';
|
|
4
4
|
import { Transformer } from 'wuchale/adapter-vanilla';
|
|
5
|
-
import type { IndexTracker, HeuristicFunc, TransformOutput, RuntimeConf, CatalogExpr, CodePattern } from 'wuchale';
|
|
5
|
+
import type { IndexTracker, HeuristicFunc, TransformOutput, RuntimeConf, CatalogExpr, CodePattern, UrlMatcher } from 'wuchale';
|
|
6
6
|
import { MixedVisitor, type CommentDirectives } from "wuchale/adapter-utils";
|
|
7
7
|
export declare function parseScriptJSX(content: string): [Estree.Program, Estree.Comment[][]];
|
|
8
8
|
type MixedNodesTypes = JX.JSXElement | JX.JSXFragment | JX.JSXText | JX.JSXExpressionContainer | JX.JSXSpreadChild;
|
|
@@ -14,7 +14,7 @@ export declare class JSXTransformer extends Transformer {
|
|
|
14
14
|
lastVisitIsComment: boolean;
|
|
15
15
|
currentJsxKey?: number;
|
|
16
16
|
mixedVisitor: MixedVisitor<MixedNodesTypes>;
|
|
17
|
-
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf);
|
|
17
|
+
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: CatalogExpr, rtConf: RuntimeConf, matchUrl: UrlMatcher);
|
|
18
18
|
initMixedVisitor: () => MixedVisitor<MixedNodesTypes>;
|
|
19
19
|
visitChildrenJ: (node: JX.JSXElement | JX.JSXFragment) => Message[];
|
|
20
20
|
visitNameJSXNamespacedName: (node: JX.JSXNamespacedName) => string;
|
package/dist/transformer.js
CHANGED
|
@@ -19,8 +19,8 @@ export class JSXTransformer extends Transformer {
|
|
|
19
19
|
lastVisitIsComment = false;
|
|
20
20
|
currentJsxKey;
|
|
21
21
|
mixedVisitor;
|
|
22
|
-
constructor(content, filename, index, heuristic, patterns, catalogExpr, rtConf) {
|
|
23
|
-
super(content, filename, index, heuristic, patterns, catalogExpr, rtConf);
|
|
22
|
+
constructor(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl) {
|
|
23
|
+
super(content, filename, index, heuristic, patterns, catalogExpr, rtConf, matchUrl);
|
|
24
24
|
}
|
|
25
25
|
initMixedVisitor = () => new MixedVisitor({
|
|
26
26
|
mstr: this.mstr,
|
|
@@ -36,6 +36,7 @@ export class JSXTransformer extends Transformer {
|
|
|
36
36
|
// @ts-expect-error
|
|
37
37
|
&& node.expression.end > node.expression.start,
|
|
38
38
|
isText: node => node.type === 'JSXText',
|
|
39
|
+
leaveInPlace: () => false,
|
|
39
40
|
isExpression: node => node.type === 'JSXExpressionContainer',
|
|
40
41
|
getTextContent: (node) => node.value,
|
|
41
42
|
getCommentData: (node) => this.getMarkupCommentBody(node.expression),
|
|
@@ -49,7 +50,7 @@ export class JSXTransformer extends Transformer {
|
|
|
49
50
|
},
|
|
50
51
|
visitExpressionTag: this.visitJSXExpressionContainer,
|
|
51
52
|
fullHeuristicDetails: this.fullHeuristicDetails,
|
|
52
|
-
checkHeuristic: this.
|
|
53
|
+
checkHeuristic: this.getHeuristicMessageType,
|
|
53
54
|
index: this.index,
|
|
54
55
|
wrapNested: (msgInfo, hasExprs, nestedRanges, lastChildEnd) => {
|
|
55
56
|
let begin = `<${rtComponent}`;
|
|
@@ -151,13 +152,6 @@ export class JSXTransformer extends Transformer {
|
|
|
151
152
|
if (node.value == null) {
|
|
152
153
|
return [];
|
|
153
154
|
}
|
|
154
|
-
if (node.value.type !== 'Literal') {
|
|
155
|
-
return this.visitJx(node.value);
|
|
156
|
-
}
|
|
157
|
-
if (typeof node.value.value !== 'string') {
|
|
158
|
-
return [];
|
|
159
|
-
}
|
|
160
|
-
const value = node.value;
|
|
161
155
|
let name;
|
|
162
156
|
if (node.name.type === 'JSXIdentifier') {
|
|
163
157
|
name = node.name.name;
|
|
@@ -165,11 +159,29 @@ export class JSXTransformer extends Transformer {
|
|
|
165
159
|
else {
|
|
166
160
|
name = node.name.name.name;
|
|
167
161
|
}
|
|
168
|
-
const
|
|
169
|
-
scope: '
|
|
162
|
+
const heurBase = {
|
|
163
|
+
scope: 'script',
|
|
170
164
|
element: this.currentElement,
|
|
171
165
|
attribute: name,
|
|
172
|
-
}
|
|
166
|
+
};
|
|
167
|
+
if (node.value.type !== 'Literal') {
|
|
168
|
+
if (node.value.type === 'JSXExpressionContainer') {
|
|
169
|
+
if (node.value.expression.type === 'Literal' && typeof node.value.expression.value === 'string') {
|
|
170
|
+
const expr = node.value.expression;
|
|
171
|
+
return this.visitWithCommentDirectives(expr, () => this.visitLiteral(expr, heurBase));
|
|
172
|
+
}
|
|
173
|
+
if (node.value.expression.type === 'TemplateLiteral') {
|
|
174
|
+
const expr = node.value.expression;
|
|
175
|
+
return this.visitWithCommentDirectives(expr, () => this.visitTemplateLiteral(expr, heurBase));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return this.visitJx(node.value);
|
|
179
|
+
}
|
|
180
|
+
if (typeof node.value.value !== 'string') {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
const value = node.value;
|
|
184
|
+
const [pass, msgInfo] = this.checkHeuristic(node.value.value, heurBase);
|
|
173
185
|
if (!pass) {
|
|
174
186
|
return [];
|
|
175
187
|
}
|
|
@@ -212,7 +224,7 @@ export class JSXTransformer extends Transformer {
|
|
|
212
224
|
if (this.commentDirectives.ignoreFile) {
|
|
213
225
|
return [];
|
|
214
226
|
}
|
|
215
|
-
if (this.commentDirectives.
|
|
227
|
+
if (this.commentDirectives.forceType !== false) {
|
|
216
228
|
msgs = this.visit(node);
|
|
217
229
|
}
|
|
218
230
|
this.commentDirectives = commentDirectivesPrev;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wuchale/jsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Protobuf-like i18n from plain code: JSX adapter",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "tsc --watch",
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@sveltejs/acorn-typescript": "^1.0.6",
|
|
73
73
|
"acorn": "^8.15.0",
|
|
74
|
-
"wuchale": "^0.
|
|
74
|
+
"wuchale": "^0.18.0"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@types/estree-jsx": "^1.0.5",
|
|
78
|
-
"typescript": "^5.
|
|
78
|
+
"typescript": "^5.9.3"
|
|
79
79
|
},
|
|
80
80
|
"type": "module"
|
|
81
81
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// This is just the default loader.
|
|
2
2
|
// You can customize it however you want, it will not be overwritten once it exists and is not empty.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { useState, useEffect } from 'react'
|
|
4
|
+
import { useState, useEffect, useMemo } from 'react'
|
|
5
|
+
import toRuntime from 'wuchale/runtime'
|
|
7
6
|
|
|
8
7
|
let locale = 'en'
|
|
9
8
|
|
|
@@ -18,15 +17,15 @@ export function setLocale(locale) {
|
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
export
|
|
20
|
+
export const getRuntimeRx = (/** @type {{[locale: string]: import('wuchale/runtime').CatalogModule }} */ catalogs) => {
|
|
22
21
|
const [locale, setLocale] = useState('en')
|
|
23
22
|
useEffect(() => {
|
|
24
23
|
const cb = (/** @type {string} */ locale) => setLocale(locale)
|
|
25
24
|
callbacks.add(cb)
|
|
26
25
|
return () => callbacks.delete(cb)
|
|
27
|
-
})
|
|
28
|
-
return catalogs[locale]
|
|
26
|
+
}, [catalogs])
|
|
27
|
+
return useMemo(() => toRuntime(catalogs[locale], locale), [locale, catalogs])
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
// non-reactive
|
|
32
|
-
export const
|
|
31
|
+
export const getRuntime = (/** @type {{[locale: string]: import('wuchale/runtime').CatalogModule }} */ catalogs) => toRuntime(catalogs[locale], locale)
|
package/src/loaders/react.js
CHANGED
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
// This is just the default loader.
|
|
2
2
|
// You can customize it however you want, it will not be overwritten once it exists and is not empty.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { loadCatalog, loadIDs, key } from 'virtual:wuchale/proxy' // or proxy/sync
|
|
4
|
+
import { loadCatalog, loadIDs } from '${PROXY}'
|
|
7
5
|
import { registerLoaders } from 'wuchale/load-utils'
|
|
8
6
|
import { useState, useEffect } from 'react'
|
|
9
7
|
|
|
8
|
+
export const key = '${KEY}'
|
|
10
9
|
const callbacks = {}
|
|
11
10
|
const store = {}
|
|
12
11
|
|
|
13
12
|
// non-reactive
|
|
14
|
-
export const
|
|
13
|
+
export const getRuntime = (/** @type {string} */ loadID) => store[loadID]
|
|
15
14
|
|
|
16
15
|
const collection = {
|
|
17
|
-
get,
|
|
18
|
-
set: (/** @type {string} */ loadID, /** @type {import('wuchale/runtime').
|
|
19
|
-
store[loadID] =
|
|
20
|
-
callbacks[loadID]?.(
|
|
16
|
+
get: getRuntime,
|
|
17
|
+
set: (/** @type {string} */ loadID, /** @type {import('wuchale/runtime').Runtime} */ runtime) => {
|
|
18
|
+
store[loadID] = runtime // for when useEffect hasn't run yet
|
|
19
|
+
callbacks[loadID]?.(runtime)
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
registerLoaders(key, loadCatalog, loadIDs, collection)
|
|
25
24
|
|
|
26
|
-
export
|
|
27
|
-
const [
|
|
25
|
+
export const getRuntimeRx = (/** @type {string} */ loadID) => {
|
|
26
|
+
const [runtime, setRuntime] = useState(collection.get(loadID))
|
|
28
27
|
useEffect(() => {
|
|
29
|
-
callbacks[loadID] = (/** @type {import('wuchale/runtime').
|
|
28
|
+
callbacks[loadID] = (/** @type {import('wuchale/runtime').Runtime} */ runtime) => setRuntime(runtime)
|
|
30
29
|
return () => delete callbacks[loadID]
|
|
31
|
-
})
|
|
32
|
-
return
|
|
30
|
+
}, [loadID])
|
|
31
|
+
return runtime
|
|
33
32
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// The content is this way because you have enabled bundleLoad in the config.
|
|
4
4
|
|
|
5
5
|
import { createSignal } from "solid-js"
|
|
6
|
+
import toRuntime from "wuchale/runtime"
|
|
6
7
|
|
|
7
8
|
const [locale, setLocale] = createSignal('en')
|
|
8
9
|
|
|
@@ -11,6 +12,6 @@ export { setLocale }
|
|
|
11
12
|
/**
|
|
12
13
|
* @param {{ [locale: string]: import('wuchale/runtime').CatalogModule }} catalogs
|
|
13
14
|
*/
|
|
14
|
-
export const
|
|
15
|
+
export const getRuntimeRx = catalogs => toRuntime(catalogs[locale()], locale())
|
|
15
16
|
// same function, because solid-js can use them anywhere
|
|
16
|
-
export
|
|
17
|
+
export const getRuntime = getRuntimeRx
|
package/src/loaders/solidjs.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// This is just the default loader.
|
|
2
2
|
// You can customize it however you want, it will not be overwritten once it exists and is not empty.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { loadCatalog, loadIDs, key } from 'virtual:wuchale/proxy' // or proxy/sync
|
|
4
|
+
import { loadCatalog, loadIDs } from '${PROXY}'
|
|
7
5
|
import { registerLoaders } from 'wuchale/load-utils'
|
|
8
6
|
import { createStore } from 'solid-js/store'
|
|
9
7
|
|
|
8
|
+
const key = '${KEY}'
|
|
9
|
+
|
|
10
10
|
const [store, setStore] = createStore({})
|
|
11
11
|
|
|
12
12
|
// two exports. can be the same because solid-js can use them anywhere unlike react
|
|
13
|
-
export const
|
|
13
|
+
export const getRuntimeRx = registerLoaders(key, loadCatalog, loadIDs, {
|
|
14
14
|
get: loadID => store[loadID],
|
|
15
15
|
set: setStore,
|
|
16
16
|
})
|
|
17
|
-
export
|
|
17
|
+
export const getRuntime = getRuntimeRx
|