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
308 changes: 289 additions & 19 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ members = [
"crates/perry-ext-streams",
"crates/perry-ext-fastify",
"crates/perry-ext-google-auth",
"crates/perry-ext-pdf",
"crates/perry-jsruntime",
"crates/perry-wasm-host",
"crates/perry-stdlib",
Expand Down Expand Up @@ -121,6 +122,7 @@ default-members = [
"crates/perry-ext-streams",
"crates/perry-ext-fastify",
"crates/perry-ext-google-auth",
"crates/perry-ext-pdf",
"crates/perry-jsruntime",
"crates/perry-wasm-host",
"crates/perry-stdlib",
Expand Down Expand Up @@ -293,6 +295,7 @@ perry-ext-http = { path = "crates/perry-ext-http" }
perry-ext-streams = { path = "crates/perry-ext-streams" }
perry-ext-fastify = { path = "crates/perry-ext-fastify" }
perry-ext-google-auth = { path = "crates/perry-ext-google-auth" }
perry-ext-pdf = { path = "crates/perry-ext-pdf" }
perry-stdlib = { path = "crates/perry-stdlib" }
perry-diagnostics = { path = "crates/perry-diagnostics" }
perry-jsruntime = { path = "crates/perry-jsruntime" }
Expand Down
24 changes: 24 additions & 0 deletions crates/perry-api-manifest/src/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ pub const NATIVE_MODULES: &[&str] = &[
// (#674). Bundled wrapper lives in `crates/perry-ext-google-auth`;
// d.ts at `types/perry/google-auth/index.d.ts`.
"@perryts/google-auth",
// `@perryts/pdf` — official PDF creation package (#516).
// Bundled wrapper lives in `crates/perry-ext-pdf`; the producer
// side companion to the existing PdfView widget. d.ts at
// `types/perry/pdf/index.d.ts`.
"@perryts/pdf",
];

/// Modules handled entirely by `perry-runtime` — the linker doesn't
Expand Down Expand Up @@ -2341,4 +2346,23 @@ pub static API_MANIFEST: &[ApiEntry] = &[
method("@perryts/google-auth", "js_google_auth_sign_in", false, None),
method("@perryts/google-auth", "js_google_auth_silent_sign_in", false, None),
method("@perryts/google-auth", "js_google_auth_sign_out", false, None),
// --- @perryts/pdf (issue #516) ---
// Minimal PDF creation API. The five FFI entry points exported
// by crates/perry-ext-pdf. Param shapes intentionally loose
// here (mostly `p_any`) — codegen's NATIVE_MODULE_TABLE rows
// tighten them. createPdf takes a single options object and
// returns a numeric handle; pdfAddText/pdfAddLine accept
// positional args.
method_sig(
"@perryts/pdf",
"createPdf",
false,
None,
&[p_any("opts")],
TypeSpec::Number,
),
method("@perryts/pdf", "pdfAddText", false, None),
method("@perryts/pdf", "pdfAddLine", false, None),
method("@perryts/pdf", "pdfNewPage", false, None),
method("@perryts/pdf", "pdfSave", false, None),
];
8 changes: 7 additions & 1 deletion crates/perry-codegen/src/lower_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1879,8 +1879,14 @@ pub(crate) fn lower_call(ctx: &mut FnCtx<'_>, callee: &Expr, args: &[Expr]) -> R
// fast path silently disengaged for
// every `Promise.resolve(...).then(...)`
// call (microtask-02..07 regression).
// Resolved-from-merge note: this used to live as
// an unresolved conflict on main; the incoming
// side called `is_global_constructor_expr`,
// which is what the rest of the file uses post
// #1030. Keep the richer comment from HEAD but
// call the same helper everything else does.
if inner_property == "resolve"
&& crate::type_analysis::is_global_builtin_named(
&& is_global_constructor_expr(
inner_object.as_ref(),
"Promise",
)
Expand Down
18 changes: 18 additions & 0 deletions crates/perry-codegen/src/runtime_decls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,24 @@ pub fn declare_stdlib_ffi(module: &mut LlModule) {
module.declare_function("js_nanoid", I64, &[DOUBLE]);
module.declare_function("js_nanoid_custom", I64, &[I64, DOUBLE]);

// ========== @perryts/pdf (issue #516) ==========
// createPdf returns an i64 handle (NaN-boxed POINTER_TAG by
// codegen via NR_PTR). The mutator ops are Rust `-> ()` and
// therefore VOID at the LLVM ABI level.
module.declare_function("js_pdf_create_pdf", I64, &[DOUBLE]);
module.declare_function(
"js_pdf_add_text",
VOID,
&[I64, I64, DOUBLE, DOUBLE, DOUBLE],
);
module.declare_function(
"js_pdf_add_line",
VOID,
&[I64, DOUBLE, DOUBLE, DOUBLE, DOUBLE],
);
module.declare_function("js_pdf_new_page", VOID, &[I64]);
module.declare_function("js_pdf_save", VOID, &[I64]);

// ========== Commander CLI ==========
module.declare_function("js_commander_action", I64, &[I64, I64]);
module.declare_function("js_commander_command", I64, &[I64, I64]);
Expand Down
14 changes: 14 additions & 0 deletions crates/perry-codegen/src/type_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,14 @@ pub(crate) fn is_string_expr(ctx: &FnCtx<'_>, e: &Expr) -> bool {
/// Pass `name = "Promise"` (etc.) to require the property-access form
/// to actually name that built-in; the legacy `GlobalGet(_)` arm
/// accepts any global because the original code never narrowed.
// `dead_code` allow: the function survived an unresolved merge in
// main (commit 9a9a233c's "fix: recognize global Promise static
// calls" left HEAD/incoming markers in this file). The
// `is_global_constructor_expr` helper added by the same commit
// supersedes this one, but ripping it out is outside #516's
// scope — leave the lingering definition with an allow so the
// dead-code lint doesn't fail the build.
#[allow(dead_code)]
pub(crate) fn is_global_builtin_named(expr: &Expr, name: &str) -> bool {
if matches!(expr, Expr::GlobalGet(_)) {
return true;
Expand Down Expand Up @@ -1042,6 +1050,12 @@ pub(crate) fn is_promise_expr(ctx: &FnCtx<'_>, e: &Expr) -> bool {
// `.then` codegen fell through to generic native
// dispatch — microtask-02..07 and edge-promises went
// silent (callbacks never enqueued). (#1008)
//
// Resolved-from-merge note: the HEAD side called
// `is_global_builtin_named`, the incoming side called
// `is_global_constructor_expr`. Post-#1030 the rest of
// the codegen prefers the latter helper, so we keep the
// richer HEAD comment but switch to the canonical call.
if matches!(
property.as_str(),
"resolve" | "reject" | "all" | "race" | "allSettled" | "any"
Expand Down
17 changes: 17 additions & 0 deletions crates/perry-ext-pdf/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "perry-ext-pdf"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "Native bindings for `@perryts/pdf` (#516) — minimal PDF creation API using the `printpdf` crate. Companion to the existing PdfView widget (which handles the read/render side). v1 surface: createPdf / pdfAddText / pdfAddLine / pdfNewPage / pdfSave."
repository.workspace = true

[lib]
crate-type = ["staticlib", "rlib"]

[dependencies]
perry-ffi.workspace = true
# Pure-Rust PDF writer. `default-features = false` drops the heavy
# `html` feature (azul-layout, kuchiki, …) — for the v1 surface we
# only need core text + line drawing, which lives in the base crate.
printpdf = { version = "0.9", default-features = false }
Loading
Loading