rask-ui 0.8.1 → 0.9.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/component.d.ts +12 -4
- package/dist/component.d.ts.map +1 -1
- package/dist/component.js +22 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin.d.ts +2 -19
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +23 -27
- package/package.json +1 -1
- package/swc-plugin/src/lib.rs +177 -48
- package/swc-plugin/target/wasm32-wasip1/release/deps/libswc_plugin_rask_component.rlib +0 -0
- package/swc-plugin/target/wasm32-wasip1/release/deps/swc_plugin_rask_component.wasm +0 -0
- package/swc-plugin/target/wasm32-wasip1/release/libswc_plugin_rask_component.rlib +0 -0
- package/swc-plugin/target/wasm32-wasip1/release/swc_plugin_rask_component.wasm +0 -0
package/dist/component.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { VNode, Component, Props } from "inferno";
|
|
2
|
-
|
|
2
|
+
import { Observer } from "./observation";
|
|
3
|
+
export type RaskStatelessFunctionComponent<P extends Props<any>> = (() => VNode) | ((props: P) => VNode);
|
|
4
|
+
export declare class RaskStatelessComponent extends Component {
|
|
5
|
+
renderFn: RaskStatelessFunctionComponent<any>;
|
|
6
|
+
observer: Observer;
|
|
7
|
+
shouldComponentUpdate(nextProps: Props<any>): boolean;
|
|
8
|
+
render(): VNode;
|
|
9
|
+
}
|
|
10
|
+
export declare function getCurrentComponent(): RaskStatefulComponent<any>;
|
|
3
11
|
export declare function createMountEffect(cb: () => void): void;
|
|
4
12
|
export declare function createCleanup(cb: () => void): void;
|
|
5
|
-
export type
|
|
6
|
-
export declare class
|
|
7
|
-
setup:
|
|
13
|
+
export type RaskStatefulFunctionComponent<P extends Props<any>> = (() => () => VNode) | ((props: P) => () => VNode);
|
|
14
|
+
export declare class RaskStatefulComponent<P extends Props<any>> extends Component<P> {
|
|
15
|
+
setup: RaskStatefulFunctionComponent<P>;
|
|
8
16
|
private renderFn?;
|
|
9
17
|
private reactiveProps?;
|
|
10
18
|
private observer;
|
package/dist/component.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACL,SAAS,EACT,KAAK,EAEN,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACL,SAAS,EACT,KAAK,EAEN,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAsB,QAAQ,EAAU,MAAM,eAAe,CAAC;AAGrE,MAAM,MAAM,8BAA8B,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAC3D,CAAC,MAAM,KAAK,CAAC,GACb,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC;AAE1B,qBAAa,sBAAuB,SAAQ,SAAS;IAC3C,QAAQ,EAAE,8BAA8B,CAAC,GAAG,CAAC,CAAC;IACtD,QAAQ,WAEL;IACH,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO;IAUrD,MAAM;CAMP;AAID,wBAAgB,mBAAmB,+BAMlC;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,QAM/C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,IAAI,QAM3C;AAED,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAC1D,CAAC,MAAM,MAAM,KAAK,CAAC,GACnB,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,CAAC;AAEhC,qBAAa,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IACnE,KAAK,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,QAAQ,CAEb;IACH,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAM;IAC3D,QAAQ,gBAAa;IACrB,eAAe;IAUf,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACjC,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACnC,OAAO,CAAC,mBAAmB;IA2D3B,iBAAiB,IAAI,IAAI;IAGzB,oBAAoB,IAAI,IAAI;IAG5B;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,GAAG;IAYlC,yBAAyB,IAAI,IAAI;IACjC,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO;IAWrD,MAAM;CAyCP;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,SAO9D"}
|
package/dist/component.js
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import { createComponentVNode, Component, } from "inferno";
|
|
2
2
|
import { getCurrentObserver, Observer, Signal } from "./observation";
|
|
3
3
|
import { syncBatch } from "./batch";
|
|
4
|
+
export class RaskStatelessComponent extends Component {
|
|
5
|
+
observer = new Observer(() => {
|
|
6
|
+
this.forceUpdate();
|
|
7
|
+
});
|
|
8
|
+
shouldComponentUpdate(nextProps) {
|
|
9
|
+
for (const prop in nextProps) {
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
if (this.props[prop] !== nextProps[prop]) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
render() {
|
|
18
|
+
const stopObserving = this.observer.observe();
|
|
19
|
+
const result = this.renderFn(this.props);
|
|
20
|
+
stopObserving();
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
4
24
|
let currentComponent;
|
|
5
25
|
export function getCurrentComponent() {
|
|
6
26
|
if (!currentComponent) {
|
|
@@ -20,7 +40,7 @@ export function createCleanup(cb) {
|
|
|
20
40
|
}
|
|
21
41
|
currentComponent.onCleanups.push(cb);
|
|
22
42
|
}
|
|
23
|
-
export class
|
|
43
|
+
export class RaskStatefulComponent extends Component {
|
|
24
44
|
renderFn;
|
|
25
45
|
reactiveProps;
|
|
26
46
|
observer = new Observer(() => {
|
|
@@ -113,9 +133,6 @@ export class RaskComponent extends Component {
|
|
|
113
133
|
shouldComponentUpdate(nextProps) {
|
|
114
134
|
// Shallow comparison of props, excluding internal props
|
|
115
135
|
for (const prop in nextProps) {
|
|
116
|
-
if (prop === "__component") {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
136
|
// @ts-ignore
|
|
120
137
|
if (this.props[prop] !== nextProps[prop]) {
|
|
121
138
|
return true;
|
|
@@ -162,5 +179,5 @@ export class RaskComponent extends Component {
|
|
|
162
179
|
}
|
|
163
180
|
}
|
|
164
181
|
export function createComponent(props, key) {
|
|
165
|
-
return createComponentVNode(4 /* VNodeFlags.ComponentClass */,
|
|
182
|
+
return createComponentVNode(4 /* VNodeFlags.ComponentClass */, RaskStatefulComponent, props, key);
|
|
166
183
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { render } from "./render";
|
|
2
|
-
export { createCleanup, createMountEffect,
|
|
2
|
+
export { createCleanup, createMountEffect, RaskStatefulComponent, RaskStatelessComponent, } from "./component";
|
|
3
3
|
export { createContext } from "./createContext";
|
|
4
4
|
export { createState } from "./createState";
|
|
5
5
|
export { createTask } from "./createTask";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { render } from "./render";
|
|
2
|
-
export { createCleanup, createMountEffect,
|
|
2
|
+
export { createCleanup, createMountEffect, RaskStatefulComponent, RaskStatelessComponent, } from "./component";
|
|
3
3
|
export { createContext } from "./createContext";
|
|
4
4
|
export { createState } from "./createState";
|
|
5
5
|
export { createTask } from "./createTask";
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
import type { Plugin } from
|
|
2
|
-
export interface RaskPluginOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Enable transformation of function components to RaskComponent classes
|
|
5
|
-
* @default true
|
|
6
|
-
*/
|
|
7
|
-
transformComponents?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* Import source for Inferno JSX runtime functions
|
|
10
|
-
* @default "rask-ui"
|
|
11
|
-
*/
|
|
12
|
-
importSource?: string;
|
|
13
|
-
/**
|
|
14
|
-
* Whether to define all arguments for createVNode/createComponentVNode
|
|
15
|
-
* @default false
|
|
16
|
-
*/
|
|
17
|
-
defineAllArguments?: boolean;
|
|
18
|
-
}
|
|
1
|
+
import type { Plugin } from "vite";
|
|
19
2
|
/**
|
|
20
3
|
* Vite plugin for transforming JSX to Inferno and function components to RaskComponent classes
|
|
21
4
|
*/
|
|
22
|
-
export default function raskPlugin(
|
|
5
|
+
export default function raskPlugin(): Plugin;
|
|
23
6
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAMnC
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAMnC;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,IAAI,MAAM,CAgF3C"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import { fileURLToPath } from
|
|
3
|
-
import { createRequire } from
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
4
|
const __filename = fileURLToPath(import.meta.url);
|
|
5
5
|
const __dirname = path.dirname(__filename);
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
7
|
/**
|
|
8
8
|
* Vite plugin for transforming JSX to Inferno and function components to RaskComponent classes
|
|
9
9
|
*/
|
|
10
|
-
export default function raskPlugin(
|
|
11
|
-
const { transformComponents = true, importSource = 'rask-ui', defineAllArguments = false, } = options;
|
|
10
|
+
export default function raskPlugin() {
|
|
12
11
|
// Resolve the path to swc-plugin-inferno WASM file
|
|
13
|
-
const infernoPluginPath = require.resolve(
|
|
12
|
+
const infernoPluginPath = require.resolve("swc-plugin-inferno/swc_plugin_inferno.wasm");
|
|
14
13
|
// Resolve the path to our RaskComponent plugin
|
|
15
|
-
const componentPluginPath = path.resolve(__dirname,
|
|
14
|
+
const componentPluginPath = path.resolve(__dirname, "../swc-plugin/target/wasm32-wasip1/release/swc_plugin_rask_component.wasm");
|
|
16
15
|
return {
|
|
17
|
-
name:
|
|
18
|
-
enforce:
|
|
16
|
+
name: "rask-plugin",
|
|
17
|
+
enforce: "pre",
|
|
19
18
|
config(config, { mode }) {
|
|
20
19
|
return {
|
|
21
|
-
esbuild: false, // Disable esbuild to use SWC
|
|
22
20
|
resolve: {
|
|
23
21
|
alias: {
|
|
24
22
|
// In development mode, use Inferno's development build to avoid the warning
|
|
25
|
-
...(mode ===
|
|
26
|
-
inferno:
|
|
23
|
+
...(mode === "development" && {
|
|
24
|
+
inferno: "inferno/dist/index.dev.mjs",
|
|
27
25
|
}),
|
|
28
26
|
},
|
|
29
27
|
},
|
|
@@ -35,35 +33,33 @@ export default function raskPlugin(options = {}) {
|
|
|
35
33
|
return null;
|
|
36
34
|
}
|
|
37
35
|
// Use SWC for transformation
|
|
38
|
-
const swc = await import(
|
|
36
|
+
const swc = await import("@swc/core");
|
|
39
37
|
const plugins = [
|
|
40
38
|
// 1. FIRST: Inferno JSX transformation
|
|
41
39
|
[
|
|
42
40
|
infernoPluginPath,
|
|
43
41
|
{
|
|
44
|
-
importSource,
|
|
45
|
-
defineAllArguments,
|
|
42
|
+
importSource: "rask-ui",
|
|
43
|
+
defineAllArguments: false,
|
|
46
44
|
},
|
|
47
45
|
],
|
|
48
46
|
];
|
|
49
47
|
// 2. SECOND: RaskComponent transformation (if enabled)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
]);
|
|
57
|
-
}
|
|
48
|
+
plugins.push([
|
|
49
|
+
componentPluginPath,
|
|
50
|
+
{
|
|
51
|
+
importSource: "rask-ui",
|
|
52
|
+
},
|
|
53
|
+
]);
|
|
58
54
|
const result = await swc.transform(code, {
|
|
59
55
|
filename: id,
|
|
60
56
|
jsc: {
|
|
61
57
|
parser: {
|
|
62
|
-
syntax: id.endsWith(
|
|
63
|
-
tsx: id.endsWith(
|
|
64
|
-
jsx: id.endsWith(
|
|
58
|
+
syntax: id.endsWith(".tsx") ? "typescript" : "ecmascript",
|
|
59
|
+
tsx: id.endsWith(".tsx"),
|
|
60
|
+
jsx: id.endsWith(".jsx"),
|
|
65
61
|
},
|
|
66
|
-
target:
|
|
62
|
+
target: "es2020",
|
|
67
63
|
experimental: {
|
|
68
64
|
plugins,
|
|
69
65
|
},
|
package/package.json
CHANGED
package/swc-plugin/src/lib.rs
CHANGED
|
@@ -15,14 +15,16 @@ pub struct Config {
|
|
|
15
15
|
|
|
16
16
|
pub struct RaskComponentTransform {
|
|
17
17
|
config: Config,
|
|
18
|
-
|
|
18
|
+
import_rask_stateful_component: Option<Ident>,
|
|
19
|
+
import_rask_stateless_component: Option<Ident>,
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
impl RaskComponentTransform {
|
|
22
23
|
fn new(config: Config) -> Self {
|
|
23
24
|
RaskComponentTransform {
|
|
24
25
|
config,
|
|
25
|
-
|
|
26
|
+
import_rask_stateful_component: None,
|
|
27
|
+
import_rask_stateless_component: None,
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -100,7 +102,27 @@ impl RaskComponentTransform {
|
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
/// Check if a function body returns
|
|
105
|
+
/// Check if a function body directly returns VNode calls (stateless component)
|
|
106
|
+
fn is_stateless_component(&self, func: &Function) -> bool {
|
|
107
|
+
if let Some(body) = &func.body {
|
|
108
|
+
for stmt in &body.stmts {
|
|
109
|
+
if let Stmt::Return(ret_stmt) = stmt {
|
|
110
|
+
if let Some(ret_arg) = &ret_stmt.arg {
|
|
111
|
+
// Check if directly returning VNode (not arrow function)
|
|
112
|
+
if self.has_vnode_call(ret_arg) {
|
|
113
|
+
// Make sure it's NOT an arrow function
|
|
114
|
+
if !matches!(&**ret_arg, Expr::Arrow(_)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Check if a function body returns an arrow function with VNode calls (stateful component)
|
|
104
126
|
fn is_rask_component(&self, func: &Function) -> bool {
|
|
105
127
|
if let Some(body) = &func.body {
|
|
106
128
|
for stmt in &body.stmts {
|
|
@@ -135,14 +157,14 @@ impl RaskComponentTransform {
|
|
|
135
157
|
false
|
|
136
158
|
}
|
|
137
159
|
|
|
138
|
-
/// Transform a function declaration to a
|
|
139
|
-
fn
|
|
140
|
-
// Ensure we have the
|
|
141
|
-
if self.
|
|
142
|
-
self.
|
|
160
|
+
/// Transform a function declaration to a RaskStatefulComponent class
|
|
161
|
+
fn transform_to_stateful_class(&mut self, name: Ident, func: Function) -> Decl {
|
|
162
|
+
// Ensure we have the RaskStatefulComponent import
|
|
163
|
+
if self.import_rask_stateful_component.is_none() {
|
|
164
|
+
self.import_rask_stateful_component = Some(private_ident!("RaskStatefulComponent"));
|
|
143
165
|
}
|
|
144
166
|
|
|
145
|
-
let super_class_ident = self.
|
|
167
|
+
let super_class_ident = self.import_rask_stateful_component.as_ref().unwrap().clone();
|
|
146
168
|
|
|
147
169
|
// Create the class property: setup = function name() { ... }
|
|
148
170
|
let setup_prop = ClassMember::ClassProp(ClassProp {
|
|
@@ -181,6 +203,52 @@ impl RaskComponentTransform {
|
|
|
181
203
|
})
|
|
182
204
|
}
|
|
183
205
|
|
|
206
|
+
/// Transform a function declaration to a RaskStatelessComponent class
|
|
207
|
+
fn transform_to_stateless_class(&mut self, name: Ident, func: Function) -> Decl {
|
|
208
|
+
// Ensure we have the RaskStatelessComponent import
|
|
209
|
+
if self.import_rask_stateless_component.is_none() {
|
|
210
|
+
self.import_rask_stateless_component = Some(private_ident!("RaskStatelessComponent"));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let super_class_ident = self.import_rask_stateless_component.as_ref().unwrap().clone();
|
|
214
|
+
|
|
215
|
+
// Create the class property: renderFn = function name() { ... }
|
|
216
|
+
let render_prop = ClassMember::ClassProp(ClassProp {
|
|
217
|
+
span: Default::default(),
|
|
218
|
+
key: PropName::Ident(quote_ident!("renderFn").into()),
|
|
219
|
+
value: Some(Box::new(Expr::Fn(FnExpr {
|
|
220
|
+
ident: Some(name.clone()),
|
|
221
|
+
function: Box::new(func),
|
|
222
|
+
}))),
|
|
223
|
+
type_ann: None,
|
|
224
|
+
is_static: false,
|
|
225
|
+
decorators: vec![],
|
|
226
|
+
accessibility: None,
|
|
227
|
+
is_abstract: false,
|
|
228
|
+
is_optional: false,
|
|
229
|
+
is_override: false,
|
|
230
|
+
readonly: false,
|
|
231
|
+
declare: false,
|
|
232
|
+
definite: false,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
Decl::Class(ClassDecl {
|
|
236
|
+
ident: name,
|
|
237
|
+
declare: false,
|
|
238
|
+
class: Box::new(Class {
|
|
239
|
+
span: Default::default(),
|
|
240
|
+
ctxt: Default::default(),
|
|
241
|
+
decorators: vec![],
|
|
242
|
+
body: vec![render_prop],
|
|
243
|
+
super_class: Some(Box::new(Expr::Ident(super_class_ident))),
|
|
244
|
+
is_abstract: false,
|
|
245
|
+
type_params: None,
|
|
246
|
+
super_type_params: None,
|
|
247
|
+
implements: vec![],
|
|
248
|
+
}),
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
|
|
184
252
|
/// Rewrite imports from "inferno" to the configured import source
|
|
185
253
|
fn rewrite_inferno_imports(&mut self, module: &mut Module) {
|
|
186
254
|
let import_source = self
|
|
@@ -204,12 +272,8 @@ impl RaskComponentTransform {
|
|
|
204
272
|
}
|
|
205
273
|
}
|
|
206
274
|
|
|
207
|
-
/// Inject the
|
|
275
|
+
/// Inject the RaskStatefulComponent and/or RaskStatelessComponent imports at the top of the module
|
|
208
276
|
fn inject_runtime(&mut self, module: &mut Module) {
|
|
209
|
-
if self.import_rask_component.is_none() {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
277
|
let import_source = self
|
|
214
278
|
.config
|
|
215
279
|
.import_source
|
|
@@ -217,47 +281,93 @@ impl RaskComponentTransform {
|
|
|
217
281
|
.map(|s| s.as_str())
|
|
218
282
|
.unwrap_or("rask-ui");
|
|
219
283
|
|
|
220
|
-
let
|
|
284
|
+
let mut specifiers = vec![];
|
|
285
|
+
|
|
286
|
+
// Add RaskStatefulComponent if needed
|
|
287
|
+
if let Some(stateful_ident) = &self.import_rask_stateful_component {
|
|
288
|
+
// Check if import already exists
|
|
289
|
+
let mut exists = false;
|
|
290
|
+
for item in &module.body {
|
|
291
|
+
if let ModuleItem::ModuleDecl(ModuleDecl::Import(import)) = item {
|
|
292
|
+
if &*import.src.value == import_source {
|
|
293
|
+
for spec in &import.specifiers {
|
|
294
|
+
if let ImportSpecifier::Named(named) = spec {
|
|
295
|
+
if let Some(ModuleExportName::Ident(imported)) = &named.imported {
|
|
296
|
+
if &*imported.sym == "RaskStatefulComponent" {
|
|
297
|
+
exists = true;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
} else if &*named.local.sym == "RaskStatefulComponent" {
|
|
301
|
+
exists = true;
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
221
309
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
310
|
+
if !exists {
|
|
311
|
+
specifiers.push(ImportSpecifier::Named(ImportNamedSpecifier {
|
|
312
|
+
span: Default::default(),
|
|
313
|
+
local: stateful_ident.clone(),
|
|
314
|
+
imported: Some(ModuleExportName::Ident(quote_ident!("RaskStatefulComponent").into())),
|
|
315
|
+
is_type_only: false,
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Add RaskStatelessComponent if needed
|
|
321
|
+
if let Some(stateless_ident) = &self.import_rask_stateless_component {
|
|
322
|
+
// Check if import already exists
|
|
323
|
+
let mut exists = false;
|
|
324
|
+
for item in &module.body {
|
|
325
|
+
if let ModuleItem::ModuleDecl(ModuleDecl::Import(import)) = item {
|
|
326
|
+
if &*import.src.value == import_source {
|
|
327
|
+
for spec in &import.specifiers {
|
|
328
|
+
if let ImportSpecifier::Named(named) = spec {
|
|
329
|
+
if let Some(ModuleExportName::Ident(imported)) = &named.imported {
|
|
330
|
+
if &*imported.sym == "RaskStatelessComponent" {
|
|
331
|
+
exists = true;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
} else if &*named.local.sym == "RaskStatelessComponent" {
|
|
335
|
+
exists = true;
|
|
336
|
+
break;
|
|
231
337
|
}
|
|
232
|
-
} else if &*named.local.sym == "RaskComponent" {
|
|
233
|
-
return; // Import already exists
|
|
234
338
|
}
|
|
235
339
|
}
|
|
236
340
|
}
|
|
237
341
|
}
|
|
238
342
|
}
|
|
343
|
+
|
|
344
|
+
if !exists {
|
|
345
|
+
specifiers.push(ImportSpecifier::Named(ImportNamedSpecifier {
|
|
346
|
+
span: Default::default(),
|
|
347
|
+
local: stateless_ident.clone(),
|
|
348
|
+
imported: Some(ModuleExportName::Ident(quote_ident!("RaskStatelessComponent").into())),
|
|
349
|
+
is_type_only: false,
|
|
350
|
+
}));
|
|
351
|
+
}
|
|
239
352
|
}
|
|
240
353
|
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
specifiers: vec![ImportSpecifier::Named(ImportNamedSpecifier {
|
|
245
|
-
span: Default::default(),
|
|
246
|
-
local: rask_component_ident.clone(),
|
|
247
|
-
imported: Some(ModuleExportName::Ident(quote_ident!("RaskComponent").into())),
|
|
248
|
-
is_type_only: false,
|
|
249
|
-
})],
|
|
250
|
-
src: Box::new(Str {
|
|
354
|
+
// Only create import if we have specifiers to add
|
|
355
|
+
if !specifiers.is_empty() {
|
|
356
|
+
let import = ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl {
|
|
251
357
|
span: Default::default(),
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
358
|
+
specifiers,
|
|
359
|
+
src: Box::new(Str {
|
|
360
|
+
span: Default::default(),
|
|
361
|
+
value: Wtf8Atom::from(import_source),
|
|
362
|
+
raw: None,
|
|
363
|
+
}),
|
|
364
|
+
type_only: false,
|
|
365
|
+
with: None,
|
|
366
|
+
phase: Default::default(),
|
|
367
|
+
}));
|
|
368
|
+
|
|
369
|
+
module.body.insert(0, import);
|
|
370
|
+
}
|
|
261
371
|
}
|
|
262
372
|
}
|
|
263
373
|
|
|
@@ -278,11 +388,19 @@ impl VisitMut for RaskComponentTransform {
|
|
|
278
388
|
fn visit_mut_module_item(&mut self, item: &mut ModuleItem) {
|
|
279
389
|
match item {
|
|
280
390
|
ModuleItem::Stmt(Stmt::Decl(Decl::Fn(fn_decl))) => {
|
|
281
|
-
// Check
|
|
391
|
+
// Check for stateful component first (returns arrow function)
|
|
282
392
|
if self.is_rask_component(&fn_decl.function) {
|
|
283
393
|
let name = fn_decl.ident.clone();
|
|
284
394
|
let func = (*fn_decl.function).clone();
|
|
285
|
-
let class_decl = self.
|
|
395
|
+
let class_decl = self.transform_to_stateful_class(name, func);
|
|
396
|
+
*item = ModuleItem::Stmt(Stmt::Decl(class_decl));
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
// Then check for stateless component (directly returns VNode)
|
|
400
|
+
else if self.is_stateless_component(&fn_decl.function) {
|
|
401
|
+
let name = fn_decl.ident.clone();
|
|
402
|
+
let func = (*fn_decl.function).clone();
|
|
403
|
+
let class_decl = self.transform_to_stateless_class(name, func);
|
|
286
404
|
*item = ModuleItem::Stmt(Stmt::Decl(class_decl));
|
|
287
405
|
return;
|
|
288
406
|
}
|
|
@@ -295,16 +413,27 @@ impl VisitMut for RaskComponentTransform {
|
|
|
295
413
|
// but transform the pattern internally if needed
|
|
296
414
|
// For now, we'll skip transforming default exports
|
|
297
415
|
// as they need special handling
|
|
416
|
+
} else if self.is_stateless_component(&fn_expr.function) {
|
|
417
|
+
// Same for stateless default exports
|
|
298
418
|
}
|
|
299
419
|
}
|
|
300
420
|
}
|
|
301
421
|
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(export)) => {
|
|
302
422
|
// Handle: export function MyComponent() { return () => <div /> }
|
|
303
423
|
if let Decl::Fn(fn_decl) = &mut export.decl {
|
|
424
|
+
// Check for stateful component first
|
|
304
425
|
if self.is_rask_component(&fn_decl.function) {
|
|
305
426
|
let name = fn_decl.ident.clone();
|
|
306
427
|
let func = (*fn_decl.function).clone();
|
|
307
|
-
let class_decl = self.
|
|
428
|
+
let class_decl = self.transform_to_stateful_class(name, func);
|
|
429
|
+
export.decl = class_decl;
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
// Then check for stateless component
|
|
433
|
+
else if self.is_stateless_component(&fn_decl.function) {
|
|
434
|
+
let name = fn_decl.ident.clone();
|
|
435
|
+
let func = (*fn_decl.function).clone();
|
|
436
|
+
let class_decl = self.transform_to_stateless_class(name, func);
|
|
308
437
|
export.decl = class_decl;
|
|
309
438
|
return;
|
|
310
439
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|