Skip to content

feat(bundler): add Vite and Rsbuild integrations - #300

Merged
lzxb merged 79 commits into
masterfrom
feat-vite-rsbuild-bundler-support
Jun 15, 2026
Merged

feat(bundler): add Vite and Rsbuild integrations#300
lzxb merged 79 commits into
masterfrom
feat-vite-rsbuild-bundler-support

Conversation

@lzxb

@lzxb lzxb commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds first-class Vite and Rsbuild support to Esmx, alongside the existing Rspack integration — 6 new additive packages, zero changes to any existing package.

Base packages (implement the App contract: build / start / dev)

  • @esmx/vite — Vite/Rollup integration. Native ESM module-federation output (shared deps externalized as bare specifiers, resolved by the import map), esmx-format manifest.json, and real module-level HMR in dev (Vite dev server in middleware mode with base aligned to /<name>/, ssrLoadModule rendering, /@vite/client injected through the module graph).
  • @esmx/rsbuild — Rsbuild integration over the rspack kernel, reusing the proven webpack-hot-middleware HMR mechanism (same as @esmx/rspack).

Framework presets (thin adapters injecting the framework plugin via the config hook)

  • @esmx/vite-react, @esmx/vite-vue@vitejs/plugin-react / @vitejs/plugin-vue
  • @esmx/rsbuild-react, @esmx/rsbuild-vue@rsbuild/plugin-react / @rsbuild/plugin-vue

All packages emit native ESM federation chunks consumed unchanged by @esmx/core.

Verification

Six example apps, each verified end-to-end with esmx build + esmx start:

Example Covers
ssr-vite-html / ssr-rsbuild-html plain HTML/TS
ssr-vite-react / ssr-rsbuild-react React + pkg:react/pkg:react-dom federation
ssr-vite-vue / ssr-rsbuild-vue Vue 3 SFC + pkg:vue federation
  • @esmx/vite dev HMR validated in a real browser (module replaced in place, no full reload).
  • lint:type, lint:js (biome), build (unbuild) pass for all 6 packages.

Notes

  • pnpm-lock.yaml updated for the new packages' deps (vite, @rsbuild/core, framework plugins).
  • No source of any existing package was modified.

Add six additive packages giving Esmx first-class support for Vite and
Rsbuild alongside the existing Rspack integration, without touching any
existing package code:

Base packages (App contract: build / start / dev):
- @esmx/vite: Vite/Rollup integration with native ESM module-federation
  output, esmx-format manifest, and real module-level HMR in dev (Vite
  dev server in middleware mode, base-aligned, ssrLoadModule rendering).
- @esmx/rsbuild: Rsbuild integration over the rspack kernel, reusing the
  proven webpack-hot-middleware HMR mechanism.

Framework presets (thin adapters injecting the framework plugin):
- @esmx/vite-react, @esmx/vite-vue (@vitejs/plugin-react / -vue)
- @esmx/rsbuild-react, @esmx/rsbuild-vue (@rsbuild/plugin-react / -vue)

Each package emits native ESM federation chunks (shared deps externalized
as bare specifiers, resolved by the import map) consumed unchanged by
@esmx/core. Verified end-to-end with six example apps
(ssr-{vite,rsbuild}-{html,react,vue}) via esmx build + esmx start,
covering plain HTML, React and Vue plus pkg:react/react-dom/vue
real-package federation.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 8, 2026

Copy link
Copy Markdown

Deploying esmx with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6271b76
Status: ✅  Deploy successful!
Preview URL: https://11c2965c.esmx.pages.dev
Branch Preview URL: https://feat-vite-rsbuild-bundler-su.esmx.pages.dev

View logs

Dev added 28 commits June 8, 2026 20:58
Add the missing async write() method (counterpart of writeSync, already used
in the postBuild example) and the command getter (current command, distinct
from the COMMAND enum) to the @esmx/core API reference, in both en and zh.
Verified all other documented core APIs against packages/core/src.
Document the @esmx/vite package API (BuildTarget, ViteAppConfigContext,
ViteAppOptions, ViteHtmlAppOptions, createViteApp, createViteHtmlApp, vite
re-export) generated from packages/vite/src, and register it in the App
section nav. Verified with a full docs build.
Document the @esmx/rsbuild package API (BuildTarget, RsbuildAppConfigContext,
RsbuildAppOptions, RsbuildHtmlAppOptions, createRsbuildApp,
createRsbuildHtmlApp, rspack re-export) generated from packages/rsbuild/src,
and register it in the App section nav. Verified with a full docs build.
…n + zh)

Document the React and Vue 3 presets (createViteReactApp/createViteVueApp,
ViteReactAppOptions/ViteVueAppOptions, @esmx/vite re-exports) from their
src/index.ts, and register them in the App section nav after vite. Verified
with a full docs build.
…rences (en + zh)

Document the React and Vue 3 presets (createRsbuildReactApp/createRsbuildVueApp,
RsbuildReactAppOptions/RsbuildVueAppOptions, @esmx/rsbuild re-exports) from
their src/index.ts, and register them in the App nav after rsbuild. All six new
bundler packages are now documented. Verified with a full docs build.
Add the two public readonly Route properties (confirm: RouteConfirmHook|null,
layer: RouteLayerOptions|null) that were missing from the Route reference, in
both en and zh. Audited the rest of the @esmx/router docs (Router/Route members,
RouterMode/RouteType enums, error classes, option types) against
packages/router/src — all accurate (deprecated href/pathname correctly omitted).
Add the useLink(props: RouterLinkProps): RouterLinkResolved headless hook to
the router-react hooks reference (en + zh); it powers RouterLink and mirrors
@esmx/router-vue's useLink, which was already documented. Audited router-react
and router-vue exports against src — all other public symbols are covered.
…d-tools section

Update the 'Decoupling of Build Tools' essentials guide (en + zh) to point at
the shipped @esmx/vite and @esmx/rsbuild integrations and their framework
presets, with a switch-to-Vite example. Audited the rest of the build/router
guides — builder names and the chain hook match the real exports.
Add README.md + README.zh-CN.md for @esmx/vite, @esmx/rsbuild,
@esmx/{vite,rsbuild}-{react,vue}, modeled on the existing package READMEs
(badges, features, install, quick start, docs link). Usage examples use the
real createViteApp/createRsbuildReactApp/... APIs from each package.
Add @esmx/{vite,rsbuild} and their React/Vue presets to the Core Packages
table, and broaden the high-performance-build feature to mention Rspack,
Rsbuild and Vite (en + zh).
The React/Vue example READMEs were copied verbatim from the csr templates
(wrong title, build tool and port). Rewrite all six (ssr-{vite,rsbuild}-{html,
react,vue}) with the correct project name, build tool, framework and dev port;
add READMEs for the two HTML examples that had none.
The core/rspack/rspack-react/rspack-vue READMEs used non-existent APIs
(createEsmx, createRspack, createRspackReact, createRspackVue). Replace with
the real entry.node.ts devApp pattern using createRspackHtmlApp /
createRspackReactApp / createRspackVue3App, driven by the esmx CLI; also fix a
stray Chinese link in the English core README (en + zh).
A Vite-built HTML micro-app remote that shares ssr-micro-shared's router via
the import map, to be composed by the hub alongside the Rspack remotes.
Mirrors ssr-micro-html; only the bundler (@esmx/vite, createViteHtmlApp) and
route path (/vite-html/) differ.
Vite-built React micro-app remote (federates react/react-dom, shares the
router via the import map). Mirrors ssr-micro-react; only the bundler
(@esmx/vite-react, createViteReactApp) and route path (/vite-react/) differ.
Vite-built Vue 3 micro-app remote (federates vue, server-only
@vue/server-renderer, SFC compilation, shares the router via the import map).
Mirrors ssr-micro-vue3; only the bundler (@esmx/vite-vue, createViteVueApp)
and route path (/vite-vue/) differ.
Rsbuild-built HTML micro-app remote that shares ssr-micro-shared's router via
the import map. Mirrors ssr-micro-html; only the bundler (@esmx/rsbuild,
createRsbuildHtmlApp) and route path (/rsbuild-html/) differ.
Rsbuild-built React micro-app remote (federates react/react-dom, shares the
router via the import map). Mirrors ssr-micro-react; only the bundler
(@esmx/rsbuild-react, createRsbuildReactApp) and route path (/rsbuild-react/)
differ.
Rsbuild-built Vue 3 micro-app remote (federates vue, server-only
@vue/server-renderer, shares the router via the import map). Mirrors
ssr-micro-vue3; only the bundler (@esmx/rsbuild-vue, createRsbuildVueApp) and
route path (/rsbuild-vue/) differ. Completes the six new bundler remotes.
… micro-app remotes into hub

@esmx/vite:
- Federate pkg exports via a virtual module with explicit static named exports
  (discovered by loading the package in Node), so a CommonJS package like react
  exposes `useState` etc. — fixes `import { useState } from 'react'` in SSR.
- Disable Vite SSR auto-externalization (ssr.noExternal) so subpaths such as
  react-dom/server / react/jsx-runtime are inlined and import the single
  federated react/react-dom instead of a second node_modules copy (which broke
  React's hooks dispatcher).

@esmx/rsbuild:
- optimization.usedExports=false so federation chunks keep exports consumed
  only by other bundles (e.g. vue's ssrUtils), and cache=!isProd for
  deterministic production output.

Wire vite-html/react/vue and rsbuild-html/react into ssr-micro-hub: one host
composing remotes built by Rspack + Vite + Rsbuild, sharing one router via the
import map. ssr-micro-rsbuild-vue is linked but not yet routed (its Vue SSR
needs a dedicated fix tracked separately).
Root-cause fixes so an Rsbuild-built Vue 3 remote SSR-renders when federated:

- @esmx/rsbuild: the externals function now only externalizes a federation
  specifier when it has an issuer (imported by another module). A pkg export's
  own entry module has no issuer and must be built, not externalized into an
  empty re-export — mirrors @esmx/rspack's module-link. This lets pkg entries
  stay BARE specifiers so resolve.alias applies to them.
- @esmx/rsbuild-vue: alias `vue$` to the runtime-only build and compile SFCs
  with isServerBuild on server/node targets. @rsbuild/plugin-vue otherwise
  resolves vue to the full build (dragging the template compiler into the
  federated chunk) and never sets isServerBuild, which broke the
  @vue/server-renderer ↔ vue `ssrUtils` linkage.
- Fix a missing `...rsbuildVueRoutes` spread in the hub so the route is
  actually registered (the import alone was tree-shaken).

All six new remotes (vite/rsbuild × html/react/vue) now SSR-render real
framework content in ssr-micro-hub, composed alongside the Rspack remotes and
sharing one router via the import map.
These were internal task-orchestration notes accidentally committed via the
lint-staged 'git add .' step; they are not part of the deliverable.
The manifest plugins keyed chunks by output name and never injected
import.meta.chunkName, so RenderContext.commit() could not match the
client manifest's chunk keys against the SSR-executed chunk set —
federated code-split chunk CSS/resources were silently dropped.

- key chunks by their source path relative to root (mirrors
  @esmx/rspack generateIdentifier, matching core's hardcoded
  `name@src/entry.client.ts` seed)
- inject import.meta.chunkName into the server build so commit()
  collects the matching client chunk CSS/resources
- resolvePkgNames: warn instead of silently returning [] on require
  failure (no silent failure)
- rsbuild dev: log watch errors instead of swallowing them
- ssr-rsbuild-html: fix copied-over title 'Vite' -> 'Rsbuild'
- add unit tests for externals predicate + chunkSourceKey (regression
  guard for the chunk-key fix)
…ue SSR

The standalone ssr-vite-* / ssr-rsbuild-* react & vue examples were
client-side rendered (createRoot / createApp + empty #app) despite the
ssr- prefix. Make their behavior match their name:

- react: renderToString(<App/>) on the server into #app, hydrateRoot on
  the client (was createRoot)
- vue: createSSRApp + @vue/server-renderer renderToString on the server,
  createSSRApp mount hydration on the client (was createApp)
- update titles/meta/copy from 'CSR / client-side' to 'SSR / server-side'

Verified: all 4 emit server-rendered markup in #app (curl), hydrate in a
real browser with no console warnings/hydration mismatch, and the counter
increments after hydration (single framework instance via the import map).
- fix one missed 'client-side rendering' string in ssr-vite-vue
- rename tsconfig self-reference path aliases from *-csr-demo to the
  actual package name (ssr-vite-react/ssr-rsbuild-react/ssr-vite-vue/
  ssr-rsbuild-vue) so they match package.json and the esmx module name
…-apps

buildSeoHead returned unhead core's UseHeadInput (= ResolvableHead, which
permits getter/function values). @unhead/vue's useHead expects its own
Vue-reactive UseHeadInput, and core ResolvableHead is not assignable to it
(@unhead/react's useHead uses the core type, so react was unaffected) —
breaking `pnpm lint:type` on all three vue micro examples.

- type buildSeoHead's return as unhead's SerializableHead (the plain,
  static head it actually produces), which IS assignable to both
  @unhead/react and @unhead/vue useHead inputs
- align the unhead core dep to ^3.1.3 across the micro examples so it
  matches the @unhead/vue / @unhead/react 3.1.3 adapters (was ^3.1.0,
  resolving to a stale 3.1.0)

Full `pnpm lint:type` now passes repo-wide; hub still SSRs every route
with SEO meta intact.
The manifest plugin hashed chunk.code in a default-order generateBundle,
but Vite's build-import-analysis rewrites dynamic-import preload markers
(__VITE_PRELOAD__) into the final dependency array in its own
generateBundle. When ours ran first, the SRI hash was computed over the
pre-rewrite code, so code-split chunks (which carry the preload array)
failed the browser's integrity check and were blocked — e.g.
ssr-micro-vite-vue's chunks/routes.*.mjs on the deployed preview. Entry
chunks were unaffected (no preload-marker rewrite).

Run generateBundle with order:'post' so integrity is computed over the
finalized code that is actually written and served.

Verified: all .mjs/.css across all 6 vite-based examples now have
matching SRI (was mismatching on code-split chunks). Added a regression
test asserting the hook stays order:'post'.
A module-level scope was only expanded onto the module's export files, so
code-split chunk files (Vite/Rollup facade+impl splits, e.g.
chunks/routes.*.mjs) — which still 'import "vue"' — had no import-map
scope. The browser then failed with 'Failed to resolve module specifier
"vue"' when such a chunk loaded. rspack's all-in-one output emits no
extra chunks, so only Vite remotes were affected.

createClientImportMap now adds, per manifest, the module's bare-specifier
scope to each of its code-split chunk files — done AFTER compression so it
never skews the global-promotion heuristic (which must keep a multi-version
dep like 'vue' scoped, not hoisted). Adds ImportMapManifest.chunks and a
regression test.

Verified in a real browser: /vite-vue/, /rsbuild-vue/ and the pre-existing
/vue3/ hub routes load with no console errors and hydrate (counter works).
Add cases for addCodeSplitChunkScopes: skip when a global import already
resolves the specifier (single-module promotion), no-op for all-in-one
manifests without chunks (rspack), and applying every module external to
its chunk. Purely additive — existing import-map cases unchanged (176 pass).
lzxb added 10 commits June 13, 2026 00:15
…for cold-start CI runners

Same commit was passing on push and failing on pull_request because shared
GHA runners have ~1.5s LCP variance. 2500ms is Google's 'good' p75 for real
users; for cold-start CI smoke runs, 4000ms ('poor' boundary) is the
defensible hard gate. Sub-2500ms targets stay as warnings.
- `parseSubpath()` extracts the exports key from a bare specifier:
  react-dom → ".", react-dom/client → "./client", @scope/pkg/deep → "./deep".
- `pickEntry()` now matches that subpath against `exports`, including
  single-* patterns (./*, ./deep/*.js) with Node's longest-prefix precedence.
- `module`/`main` only describe the root entry, so they're skipped for
  subpath specifiers — caller falls back to `require.resolve` instead.

Adds 17 edge-case tests covering: conditional NODE_ENV branches (react),
pure CJS re-exports, ESM-with-default, ESM `export *` proxy over CJS,
module.exports as function, scoped packages, require-only exports,
import>require preference, reserved keys filtering, cyclic re-exports,
identifier validity, unresolvable specifiers, and real deep subpaths
(react-dom/client, vue/server-renderer).
…t contract

RFC 0001 draft (status: Accepted — pending implementation). Replaces the
current entry.node.ts `modules: { links, imports, exports, scopes }` configuration
+ `pkg:` / `root:` prefix DSL with three things:

1. **Declaration** in the `package.json` `esmx` field — a module declares only
   facts about itself (local knowledge).
2. **Manifest** as the deployment contract — adds `protocol`, `version`, and
   `uses` transcriptions to what build produces.
3. **Deterministic link-time resolution** — auto-wiring from declarations,
   hard build-time errors with fixes that always live in existing declarations,
   plus an emitted audit artifact.

Breaking by intent — correctness over compatibility. Three independent expert
reviews (module resolution / TypeScript, bundler internals, micro-frontend
architecture) cited in §11.
@lzxb
lzxb force-pushed the feat-vite-rsbuild-bundler-support branch from 267d86b to f89fc09 Compare June 12, 2026 17:38
lzxb added 17 commits June 13, 2026 01:42
…es to an unlexable bundle

After 60d02d4 taught pickEntry() to follow subpath specifiers into the
exports map, packages like vue map 'vue/dist/vue.runtime.esm-browser.prod.js'
to a single-line minified file that es-module-lexer rejects with a parse
error. inspectPkg then degraded to default-only re-export and downstream
'import { version } from vue' crashed shared-modules's postBuild.

The fix retries with the package's bare specifier (root entry) when the
first lex attempt throws. The root entry is the lean ESM build whose
named-export surface is a superset of (or identical to) the deep subpath's,
so the federation wrapper still emits a complete static names list. The
bundler ultimately resolves to the deep subpath via the host's import map,
so the wrapper only needs to satisfy the lexer.

Adds a synthetic 'minified-subpath-pkg' fixture with an intentionally
unterminated-template dist/* target that exercises the fallback path; the
test asserts no warning is logged when the retry succeeds.
…te CLI

Implements RFC 0001 Phase 1: package.json esmx field (entry/exports/
provides/uses), JSON Schema, recursive supply merge with the full
diagnostic taxonomy (E_*/W_*), and lowering to the internal
ModuleConfig — legacy path is byte-identical when no esmx field exists.

- esmx validate [--json]: build-free dry run emitting the RFC §7
  diagnostics envelope extended with supply/mounts; exit non-zero only
  on error-severity diagnostics
- esmx migrate [--dry-run] [--json]: legacy modules config → esmx
  declaration with exact public-name preservation and in-process
  parseModuleConfig parity verification (restores package.json on
  mismatch)

252 tests passing (76 new)
Diagnostic taxonomy completed (E_CYCLE, E_PROTOCOL, W_* structured
codes), validate --json envelope specified, Gate 5 quantified with a
machine judge, server import map named as a suppression site,
chunk-set provenance, peerDependencies in role examples (verified to
produce zero diagnostics against the implemented resolver)
Full pipeline walkthrough (manifest -> import map -> SSR), data
structures, three-pass client map, bundler adapter contract,
pkg-wrapper internals, declaration subsystem and implemented CLI
surface — every claim verified against source with line references
Four-field declaration with three role examples (empirically verified:
zero diagnostics via esmx validate against the real resolver), merge
rule, diagnostic taxonomy, validate/migrate workflow; legacy syntax
compressed into an explicitly deprecated section; negative-space list
extended (no singleton/resolutions/sealed/lockfile)
Replace the multi-candidate election + loser-copy suppression model with
single-owner-per-(package,major): a duplicate provider is now a hard
E_DUP_PROVIDER error, so every shared dependency has one authoritative
owner (unambiguous to rebuild/republish). Cross-major coexistence
(vue2/vue3) is retained, keyed by (package, major).

- core: delete the election/suppression subsystem (resolver, lower,
  import-map, core, render-context); manifest provenance is version-only.
- core: add E_TARGET_MISSING (root entry/exports file existence); mark
  E_NOT_USED/E_NO_EXPORT as build-time (bundler-emitted); drop the
  elections key from the esmx validate --json envelope.
- examples: framework shared packages (vue3/react/preact-shared) as the
  single owners; dependency hygiene (prod deps = @esmx/core only);
  rename ssr-micro-{vite,rsbuild}-vue -> -vue3; preact-htm JSX -> htm.
- scripts: Gate 5 agent one-shot harness (pnpm gate5; authoring + repair,
  judged by esmx validate --json exit status); smoke chunk-graph gate
  (Gate 2: single-owner + cross-major isolation across all 3 bundlers).
- remove the esmx migrate command (pre-release, no legacy users).
- docs(rfc,llms,architecture): rewrite for single-owner; gates met.

Verified: type-check, unit tests, build:packages + build:examples, SSR
smoke 22/22 + chunk-graph gate, hub validate exit 0, Gate 5 (kimi) 79/80.

BREAKING CHANGE: multiple providers of the same (package, major) now
error with E_DUP_PROVIDER instead of electing a winner; the esmx migrate
command and the loser-copy suppression manifest provenance are removed.
The single-owner shared packages over-shared the thin per-framework
provide/inject binding adapters (@unhead/vue, @esmx/router-vue;
@unhead/react, @esmx/router-react). Federating them split the module
instance across chunks, so a component's `useHead()` injected a
different headSymbol than create-app provided — SSR rendered with
"useHead() was called without provide context" (caught by CI lighthouse
+ visual; SSR smoke only checks hydration markers, so it missed it).

Share the framework RUNTIME only (vue / react / react-dom — the true
singletons) and bundle the binding adapters per app, so each app's
provide/inject Symbols stay self-consistent. The shared STATE (the
router-scoped head, the router) is still passed as values from
ssr-micro-shared, so head entries still converge on one document head.
No election is reintroduced (these adapters were never multi-provided).

vue3-shared provides ["vue"] (+ the @vue/server-renderer logical export);
react-shared provides ["react","react-dom"]. Verified: build:examples
0 SSR render errors (was 2), SSR smoke 22/22, chunk-graph gate intact
(vue/react/preact single-owner, majors isolated).
Regenerated via scripts/visual-run.sh (Linux chromium container) after
the single-owner refactor + head/router adapter fix. Only two baselines
changed in pixels: hub-landing (legitimate landing-page evolution on the
branch) and standalone-vite-html; all framework pages now match the
committed baselines again (the SSR head fix restored correct rendering).
Regenerate the visual PNG baselines in the same Linux/Chromium image CI
compares against (servers + Playwright co-located on localhost), then
upload them as an artifact to commit. The host-server scripts/visual-run.sh
helper cannot render client-rendered pages (e.g. standalone-vite-html)
because their import-map module URLs don't resolve across the docker bridge.
The local docker regen captured this client-rendered page empty (720px)
because its import-map module URLs don't resolve across the host->container
bridge. Replaced with the baseline regenerated in the jammy CI container
(servers + Playwright co-located on localhost), now the correct full-page
render (5476px).
The single rule: only dependencies the Node server resolves from
node_modules at production runtime (e.g. @esmx/core) belong in
`dependencies`; everything bundled or composed (frameworks, and `uses`
federation modules) goes in `devDependencies`.

- core(resolver): a used module's version range is read from
  devDependencies ∪ dependencies ∪ peerDependencies (it was deps∪peerDeps),
  so a `uses` module placed in devDependencies is still version-validated.
- docs(rfc,llms): the cart/host/my-remote examples put their `uses`
  modules (shared, cart, my-remote) in devDependencies, not dependencies;
  §4.1 range-source prose updated.
- create-esmx(templates): react-csr/react-ssr move react/react-dom to
  devDependencies — production deps are now @esmx/core only, matching the
  vue templates and the micro-app examples.

Verified: core 263 tests, create-esmx 96 tests, validate:llms, Biome.
build:packages exports the templates to examples/templates/* (workspace
packages in the lockfile); moving react/react-dom to devDependencies in
the source templates changed those importers, so the lockfile must be
regenerated or CI's `pnpm install --frozen-lockfile` (step: relink bins)
rejects the mismatch. Verified full CI-equivalent locally: lint:type,
all unit tests, build:examples, SSR smoke 22/22, frozen-lockfile install.
Leave only workflow_dispatch. The push-path trigger was a pre-merge
workaround (workflow_dispatch is only invocable once the workflow is on
the default branch); it can be re-run manually after this branch merges.
@lzxb
lzxb merged commit f640ada into master Jun 15, 2026
14 checks passed
@lzxb
lzxb deleted the feat-vite-rsbuild-bundler-support branch June 15, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant