Files
bun.sh/src/ast/ServerComponentBoundary.zig
taylor.fish 07cd45deae Refactor Zig imports and file structure (part 1) (#21270)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-07-22 17:51:38 -07:00

122 lines
4.4 KiB
Zig

//! Represents a boundary between client and server code. Every boundary
//! gets bundled twice, once for the desired target, and once to generate
//! a module of "references". Specifically, the generated file takes the
//! canonical Ast as input to derive a wrapper. See `Framework.ServerComponents`
//! for more details about this generated file.
//!
//! This is sometimes abbreviated as SCB
use_directive: UseDirective,
/// The index of the original file.
source_index: Index.Int,
/// Index to the file imported on the opposite platform, which is
/// generated by the bundler. For client components, this is the
/// server's code. For server actions, this is the client's code.
reference_source_index: Index.Int,
/// When `bake.Framework.ServerComponents.separate_ssr_graph` is enabled this
/// points to the separated module. When the SSR graph is not separate, this is
/// equal to `reference_source_index`
//
// TODO: Is this used for server actions.
ssr_source_index: Index.Int,
/// The requirements for this data structure is to have reasonable lookup
/// speed, but also being able to pull a `[]const Index.Int` of all
/// boundaries for iteration.
pub const List = struct {
list: std.MultiArrayList(ServerComponentBoundary) = .{},
/// Used to facilitate fast lookups into `items` by `.source_index`
map: Map = .{},
const Map = std.ArrayHashMapUnmanaged(void, void, struct {}, true);
/// Can only be called on the bundler thread.
pub fn put(
m: *List,
allocator: std.mem.Allocator,
source_index: Index.Int,
use_directive: UseDirective,
reference_source_index: Index.Int,
ssr_source_index: Index.Int,
) !void {
try m.list.append(allocator, .{
.source_index = source_index,
.use_directive = use_directive,
.reference_source_index = reference_source_index,
.ssr_source_index = ssr_source_index,
});
const gop = try m.map.getOrPutAdapted(
allocator,
source_index,
Adapter{ .list = m.list.slice() },
);
bun.assert(!gop.found_existing);
}
/// Can only be called on the bundler thread.
pub fn getIndex(l: *const List, real_source_index: Index.Int) ?usize {
return l.map.getIndexAdapted(
real_source_index,
Adapter{ .list = l.list.slice() },
);
}
/// Use this to improve speed of accessing fields at the cost of
/// storing more pointers. Invalidated when input is mutated.
pub fn slice(l: List) Slice {
return .{ .list = l.list.slice(), .map = l.map };
}
pub const Slice = struct {
list: std.MultiArrayList(ServerComponentBoundary).Slice,
map: Map,
pub fn getIndex(l: *const Slice, real_source_index: Index.Int) ?usize {
return l.map.getIndexAdapted(
real_source_index,
Adapter{ .list = l.list },
) orelse return null;
}
pub fn getReferenceSourceIndex(l: *const Slice, real_source_index: Index.Int) ?u32 {
const i = l.map.getIndexAdapted(
real_source_index,
Adapter{ .list = l.list },
) orelse return null;
bun.unsafeAssert(l.list.capacity > 0); // optimize MultiArrayList.Slice.items
return l.list.items(.reference_source_index)[i];
}
pub fn bitSet(scbs: Slice, alloc: std.mem.Allocator, input_file_count: usize) !bun.bit_set.DynamicBitSetUnmanaged {
var scb_bitset = try bun.bit_set.DynamicBitSetUnmanaged.initEmpty(alloc, input_file_count);
for (scbs.list.items(.source_index)) |source_index| {
scb_bitset.set(source_index);
}
return scb_bitset;
}
};
pub const Adapter = struct {
list: std.MultiArrayList(ServerComponentBoundary).Slice,
pub fn hash(_: Adapter, key: Index.Int) u32 {
return std.hash.uint32(key);
}
pub fn eql(adapt: Adapter, a: Index.Int, _: void, b_index: usize) bool {
bun.unsafeAssert(adapt.list.capacity > 0); // optimize MultiArrayList.Slice.items
return a == adapt.list.items(.source_index)[b_index];
}
};
};
const bun = @import("bun");
const std = @import("std");
const js_ast = bun.ast;
const Index = js_ast.Index;
const ServerComponentBoundary = js_ast.ServerComponentBoundary;
const UseDirective = js_ast.UseDirective;