Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .config/lint/monorepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ export const monorepoReadonlyParameterAllows: Array<
from: 'package',
name: [
'ReactElement',
'ReactNode',
'ReactPortal',
'ReactPromise',
'PendingReactPromise',
'FulfilledReactPromise',
'RejectedReactPromise',
'ComponentType',
'SyntheticEvent',
'MouseEvent',
'CSSProperties',
Expand All @@ -56,6 +62,7 @@ export const monorepoReadonlyParameterAllows: Array<
{ from: 'package', name: ['PageProps', 'LayoutProps', 'ErrorProps'], package: 'rari' },
{ from: 'package', name: ['EvaluateOptions'], package: '@mdx-js/mdx' },
'Page',
'FlightContent',
'APIRequestContext',
'ViteDevServer',
'Plugin',
Expand Down
2 changes: 1 addition & 1 deletion crates/rari/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ mod utils;
pub use ::async_trait;
pub use rendering::{
base::{RscJsLoader, RscRenderer},
r#static::RscHtmlRenderer,
html_shell::RscHtmlRenderer,
};
pub use rsc::{ComponentRegistry, extract_dependencies};
19 changes: 8 additions & 11 deletions crates/rari/src/rendering/base/constants.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
use std::time::Duration;

pub const MEMORY_PRESSURE_THRESHOLD: f64 = 0.8;
pub const MEMORY_PRESSURE_RENDER_THRESHOLD_NUM: usize = 8;
pub const MEMORY_PRESSURE_RENDER_THRESHOLD_DEN: usize = 10;
pub const CACHE_CLEANUP_INTERVAL: Duration = Duration::from_millis(10);

pub const MAX_RETRIES: u64 = 3;
pub const RETRY_BASE_DELAY_MS: u64 = 150;
pub const COMPONENT_AVAILABILITY_CHECK_DELAY_MS: u64 = 20;

pub const DEFAULT_MAX_CONCURRENT_RENDERS: usize = 50;
pub const DEFAULT_MAX_RENDER_TIME_MS: u64 = 8000;
pub const DEFAULT_MAX_SCRIPT_EXECUTION_TIME_MS: u64 = 3000;
pub const DEFAULT_MAX_MEMORY_PER_COMPONENT_MB: usize = 50;
pub const DEFAULT_MAX_CACHE_SIZE: usize = 1000;

pub const ACTION_FLIGHT_ENCODE_SCRIPT: &str = concat!(
include_str!("js/stream_utils.ts"),
include_str!("js/action_flight_shared.ts"),
include_str!("js/action_flight_encode.ts"),
);
pub const ACTION_HANDLER_SCRIPT: &str = concat!(
"// rari-action-handler-v3\n",
include_str!("js/action_fn_resolver.ts"),
include_str!("js/action_args_validation.core.ts"),
include_str!("js/action_args_validation_v8.ts"),
include_str!("js/stream_utils.ts"),
include_str!("js/action_flight_shared.ts"),
include_str!("js/action_handler.ts"),
);
Expand All @@ -38,7 +32,8 @@ pub const GET_RSC_BINARY_B64: &str = r"(function() {
return btoa(str);
})()";

pub const FIZZ_RENDER_SCRIPT: &str = include_str!("../layout/js/fizz_render.ts");
pub const FIZZ_RENDER_SCRIPT: &str =
concat!(include_str!("js/stream_utils.ts"), include_str!("../layout/js/fizz_render.ts"),);
pub const ROUTE_COMPOSER_SCRIPT: &str = concat!(
include_str!("../layout/js/layout_reuse.ts"),
"\n",
Expand All @@ -49,13 +44,15 @@ pub const STREAMING_FIZZ_SCRIPT: &str = concat!(
"\n",
include_str!("../layout/js/streaming_fizz.ts"),
);
pub const RSC_RENDERER_SCRIPT: &str = include_str!("js/rsc_renderer.ts");
pub const RSC_RENDERER_SCRIPT: &str =
concat!(include_str!("js/stream_utils.ts"), include_str!("js/rsc_renderer.ts"),);

pub const STREAMING_PIPELINE_READY_CHECK: &str = "typeof globalThis['~rari']?.renderStreamingDocument === 'function' \
&& typeof globalThis['~rari']?.renderStaticDocument === 'function' \
&& typeof globalThis['~rari']?.composeRoute === 'function' \
&& typeof globalThis['~rari']?.createPageElement === 'function' \
&& typeof globalThis['~rari']?.wrapLayoutReuse === 'function'";
&& typeof globalThis['~rari']?.wrapLayoutReuse === 'function' \
&& typeof globalThis['~rari']?.stampLayoutPath === 'function'";

pub const LOAD_FULL_REACT_VENDORS_SCRIPT: &str = r"
(function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,26 @@
isDangerousActionProperty,
}
})()

function getActionArgsValidationApi(): ActionArgsValidationApi {
const api = g.__RARI_ACTION_ARGS_VALIDATION__

if (!api) throw new TypeError('Action args validation API not initialized')

return api
}

function actionValidationConfig() {
const api = getActionArgsValidationApi()
return g['~rari']?.isDevelopment
? api.developmentValidationConfig()
: api.productionValidationConfig()
}

function validateActionArgs(args: readonly unknown[]): unknown[] {
return getActionArgsValidationApi().validateActionArgsWithConfig(args, actionValidationConfig())
}

function validateFormData(formData: FormData): void {
getActionArgsValidationApi().validateFormDataWithConfig(formData, actionValidationConfig())
}
24 changes: 0 additions & 24 deletions crates/rari/src/rendering/base/js/action_args_validation_v8.ts

This file was deleted.

20 changes: 1 addition & 19 deletions crates/rari/src/rendering/base/js/action_flight_shared.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
/// <reference path="../../types.d.ts" />

async function readStreamToLastRscBinary(stream: ReadableStream<Uint8Array>): Promise<void> {
const reader = stream.getReader()
const chunks: Uint8Array[] = []
let totalLength = 0

for (;;) {
const { done, value } = await reader.read()
if (done) break
chunks.push(value)
totalLength += value.byteLength
}

const fullBuffer = new Uint8Array(totalLength)
let offset = 0
for (const chunk of chunks) {
fullBuffer.set(chunk, offset)
offset += chunk.byteLength
}

const rari = (g['~rari'] ??= {})
rari.lastRscBinary = fullBuffer
rari.lastRscBinary = await readStreamToUint8Array(stream)
}

async function encodeActionFlightResponse(
Expand Down
20 changes: 1 addition & 19 deletions crates/rari/src/rendering/base/js/rsc_renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,7 @@ async function renderToRsc(element: unknown): Promise<string> {
},
})

const reader = stream.getReader()
const chunks: Uint8Array[] = []
let totalLength = 0

for (;;) {
const { done, value } = await reader.read()

if (done) break

chunks.push(value)
totalLength += value.byteLength
}

const fullBuffer = new Uint8Array(totalLength)
let offset = 0
for (const chunk of chunks) {
fullBuffer.set(chunk, offset)
offset += chunk.byteLength
}
const fullBuffer = await readStreamToUint8Array(stream)

const rari = (g['~rari'] ??= {})
rari.lastRscBinary = fullBuffer
Expand Down
43 changes: 43 additions & 0 deletions crates/rari/src/rendering/base/js/stream_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/// <reference path="../../types.d.ts" />

async function readStreamToUint8Array(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
const reader = stream.getReader()
const chunks: Uint8Array[] = []
let totalLength = 0

for (;;) {
const { done, value } = await reader.read()
if (done) break
chunks.push(value)
totalLength += value.byteLength
}

const fullBuffer = new Uint8Array(totalLength)
let offset = 0
for (const chunk of chunks) {
fullBuffer.set(chunk, offset)
offset += chunk.byteLength
}
return fullBuffer
}

async function readStreamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
const reader = stream.getReader()
const decoder = new TextDecoder()
let text = ''

for (;;) {
const { done, value } = await reader.read()
if (done) break
text += decoder.decode(value, { stream: true })
}
text += decoder.decode()
return text
}

{
const streamRari = (g['~rari'] ??= {})
streamRari.readStreamToUint8Array = readStreamToUint8Array
streamRari.readStreamToText = readStreamToText
streamRari.readStream = readStreamToText
}
2 changes: 1 addition & 1 deletion crates/rari/src/rendering/base/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use loader::{RscJsLoader, RscModuleOperation, StubType};
pub use renderer::RscRenderer;
pub use renderer_lock::{run_with_renderer, run_with_renderer_result};
pub use sanitizer::sanitize_html_output;
pub use types::{ResourceLimits, ResourceMetrics, ResourceTracker};
pub use types::{ResourceLimits, ResourceTracker};

#[cfg(test)]
#[expect(clippy::expect_used, clippy::unwrap_used)]
Expand Down
Loading
Loading