Skip to content

Commit 264b3c5

Browse files
Enhance incremental render functionality and improve test coverage
- Updated the `setResponse` call in the `run` function to correctly use `result.response`. - Expanded the incremental render tests to cover new scenarios, including basic updates, multi-bundle interactions, and error handling for malformed update chunks. - Introduced new helper functions in test fixtures to streamline the creation of async values and streams, enhancing the robustness of the tests. - Improved the secondary bundle's functionality to support async value resolution and streaming, ensuring consistent behavior across bundles.
1 parent 95e80eb commit 264b3c5

File tree

4 files changed

+421
-2
lines changed

4 files changed

+421
-2
lines changed

react_on_rails_pro/packages/node-renderer/src/worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export default function run(config: Partial<Config>) {
236236
providedNewBundles,
237237
assetsToCopy,
238238
});
239-
await setResponse(result, res);
239+
await setResponse(result.response, res);
240240
} catch (err) {
241241
const exceptionMessage = formatExceptionMessage(
242242
renderingRequest,
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,57 @@
1+
const { PassThrough } = require('stream');
2+
13
global.ReactOnRails = {
24
dummy: { html: 'Dummy Object' },
5+
6+
// Get or create async value promise
7+
getAsyncValue: function() {
8+
debugger;
9+
if (!sharedExecutionContext.has('asyncPromise')) {
10+
const promiseData = {};
11+
const promise = new Promise((resolve, reject) => {
12+
promiseData.resolve = resolve;
13+
promiseData.reject = reject;
14+
});
15+
promiseData.promise = promise;
16+
sharedExecutionContext.set('asyncPromise', promiseData);
17+
}
18+
return sharedExecutionContext.get('asyncPromise').promise;
19+
},
20+
21+
// Resolve the async value promise
22+
setAsyncValue: function(value) {
23+
debugger;
24+
if (!sharedExecutionContext.has('asyncPromise')) {
25+
ReactOnRails.getAsyncValue();
26+
}
27+
const promiseData = sharedExecutionContext.get('asyncPromise');
28+
promiseData.resolve(value);
29+
},
30+
31+
// Get or create stream
32+
getStreamValues: function() {
33+
if (!sharedExecutionContext.has('stream')) {
34+
const stream = new PassThrough();
35+
sharedExecutionContext.set('stream', { stream });
36+
}
37+
return sharedExecutionContext.get('stream').stream;
38+
},
39+
40+
// Add value to stream
41+
addStreamValue: function(value) {
42+
if (!sharedExecutionContext.has('stream')) {
43+
// Create the stream first if it doesn't exist
44+
ReactOnRails.getStreamValues();
45+
}
46+
const { stream } = sharedExecutionContext.get('stream');
47+
stream.write(value);
48+
return value;
49+
},
50+
51+
endStream: function() {
52+
if (sharedExecutionContext.has('stream')) {
53+
const { stream } = sharedExecutionContext.get('stream');
54+
stream.end();
55+
}
56+
},
357
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,53 @@
11
global.ReactOnRails = {
22
dummy: { html: 'Dummy Object from secondary bundle' },
3+
4+
5+
// Get or create async value promise
6+
getAsyncValue: function() {
7+
if (!sharedExecutionContext.has('secondaryAsyncPromise')) {
8+
const promiseData = {};
9+
const promise = new Promise((resolve, reject) => {
10+
promiseData.resolve = resolve;
11+
promiseData.reject = reject;
12+
});
13+
promiseData.promise = promise;
14+
sharedExecutionContext.set('secondaryAsyncPromise', promiseData);
15+
}
16+
return sharedExecutionContext.get('secondaryAsyncPromise').promise;
17+
},
18+
19+
// Resolve the async value promise
20+
setAsyncValue: function(value) {
21+
if (!sharedExecutionContext.has('secondaryAsyncPromise')) {
22+
ReactOnRails.getAsyncValue();
23+
}
24+
const promiseData = sharedExecutionContext.get('secondaryAsyncPromise');
25+
promiseData.resolve(value);
26+
},
27+
28+
// Get or create stream
29+
getStreamValues: function() {
30+
if (!sharedExecutionContext.has('secondaryStream')) {
31+
const stream = new PassThrough();
32+
sharedExecutionContext.set('secondaryStream', { stream });
33+
}
34+
return sharedExecutionContext.get('secondaryStream').stream;
35+
},
36+
37+
// Add value to stream
38+
addStreamValue: function(value) {
39+
if (!sharedExecutionContext.has('secondaryStream')) {
40+
// Create the stream first if it doesn't exist
41+
ReactOnRails.getStreamValues();
42+
}
43+
const { stream } = sharedExecutionContext.get('secondaryStream');
44+
stream.write(value);
45+
},
46+
47+
endStream: function() {
48+
if (sharedExecutionContext.has('secondaryStream')) {
49+
const { stream } = sharedExecutionContext.get('secondaryStream');
50+
stream.end();
51+
}
52+
},
353
};

0 commit comments

Comments
 (0)