const std = @import("std"); // vendored libzstd, decode-only subset, pinned by url+hash in build.zig.zon // (same v1.5.7 pin as zat and stream). no system library, cross-compiles // with -Dtarget. zig std's zstd decompressor measured ~20x slower than // libzstd on jss archive blocks and cannot verify frame content checksums. fn linkVendoredZstd(mod: *std.Build.Module, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) void { const zstd_dep = b.dependency("zstd", .{}); const clib_mod = b.createModule(.{ .target = target, .optimize = optimize, .link_libc = true, }); clib_mod.addCSourceFiles(.{ .root = zstd_dep.path("lib"), .files = &.{ "common/debug.c", "common/entropy_common.c", "common/error_private.c", "common/fse_decompress.c", "common/xxhash.c", "common/zstd_common.c", "decompress/huf_decompress.c", "decompress/zstd_ddict.c", "decompress/zstd_decompress_block.c", "decompress/zstd_decompress.c", }, .flags = &.{ "-DZSTD_DISABLE_ASM", "-DZSTD_MULTITHREAD=0", "-DXXH_NAMESPACE=ZSTD_", }, }); const clib = b.addLibrary(.{ .name = "jetstream-vendored-zstd", .root_module = clib_mod }); mod.linkLibrary(clib); } pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const zat = b.dependency("zat", .{ .target = target, .optimize = optimize, }); const mod = b.addModule("jetstream", .{ .root_source_file = b.path("src/root.zig"), .target = target, .optimize = optimize, .link_libc = true, .imports = &.{ .{ .name = "zat", .module = zat.module("zat") }, .{ .name = "websocket", .module = b.dependency("websocket", .{ .target = target, .optimize = optimize }).module("websocket") }, }, }); linkVendoredZstd(mod, b, target, optimize); const tests = b.addTest(.{ .root_module = mod }); const run_tests = b.addRunArtifact(tests); const test_step = b.step("test", "run unit tests"); test_step.dependOn(&run_tests.step); const check_client = b.addExecutable(.{ .name = "zig-client", .root_module = b.createModule(.{ .root_source_file = b.path("checks/client.zig"), .target = target, .optimize = optimize, .imports = &.{.{ .name = "jetstream", .module = mod }}, }), }); const install_check_client = b.addInstallArtifact(check_client, .{}); const check_step = b.step("check-client", "build the local SDK adapter for differential checks"); check_step.dependOn(&install_check_client.step); const example = b.addExecutable(.{ .name = "example-streamplace-chat", .root_module = b.createModule(.{ .root_source_file = b.path("examples/streamplace_chat.zig"), .target = target, .optimize = optimize, .link_libc = true, .imports = &.{ .{ .name = "zat", .module = zat.module("zat") }, .{ .name = "jetstream", .module = mod }, }, }), }); b.installArtifact(example); const run_example = b.addRunArtifact(example); if (b.args) |args| run_example.addArgs(args); const example_step = b.step("example-streamplace-chat", "replay a Streamplace broadcast's chat from the archive"); example_step.dependOn(&run_example.step); const smoke = b.addExecutable(.{ .name = "example-failover-smoke", .root_module = b.createModule(.{ .root_source_file = b.path("examples/failover_smoke.zig"), .target = target, .optimize = optimize, .link_libc = true, .imports = &.{ .{ .name = "jetstream", .module = mod }, }, }), }); b.installArtifact(smoke); const run_smoke = b.addRunArtifact(smoke); if (b.args) |args| run_smoke.addArgs(args); const smoke_step = b.step("example-failover-smoke", "live smoke: dead primary rotates to a real fallback"); smoke_step.dependOn(&run_smoke.step); const cutover = b.addExecutable(.{ .name = "example-cutover-smoke", .root_module = b.createModule(.{ .root_source_file = b.path("examples/cutover_smoke.zig"), .target = target, .optimize = optimize, .link_libc = true, .imports = &.{ .{ .name = "jetstream", .module = mod }, }, }), }); b.installArtifact(cutover); const segment_export = b.addExecutable(.{ .name = "segment-export", .root_module = b.createModule(.{ .root_source_file = b.path("examples/segment_export.zig"), .target = target, .optimize = optimize, .link_libc = true, .imports = &.{ .{ .name = "jetstream", .module = mod }, }, }), }); b.installArtifact(segment_export); const run_segment_export = b.addRunArtifact(segment_export); if (b.args) |args| run_segment_export.addArgs(args); const segment_export_step = b.step("segment-export", "one local jss segment -> TSV rows on stdout"); segment_export_step.dependOn(&run_segment_export.step); const run_cutover = b.addRunArtifact(cutover); if (b.args) |args| run_cutover.addArgs(args); const cutover_step = b.step("example-cutover-smoke", "live smoke: archive sweep -> gapless cutover -> live tail"); cutover_step.dependOn(&run_cutover.step); const slice = b.addExecutable(.{ .name = "example-slice-sync", .root_module = b.createModule(.{ .root_source_file = b.path("examples/slice_sync.zig"), .target = target, .optimize = optimize, .link_libc = true, .imports = &.{ .{ .name = "zat", .module = zat.module("zat") }, .{ .name = "jetstream", .module = mod }, }, }), }); b.installArtifact(slice); const run_slice = b.addRunArtifact(slice); if (b.args) |args| run_slice.addArgs(args); const slice_step = b.step("example-slice-sync", "replay one account's whole history from the archive slice"); slice_step.dependOn(&run_slice.step); }