Skip to content
Closed
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
4 changes: 4 additions & 0 deletions web/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ test_suite(
tests = [
"//web/api:generate_tests",
"//web/api:test",
"//web/package_test:consumer_typecheck_typecheck_test",
"//web/package_test:pack_contents_test",
"//web/submitqueue:test",
"//web/submitqueue:typecheck_typecheck_test",
],
)

Expand Down
52 changes: 52 additions & 0 deletions web/package_test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
load("@aspect_rules_js//npm:defs.bzl", "npm_link_package")
load("@aspect_rules_ts//ts:defs.bzl", "ts_config", "ts_project")
load("@rules_python//python:defs.bzl", "py_test")

package(default_visibility = ["//visibility:public"])

npm_link_package(
name = "node_modules/@submitqueue/api",
src = "//web/api:pkg",
)

npm_link_package(
name = "node_modules/@submitqueue/web-submitqueue",
src = "//web/submitqueue:pkg",
)

ts_config(
name = "tsconfig",
src = "tsconfig.json",
)

ts_project(
name = "consumer_typecheck",
srcs = ["consumer.ts"],
declaration = False,
no_emit = True,
tsconfig = ":tsconfig",
deps = [
":node_modules/@submitqueue/api",
":node_modules/@submitqueue/web-submitqueue",
"//web:node_modules/@bufbuild/protobuf",
"//web:node_modules/@connectrpc/connect",
"//web:node_modules/@types/node",
"//web:node_modules/react",
"//web:node_modules/react-dom",
],
)

py_test(
name = "pack_contents_test",
srcs = ["pack_contents_test.py"],
main = "pack_contents_test.py",
legacy_create_init = 0,
args = [
"$(rootpath //web/api:pkg.pack)",
"$(rootpath //web/submitqueue:pkg.pack)",
],
data = [
"//web/api:pkg.pack",
"//web/submitqueue:pkg.pack",
],
)
7 changes: 7 additions & 0 deletions web/package_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Package consumer checks

This package validates the artifacts that downstream consumers receive rather than importing workspace source directly.

`//web/package_test:pack_contents_test` checks the Bazel-created npm tarballs for the generated gateway API and the library's root, `./server`, and `./testing` declaration files. `//web/package_test:consumer_typecheck_typecheck_test` links the packaged outputs into an isolated TypeScript consumer and verifies all public entry points.

These checks complement the Next reference-host build: the package tests enforce publication shape, while the host proves framework integration.
8 changes: 8 additions & 0 deletions web/package_test/consumer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { AutoRefresh, RequestStatus } from "@submitqueue/web-submitqueue";
import { loadRequestList } from "@submitqueue/web-submitqueue/server";
import { createFakeGatewayReader } from "@submitqueue/web-submitqueue/testing";

void AutoRefresh;
void RequestStatus;
void loadRequestList;
void createFakeGatewayReader;
59 changes: 59 additions & 0 deletions web/package_test/pack_contents_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import sys
import json
import tarfile
from pathlib import Path


_EXPECTED_API_FILES = {
"package/dist/api/submitqueue/gateway/proto/gateway_pb.d.ts",
"package/dist/api/submitqueue/gateway/proto/gateway_pb.js",
"package/README.md",
}

_EXPECTED_WEB_FILES = {
"package/dist/index.d.ts",
"package/dist/server.d.ts",
"package/dist/testing.d.ts",
"package/README.md",
}


def _missing_files(archive_path: Path, expected: set[str]) -> list[str]:
with tarfile.open(archive_path) as archive:
files = {member.name for member in archive.getmembers()}
return sorted(expected - files)


def main() -> int:
if len(sys.argv) != 3:
raise RuntimeError("expected API and web package archives")

missing = {
str(archive): absent
for archive, expected in (
(Path(sys.argv[1]), _EXPECTED_API_FILES),
(Path(sys.argv[2]), _EXPECTED_WEB_FILES),
)
if (absent := _missing_files(archive, expected))
}
if missing:
for archive, files in missing.items():
print(f"{archive} is missing: {', '.join(files)}", file=sys.stderr)
return 1
with tarfile.open(Path(sys.argv[2])) as archive:
package_file = archive.extractfile("package/package.json")
package = json.load(package_file)
if "next" in package.get("peerDependencies", {}) or "next" in package.get("dependencies", {}):
print("The presentation library must not require Next.js.", file=sys.stderr)
return 1
for member in archive.getmembers():
if member.name.endswith((".js", ".d.ts")):
source = archive.extractfile(member).read().decode("utf-8")
if '"next/' in source or "'next/" in source:
print(f"{member.name} imports host-owned Next.js.", file=sys.stderr)
return 1
return 0


if __name__ == "__main__":
raise SystemExit(main())
11 changes: 11 additions & 0 deletions web/package_test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"noEmit": true,
"skipLibCheck": true,
"strict": true,
"target": "ES2023"
},
"include": ["consumer.ts"]
}
101 changes: 100 additions & 1 deletion web/submitqueue/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
load("@aspect_rules_js//npm:defs.bzl", "npm_package")
load("@aspect_rules_ts//ts:defs.bzl", "ts_config", "ts_project")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//web/submitqueue:vitest/package_json.bzl", vitest = "bin")

package(default_visibility = ["//visibility:public"])

exports_files(["package.json"])
npm_link_all_packages(name = "node_modules")

ts_config(
name = "tsconfig",
src = "tsconfig.json",
)

ts_config(
name = "tsconfig_build",
src = "tsconfig.build.json",
deps = [":tsconfig"],
)

ts_project(
name = "lib",
srcs = glob([
"src/**/*.ts",
"src/**/*.tsx",
], exclude = [
"src/**/*.test.ts",
"src/**/*.test.tsx",
"src/test-setup.ts",
]),
declaration = True,
declaration_map = True,
no_emit = False,
out_dir = "dist",
root_dir = "src",
transpiler = "tsc",
tsconfig = ":tsconfig_build",
deps = [
":node_modules/@bufbuild/protobuf",
":node_modules/@connectrpc/connect",
":node_modules/@submitqueue/api",
":node_modules/@types/react",
":node_modules/react",
":node_modules/server-only",
],
)

ts_project(
name = "typecheck",
srcs = glob([
"src/**/*.ts",
"src/**/*.tsx",
]) + ["vitest.config.ts"],
declaration = True,
no_emit = True,
tsconfig = ":tsconfig",
deps = [
":node_modules/@bufbuild/protobuf",
":node_modules/@connectrpc/connect",
":node_modules/@submitqueue/api",
":node_modules/@testing-library/jest-dom",
":node_modules/@testing-library/react",
":node_modules/@types/react",
":node_modules/@types/react-dom",
":node_modules/jsdom",
":node_modules/react",
":node_modules/react-dom",
":node_modules/server-only",
":node_modules/vitest",
],
)

npm_package(
name = "pkg",
package = "@submitqueue/web-submitqueue",
packable = True,
srcs = [
":lib",
":lib_types",
"README.md",
"package.json",
],
)

vitest.vitest_test(
name = "test",
args = [
"run",
"--config",
"vitest.config.ts",
],
chdir = package_name(),
data = [
":node_modules",
":node_modules/vitest",
"//web:node_modules/vitest",
"vitest.config.ts",
] + glob([
"src/**/*.ts",
"src/**/*.tsx",
]) + ["test/server-only.ts"],
)
9 changes: 9 additions & 0 deletions web/submitqueue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SubmitQueue web library

`@submitqueue/web-submitqueue` owns serializable models, gateway loaders, safe timestamps, status/error presentation, route helpers, refresh controls, and deterministic gateway fakes.

The root entry point is client-safe; `./server` contains server-only gateway mapping, and `./testing` contains test fixtures. React, Connect, and Protobuf-ES are peer contracts. The package has no Next.js dependency.

Hosts own routes, credentials, queue selection, transport creation, deadlines, dynamic rendering, and deployment. `AutoRefresh` takes a host callback whose promise settles after refreshing finishes.

Bazel owns compilation, unit/type tests, package tarballs, and isolated package-consumer checks. Page components are added in the following stack changes.
7 changes: 6 additions & 1 deletion web/submitqueue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
"import": "./dist/testing.js"
}
},
"scripts": {},
"scripts": {
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
"lint": "tsc --noEmit",
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@submitqueue/api": "0.1.0",
"server-only": "^0.0.1"
Expand Down
Loading