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: 2 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
- [@taffyjs/wasm package design](taffyjs-wasm-package.md) — public contract, artifact layout, initialization model, ownership boundary, and verification requirements for the explicit Wasm package.
- [@taffyjs/yoga decisions](taffyjs-yoga-decisions.md) — compatibility decisions for replacing yoga-layout through the TaffyJS Yoga layer.
- [@taffyjs/yoga implementation reference](taffyjs-yoga-reference.md) — the audited Yoga 3.2.1 public API inventory, implemented compatibility boundary, evidence, and ongoing maintenance constraints.
- [Tooling decisions](tooling-decisions.md) — rulings for npm scope and test workspace package naming, the repository-wide TypeScript default, JavaScript package builds, repository command orchestration, tool ownership, and demand-driven API code generation.
- [@taffyjs/yoga-wasm package design](taffyjs-yoga-wasm-package.md) — the shared-source Wasm transport, package boundary, loading behavior, and verification contract for the Yoga facade.
- [Tooling decisions](tooling-decisions.md) — rulings for third-party license filenames, npm scope and test workspace package naming, the repository-wide TypeScript default, JavaScript package builds, repository command orchestration, tool ownership, and demand-driven API code generation.
8 changes: 7 additions & 1 deletion .agents/docs/architecture.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Architecture

This repository is a small Rust and JavaScript monorepo with one shared napi-rs binding and three public packages.
This repository is a small Rust and JavaScript monorepo with one shared napi-rs binding and four public packages.

## Ownership

Expand All @@ -9,20 +9,26 @@ This repository is a small Rust and JavaScript monorepo with one shared napi-rs
- `packages/taffyjs-node` owns the public ESM wrapper and declarations, the private napi-rs loader and declarations, and npm metadata. The wrapper owns JavaScript-only NodeId validity data and context; Taffy owns topology, Style, Layout, cache, and computation state.
- `packages/taffyjs-wasm` compiles the same authored source from `packages/taffyjs-node/src` against generated private Node and browser adapters that share one inline payload. It owns package metadata, generated artifacts, and build-time binding redirection; its package-specific typed generator lives under `tools/taffy-wasm`. It has no authored public wrapper source or separate initialization API.
- `packages/taffyjs-yoga` owns the Node-only ESM Yoga 3.2.1 compatibility facade, Yoga declarations and visible state, input translation, and Yoga-shaped output projection. It depends only on the public `@taffyjs/node` package boundary and does not modify Taffy or the native binding.
- `packages/taffyjs-yoga-wasm` builds the exact facade source owned by `packages/taffyjs-yoga/src` against the public `@taffyjs/wasm` backend. It owns only its package metadata and build-time backend redirection; it has no copied facade source or second compatibility policy.
- `tests/taffyjs-node` is a private consumer package that tests `@taffyjs/node` through its package boundary.
- `tests/taffyjs-wasm` is a private consumer package that checks the Wasm package through Node and browser package resolution, reuses the existing public type tests, mechanically inspects the published file set, and installs the packed result in fresh npm and pnpm consumers.
- `tests/taffyjs-yoga` is the corresponding private consumer package for compatibility, differential, and end-to-end tests through the `@taffyjs/yoga` package boundary; it does not contain a redundant nested `tests/` directory.
- `tests/taffyjs-yoga-wasm` reruns the same Yoga behavior and declaration suites against the Wasm transport, inspects the package boundary, and installs the packed packages in fresh npm and pnpm consumers for Node and Chromium checks.

The `@taffyjs/node` public entry bundles the private napi-rs root loader, which selects the matching optional platform package. Its generated loader and declaration remain repository build inputs rather than published package files. The `@taffyjs/wasm` default entry reaches a no-TLA ESM bridge that imports the shared payload and immediately invokes a synchronous CommonJS factory mechanically derived from napi-rs's eager Node loader; its browser entry reaches a TLA adapter and the unmodified deferred loader. Neither direct runtime package exposes an intermediate binding package, JavaScript shadow tree, separate core crate, public binding, or public initialization API.

`@taffyjs/yoga` is a Node-only TypeScript compatibility layer over `@taffyjs/node`; browser and WASM backends never live in that package. It performs bounded input normalization and output processing, but it does not modify or fork Taffy core, add a Yoga-specific native algorithm, or reimplement Flex layout in JavaScript; behavior that cannot cross that boundary is documented as Different or Unsupported as recorded in [@taffyjs/yoga decisions](taffyjs-yoga-decisions.md).

`@taffyjs/yoga-wasm` is a separate transport over `@taffyjs/wasm`, selected at build time by replacing only the exact bare `@taffyjs/node` dependency. The eager root entry and lazy `/load` entry keep Yoga's public shapes; `/load` dynamically imports the facade so a browser compiles no WebAssembly until `loadYoga()` is called. Compatibility semantics stay owned by the shared Yoga source and documentation.

## Testing

JavaScript integration tests are the primary proof of observable behavior. Package-local JavaScript and Rust unit tests are limited to critical behavior that is clearer in isolation. Maintained test names follow product behavior rather than temporary milestone or acceptance labels.

The Wasm package runs the complete Node public API behavior suite without copied test files: a Wasm-only Vite+ configuration replaces the exact `@taffyjs/node` import with `@taffyjs/wasm`. Subprocess fixtures select the same test entry through an inherited test-only file URL. The Wasm package additionally has a real Chromium runtime test through Vite+ and Playwright. A separate Vite consumer build proves that the `browser` export is selected, the payload occurs once in JavaScript, and no external `.wasm` asset is emitted; the browser runtime check exercises synchronous measurement and reuse after a controlled error without cross-origin isolation or `SharedArrayBuffer`.

The Yoga Wasm package likewise reuses the complete maintained Yoga suite and public declaration test. Its packed-consumer fixture proves unchanged `yoga-layout` root and `/load` imports in Node and bundled Chromium, including the lazy compilation boundary, rather than maintaining a second copy of compatibility tests.

A test earns its place only when it is the clearest durable check for a distinct observable behavior or safety property. Before adding one, identify the exact failure it would catch and explain why tests beside the code that owns the behavior would not already catch it. Distinct coverage is not enough: the protection must justify the code to maintain, time to run, ways it can fail for unrelated reasons, and platform-specific behavior it introduces. Prefer the smallest direct check. When consolidating duplicate files, move any genuinely unique assertion into the owning test before deleting the duplicate.

Review test changes in this order: whether the protection is worth its cost, whether the check sits beside the right code, then whether its implementation is correct. A passing test or a working harness proves only that it runs. Do not use runtime tests that read README, source, or test files as a substitute for testing product behavior or enforcing architecture. If an explicit repository rule needs automatic enforcement, such as which module may import a private loader, use a focused lint or CI check against the source files. Generated-artifact freshness follows [API code generation](api-codegen.md#verification), not generator unit tests.
Expand Down
3 changes: 2 additions & 1 deletion .agents/docs/intent.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ TaffyJS is intended to bring Taffy, a high-performance layout engine written in
- `@taffyjs/node` is the first entry point and provides native Node-API bindings built with napi-rs.
- `@taffyjs/wasm` is the explicit WebAssembly entry point for Node.js and bundled browsers. It reuses the `@taffyjs/node` public API over a threadless napi-rs WASIP binding rather than acting as an automatic fallback; its vouched contract is in [@taffyjs/wasm package design](taffyjs-wasm-package.md).
- `@taffyjs/yoga` is the Node-only Yoga 3.2.1 compatibility package built on top of `@taffyjs/node`; browser and WASM backends remain outside that package.
- `@taffyjs/yoga-wasm` is the separate Node.js and bundled-browser transport for that same compatibility facade. It builds the same source over `@taffyjs/wasm` so the two packages cannot drift into separate Yoga implementations.
- The package family should support real consumers such as terminal UI frameworks without forcing those consumers to own their own Taffy bindings.

## Bun and Deno runtime support
Expand All @@ -31,5 +32,5 @@ The binding role and API priority are recorded in [@taffyjs/node decisions](taff

## Open questions

- Runtime and platform support beyond the current native targets, the approved `@taffyjs/wasm` Node.js and bundled-browser scope, Bun 1.2+ within major 1, and Deno 2.2+ within major 2 requires a concrete consumer need.
- Runtime and platform support beyond the current native targets, the approved `@taffyjs/wasm` and `@taffyjs/yoga-wasm` Node.js and bundled-browser scope, Bun 1.2+ within major 1, and Deno 2.2+ within major 2 requires a concrete consumer need.
- The release timing of `@taffyjs/yoga` remains open. Yoga compatibility is not part of the `@taffyjs/node` contract.
Loading