Skip to content

Commit 5bd92b5

Browse files
committed
feat: communicate with js
1 parent 64fa012 commit 5bd92b5

File tree

12 files changed

+308
-73
lines changed

12 files changed

+308
-73
lines changed

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/node_binding/binding.d.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export declare class JsCompilation {
138138
addRuntimeModule(chunk: JsChunk, runtimeModule: JsAddingRuntimeModule): void
139139
get moduleGraph(): JsModuleGraph
140140
get chunkGraph(): JsChunkGraph
141-
addInclude(args: [string, RawDependency, RawEntryOptions | undefined][], callback: (errMsg: Error | null, results: [string | null, JsDependency | null, JsModule | null][]) => void): void
141+
addInclude(args: [string, RawDependency, JsEntryOptions | undefined][], callback: (errMsg: Error | null, results: [string | null, JsDependency | null, JsModule | null][]) => void): void
142142
}
143143

144144
export declare class JsContextModuleFactoryAfterResolveData {
@@ -271,7 +271,7 @@ export declare class JsModuleGraphConnection {
271271

272272
export declare class JsResolver {
273273
resolveSync(path: string, request: string): string | false
274-
withOptions(JsResolver): JsResolverWrapper
274+
withOptions(raw?: RawResolveOptionsWithDependencyType | undefined | null): JsResolver
275275
}
276276

277277
export declare class JsResolverFactory {
@@ -378,7 +378,8 @@ export declare enum BuiltinPluginName {
378378
BundlerInfoRspackPlugin = 'BundlerInfoRspackPlugin',
379379
CssExtractRspackPlugin = 'CssExtractRspackPlugin',
380380
JsLoaderRspackPlugin = 'JsLoaderRspackPlugin',
381-
LazyCompilationPlugin = 'LazyCompilationPlugin'
381+
LazyCompilationPlugin = 'LazyCompilationPlugin',
382+
FlightClientEntryPlugin = 'FlightClientEntryPlugin'
382383
}
383384

384385
export declare function cleanupGlobalTrace(): void
@@ -390,6 +391,11 @@ export interface ContextInfo {
390391

391392
export declare function formatDiagnostic(diagnostic: JsDiagnostic): ExternalObject<'Diagnostic'>
392393

394+
export interface JsAction {
395+
workers: Record<string, JsModuleInfo>
396+
layer: Record<string, string>
397+
}
398+
393399
export interface JsAddingRuntimeModule {
394400
name: string
395401
generator: () => String
@@ -671,7 +677,7 @@ export interface JsExternalItemFnCtx {
671677
context: string
672678
dependencyType: string
673679
contextInfo: ContextInfo
674-
resolver: JsResolverWrapper
680+
resolver: JsResolver
675681
}
676682

677683
export interface JsFactorizeArgs {
@@ -685,6 +691,18 @@ export interface JsFactoryMeta {
685691
sideEffectFree?: boolean
686692
}
687693

694+
export interface JsFlightClientEntryPluginState {
695+
serverActions: Record<string, JsAction>
696+
edgeServerActions: Record<string, JsAction>
697+
serverActionModules: Record<string, JsModulePair>
698+
edgeServerActionModules: Record<string, JsModulePair>
699+
ssrModules: Record<string, JsModuleInfo>
700+
edgeSsrModules: Record<string, JsModuleInfo>
701+
rscModules: Record<string, JsModuleInfo>
702+
edgeRscModules: Record<string, JsModuleInfo>
703+
injectedClientEntries: Record<string, string>
704+
}
705+
688706
export interface JsHtmlPluginAssets {
689707
publicPath: string
690708
js: Array<string>
@@ -779,6 +797,16 @@ export interface JsModuleDescriptor {
779797
id?: string
780798
}
781799

800+
export interface JsModuleInfo {
801+
moduleId: string
802+
isAsync: boolean
803+
}
804+
805+
export interface JsModulePair {
806+
server?: JsModuleInfo
807+
client?: JsModuleInfo
808+
}
809+
782810
export interface JsNormalModuleFactoryCreateModuleArgs {
783811
dependencyType: string
784812
rawRequest: string
@@ -877,6 +905,13 @@ export interface JsRuntimeRequirementInTreeResult {
877905
runtimeRequirements: JsRuntimeGlobals
878906
}
879907

908+
export interface JsShouldInvalidateCbCtx {
909+
entryName: string
910+
absolutePagePath: string
911+
bundlePath: string
912+
clientBrowserLoader: string
913+
}
914+
880915
export interface JsSourceMap {
881916
version: number
882917
file?: string
@@ -1482,6 +1517,17 @@ export interface RawFlagAllModulesAsUsedPluginOptions {
14821517
explanation: string
14831518
}
14841519

1520+
export interface RawFlightClientEntryPluginOptions {
1521+
dev: boolean
1522+
appDir: string
1523+
isEdgeServer: boolean
1524+
encryptionKey: string
1525+
builtinAppLoader: boolean
1526+
shouldInvalidateCb: (ctx: JsShouldInvalidateCbCtx) => boolean
1527+
invalidateCb: () => void
1528+
stateCb: (state: JsFlightClientEntryPluginState) => void
1529+
}
1530+
14851531
export interface RawFuncUseCtx {
14861532
resource?: string
14871533
realResource?: string

crates/node_binding/src/compilation/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ impl JsCompilation {
741741
}
742742

743743
#[napi(
744-
ts_args_type = "args: [string, RawDependency, RawEntryOptions | undefined][], callback: (errMsg: Error | null, results: [string | null, JsDependency | null, JsModule | null][]) => void"
744+
ts_args_type = "args: [string, RawDependency, JsEntryOptions | undefined][], callback: (errMsg: Error | null, results: [string | null, JsDependency | null, JsModule | null][]) => void"
745745
)]
746746
pub fn add_include(
747747
&mut self,

crates/node_binding/src/raw_options/raw_builtins/raw_flight_client_entry_plugin.rs

Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,116 @@
11
use rspack_napi::threadsafe_function::ThreadsafeFunction;
2-
use rspack_plugin_next_flight_client_entry::{Options, ShouldInvalidateCbCtx, State};
2+
use rspack_plugin_next_flight_client_entry::{
3+
Action, ModuleInfo, ModulePair, Options, ShouldInvalidateCbCtx, State,
4+
};
5+
use rustc_hash::FxHashMap as HashMap;
36

47
#[napi(object, object_from_js = false)]
5-
pub struct JsFlightClientEntryPluginState {}
8+
pub struct JsModuleInfo {
9+
pub module_id: String,
10+
pub is_async: bool,
11+
}
12+
13+
impl From<ModuleInfo> for JsModuleInfo {
14+
fn from(value: ModuleInfo) -> Self {
15+
JsModuleInfo {
16+
module_id: value.module_id,
17+
is_async: value.is_async,
18+
}
19+
}
20+
}
21+
22+
#[napi(object, object_from_js = false)]
23+
pub struct JsAction {
24+
pub workers: HashMap<String, JsModuleInfo>,
25+
pub layer: HashMap<String, String>,
26+
}
27+
28+
impl From<Action> for JsAction {
29+
fn from(action: Action) -> Self {
30+
let workers = action
31+
.workers
32+
.into_iter()
33+
.map(|(key, worker)| (key, worker.into()))
34+
.collect::<HashMap<String, JsModuleInfo>>();
35+
JsAction {
36+
workers,
37+
layer: action.layer,
38+
}
39+
}
40+
}
41+
42+
fn into_js_actions(actions: HashMap<String, Action>) -> HashMap<String, JsAction> {
43+
actions
44+
.into_iter()
45+
.map(|(key, action)| (key, action.into()))
46+
.collect()
47+
}
48+
49+
#[napi(object, object_from_js = false)]
50+
pub struct JsModulePair {
51+
pub server: Option<JsModuleInfo>,
52+
pub client: Option<JsModuleInfo>,
53+
}
54+
55+
impl From<ModulePair> for JsModulePair {
56+
fn from(module_pair: ModulePair) -> Self {
57+
JsModulePair {
58+
server: module_pair.server.map(Into::into),
59+
client: module_pair.client.map(Into::into),
60+
}
61+
}
62+
}
63+
64+
fn into_js_module_pairs(
65+
module_pairs: HashMap<String, ModulePair>,
66+
) -> HashMap<String, JsModulePair> {
67+
module_pairs
68+
.into_iter()
69+
.map(|(key, module_pair)| (key, module_pair.into()))
70+
.collect()
71+
}
72+
73+
fn into_js_module_infos(
74+
module_infos: HashMap<String, ModuleInfo>,
75+
) -> HashMap<String, JsModuleInfo> {
76+
module_infos
77+
.into_iter()
78+
.map(|(key, module_info)| (key, module_info.into()))
79+
.collect()
80+
}
81+
82+
#[napi(object, object_from_js = false)]
83+
pub struct JsFlightClientEntryPluginState {
84+
pub server_actions: HashMap<String, JsAction>,
85+
pub edge_server_actions: HashMap<String, JsAction>,
86+
87+
pub server_action_modules: HashMap<String, JsModulePair>,
88+
pub edge_server_action_modules: HashMap<String, JsModulePair>,
89+
90+
pub ssr_modules: HashMap<String, JsModuleInfo>,
91+
pub edge_ssr_modules: HashMap<String, JsModuleInfo>,
92+
93+
pub rsc_modules: HashMap<String, JsModuleInfo>,
94+
pub edge_rsc_modules: HashMap<String, JsModuleInfo>,
95+
pub injected_client_entries: HashMap<String, String>,
96+
}
697

798
impl From<State> for JsFlightClientEntryPluginState {
8-
fn from(val: State) -> Self {
9-
JsFlightClientEntryPluginState {}
99+
fn from(state: State) -> Self {
100+
JsFlightClientEntryPluginState {
101+
server_actions: into_js_actions(state.server_actions),
102+
edge_server_actions: into_js_actions(state.edge_server_actions),
103+
104+
server_action_modules: into_js_module_pairs(state.server_action_modules),
105+
edge_server_action_modules: into_js_module_pairs(state.edge_server_action_modules),
106+
107+
ssr_modules: into_js_module_infos(state.ssr_modules),
108+
edge_ssr_modules: into_js_module_infos(state.edge_ssr_modules),
109+
110+
rsc_modules: into_js_module_infos(state.rsc_modules),
111+
edge_rsc_modules: into_js_module_infos(state.edge_rsc_modules),
112+
injected_client_entries: state.injected_client_entries,
113+
}
10114
}
11115
}
12116

@@ -36,13 +140,18 @@ pub struct RawFlightClientEntryPluginOptions {
36140
pub is_edge_server: bool,
37141
pub encryption_key: String,
38142
pub builtin_app_loader: bool,
143+
#[napi(ts_type = "(ctx: JsShouldInvalidateCbCtx) => boolean")]
39144
pub should_invalidate_cb: ThreadsafeFunction<JsShouldInvalidateCbCtx, bool>,
145+
#[napi(ts_type = "() => void")]
146+
pub invalidate_cb: ThreadsafeFunction<(), ()>,
147+
#[napi(ts_type = "(state: JsFlightClientEntryPluginState) => void")]
40148
pub state_cb: ThreadsafeFunction<JsFlightClientEntryPluginState, ()>,
41149
}
42150

43151
impl From<RawFlightClientEntryPluginOptions> for Options {
44152
fn from(val: RawFlightClientEntryPluginOptions) -> Self {
45153
let should_invalidate_cb = val.should_invalidate_cb;
154+
let invalidate_cb = val.invalidate_cb;
46155
let state_cb = val.state_cb;
47156

48157
Options {
@@ -58,6 +167,10 @@ impl From<RawFlightClientEntryPluginOptions> for Options {
58167
.blocking_call_with_sync(js_ctx)
59168
.unwrap()
60169
}),
170+
invalidate_cb: Box::new(move || {
171+
let invalidate_cb = invalidate_cb.clone();
172+
invalidate_cb.blocking_call_with_sync(()).unwrap()
173+
}),
61174
state_cb: Box::new(move |state| {
62175
let js_state = state.into();
63176
let state_cb = state_cb.clone();

crates/node_binding/src/raw_options/raw_external.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub struct JsExternalItemFnCtx {
7878
pub context: String,
7979
pub dependency_type: String,
8080
pub context_info: ContextInfo,
81+
#[napi(ts_type = "JsResolver")]
8182
pub resolver: JsResolverWrapper,
8283
}
8384

crates/node_binding/src/resolver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl JsResolver {
3030
}
3131
}
3232

33-
#[napi(ts_args_type = "JsResolver")]
33+
#[napi(ts_return_type = "JsResolver")]
3434
pub fn with_options(
3535
&self,
3636
raw: Option<RawResolveOptionsWithDependencyType>,

crates/rspack_plugin_next_flight_client_entry/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ tokio = { workspace = true, features = ["rt"] }
2929
tracing = { workspace = true }
3030
futures = { workspace = true }
3131
querystring = { version = "1.1.0" }
32+
sugar_path= { workspace = true }
33+
serde_urlencoded = "0.7.1"
3234
lazy-regex = "3.4.1"
3335
indexmap = { workspace = true }
3436
derive_more = { workspace = true }

0 commit comments

Comments
 (0)