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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.idea
.DS_Store

/rust-deps/target
/rust-deps/Cargo.toml

Expand Down
16 changes: 16 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
load("@capnp-cpp//src/capnp:cc_capnp_library.bzl", "cc_capnp_library")
load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")
load("@aspect_rules_js//npm:defs.bzl", "npm_link_package", "npm_package")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//:capnpc-ts/package_json.bzl", capnpc_ts_bin = "bin")

cc_capnp_library(
name = "icudata-embed",
Expand All @@ -13,3 +16,16 @@ cc_capnp_library(
refresh_compile_commands(
name = "refresh_compile_commands",
)

npm_link_all_packages(name = "node_modules")

npm_link_package(
name = "node_modules/@workerd/jsg",
src = "//src/workerd/jsg:jsg_js",
package = "@workerd/jsg",
)

capnpc_ts_bin.capnpc_ts_binary(
name = "capnpc_ts",
visibility = ["//visibility:public"],
)
52 changes: 52 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,58 @@ load("//rust-deps/cxxbridge_crates:crates.bzl", cxxbridge_repositories = "crate_

cxxbridge_repositories()

# ========================================================================================
# Node.js bootstrap
#
# workerd uses Node.js scripts for generating TypeScript types.

http_archive(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will definitely make embedding workerd hard.

Maybe extract this to a separate function setup_js_dependencies in bzl file so that it can be called by downstream deps if needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, I don't think you can call load() in functions (bazelbuild/bazel#1550)? So we wouldn't be able to call rules_js_dependencies, rules_ts_dependencies, npm_translate_lock or npm_repositories in our function? We have the same problem with Rust dependencies atm: the internal repository currently duplicates all the Rust WORKSPACE rules. 😕

name = "aspect_rules_js",
sha256 = "b9fde0f20de6324ad443500ae738bda00facbd73900a12b417ce794856e01407",
strip_prefix = "rules_js-1.5.0",
url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.5.0.tar.gz",
)

http_archive(
name = "aspect_rules_ts",
sha256 = "743f0e988e4e3f1e25e52c79f9dc3da1ddd77507ae88787ae95b4e70c537872b",
strip_prefix = "rules_ts-1.0.0-rc4",
url = "https://github.com/aspect-build/rules_ts/archive/refs/tags/v1.0.0-rc4.tar.gz",
)

load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies")

rules_js_dependencies()

load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")

nodejs_register_toolchains(
name = "nodejs",
node_version = "18.10.0",
)

load("@aspect_rules_ts//ts:repositories.bzl", TS_LATEST_VERSION = "LATEST_VERSION", "rules_ts_dependencies")

rules_ts_dependencies(ts_version = TS_LATEST_VERSION)

load("@aspect_rules_js//npm:npm_import.bzl", "npm_translate_lock")

npm_translate_lock(
name = "npm",
pnpm_lock = "//:pnpm-lock.yaml",
# Patches required for `capnp-ts` to type-check
patches = {
"capnp-ts@0.7.0": ["//:patches/capnp-ts@0.7.0.patch"],
},
patch_args = {
"capnp-ts@0.7.0": ["-p1"],
},
)

load("@npm//:repositories.bzl", "npm_repositories")

npm_repositories()

# ========================================================================================
# V8 and its dependencies
#
Expand Down
124 changes: 124 additions & 0 deletions build/js_capnp_library.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"""
Bazel rule to compile .capnp files into JavaScript using capnp-ts.
Based on https://github.com/capnproto/capnproto/blob/3b2e368cecc4b1419b40c5970d74a7a342224fac/c++/src/capnp/cc_capnp_library.bzl.
"""

load("@aspect_rules_js//js:defs.bzl", "js_library")

capnp_provider = provider("Capnproto Provider", fields = {
"includes": "includes for this target (transitive)",
"inputs": "src + data for the target",
"src_prefix": "src_prefix of the target",
})

def _workspace_path(label, path):
if label.workspace_root == "":
return path
return label.workspace_root + "/" + path

def _capnp_gen_impl(ctx):
label = ctx.label
src_prefix = _workspace_path(label, ctx.attr.src_prefix)
includes = []

inputs = ctx.files.srcs + ctx.files.data
for dep_target in ctx.attr.deps:
includes += dep_target[capnp_provider].includes
inputs += dep_target[capnp_provider].inputs

if src_prefix != "":
includes.append(src_prefix)

system_include = ctx.files._capnp_system[0].dirname.removesuffix("/capnp")

out_dir = ctx.var["GENDIR"]
if src_prefix != "":
out_dir = out_dir + "/" + src_prefix

js_out = "-o%s:%s" % (ctx.executable._capnpc_ts.path, out_dir)
args = ctx.actions.args()
args.add_all(["compile", "--verbose", js_out])
args.add_all(["-I" + inc for inc in includes])
args.add_all(["-I", system_include])
if src_prefix != "":
args.add_all(["--src-prefix", src_prefix])

args.add_all([s for s in ctx.files.srcs])

ctx.actions.run(
inputs = inputs + ctx.files._capnpc_ts + ctx.files._capnpc_capnp + ctx.files._capnp_system,
tools = [ctx.executable._capnpc_ts], # Include required js_binary runfiles
outputs = ctx.outputs.outs,
executable = ctx.executable._capnpc,
arguments = [args],
mnemonic = "GenCapnp",
)

return [
capnp_provider(
includes = includes,
inputs = inputs,
src_prefix = src_prefix,
),
]

_capnp_gen = rule(
attrs = {
"srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(providers = [capnp_provider]),
"data": attr.label_list(allow_files = True),
"outs": attr.output_list(),
"src_prefix": attr.string(),
"_capnpc": attr.label(executable = True, allow_single_file = True, cfg = "exec", default = "@capnp-cpp//src/capnp:capnp_tool"),
"_capnpc_ts": attr.label(executable = True, allow_single_file = True, cfg = "exec", default = "//:capnpc_ts"),
"_capnpc_capnp": attr.label(executable = True, allow_single_file = True, cfg = "exec", default = "@capnp-cpp//src/capnp:capnpc-capnp"),
"_capnp_system": attr.label(default = "@capnp-cpp//src/capnp:capnp_system_library"),
},
output_to_genfiles = True,
implementation = _capnp_gen_impl,
)

def js_capnp_library(
name,
srcs = [],
data = [],
deps = [],
src_prefix = "",
visibility = None,
target_compatible_with = None,
**kwargs):
"""Bazel rule to create a JavaScript capnproto library from capnp source files

Args:
name: library name
srcs: list of files to compile
data: additional files to provide to the compiler - data files and includes that need not to
be compiled
deps: other js_capnp_library rules to depend on
src_prefix: src_prefix for capnp compiler to the source root
visibility: rule visibility
target_compatible_with: target compatibility
**kwargs: rest of the arguments to js_library rule
"""

js_files = [s + ".js" for s in srcs]
d_ts_files = [s + ".d.ts" for s in srcs]

_capnp_gen(
name = name + "_gen",
srcs = srcs,
deps = [s + "_gen" for s in deps],
data = data,
outs = js_files + d_ts_files,
src_prefix = src_prefix,
visibility = visibility,
target_compatible_with = target_compatible_with,
)
js_library(
name = name,
srcs = js_files + d_ts_files,
deps = deps + ["//:node_modules/capnp-ts"],
visibility = visibility,
target_compatible_with = target_compatible_with,
**kwargs
)
13 changes: 13 additions & 0 deletions build/typescript.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
def module_name(ts_name):
if ts_name.endswith(".ts"):
return ts_name.removesuffix(".ts")
if ts_name.endswith(".mts"):
return ts_name.removesuffix(".mts")
fail("Expected TypeScript source file, got " + ts_name)

def js_name(ts_name):
if ts_name.endswith(".ts"):
return ts_name.removesuffix(".ts") + ".js"
if ts_name.endswith(".mts"):
return ts_name.removesuffix(".mts") + ".mjs"
fail("Expected TypeScript source file, got " + ts_name)
19 changes: 19 additions & 0 deletions build/wd_ts_project.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")

def wd_ts_project(name, srcs, deps, testonly = False):
"""Bazel rule for a workerd TypeScript project, setting common options"""

ts_project(
name = name,
srcs = srcs,
deps = deps,
tsconfig = "//types:tsconfig.json",
allow_js = True,
composite = True,
source_map = True,
testonly = testonly,
# Disable workers to avoid issue with multiple targets
# (https://github.com/aspect-build/rules_ts/issues/128)
# TODO: try re-enable these on next aspect_rules_ts update
supports_workers = False,
)
23 changes: 23 additions & 0 deletions build/wd_ts_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("@aspect_rules_js//js:defs.bzl", "js_test")
load("//:build/wd_ts_project.bzl", "wd_ts_project")
load("//:build/typescript.bzl", "js_name", "module_name")

def wd_ts_test(src, deps = [], **kwargs):
"""Bazel rule to compile and run a TypeScript test"""

name = module_name(src)

wd_ts_project(
name = name + "@compile",
srcs = [src],
deps = deps,
testonly = True,
)

js_test(
name = name,
entry_point = js_name(src),
data = deps + [name + "@compile"],
tags = ["no-arm64", "js-test"],
**kwargs
)
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@cloudflare/workerd-root",
"private": true,
"scripts": {
"lint": "eslint types/src"
},
"dependencies": {
"capnp-ts": "^0.7.0",
"prettier": "^2.7.1",
"typescript": "~4.7.4"
},
"devDependencies": {
"@types/debug": "^4.1.7",
"@types/node": "^18.7.18",
"@types/prettier": "^2.7.1",
"@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0",
"capnpc-ts": "^0.7.0",
"esbuild": "^0.15.7",
"eslint": "^8.22.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1"
}
}
11 changes: 11 additions & 0 deletions patches/capnp-ts@0.7.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/src/serialization/pointers/struct.ts
+++ b/src/serialization/pointers/struct.ts
@@ -107,8 +107,6 @@ export class Struct extends Pointer {
static readonly setText = setText;
static readonly testWhich = testWhich;

- readonly _capnp!: _Struct;
-
/**
* Create a new pointer to a struct.
*
Loading