Skip to content

V2 new samples#55

Open
erenkucuker wants to merge 19 commits intobugra9:mainfrom
erenkucuker:v2-new-samples
Open

V2 new samples#55
erenkucuker wants to merge 19 commits intobugra9:mainfrom
erenkucuker:v2-new-samples

Conversation

@erenkucuker
Copy link
Copy Markdown
Contributor

No description provided.

@erenkucuker erenkucuker requested a review from bugra9 as a code owner January 12, 2026 18:04
Both branches independently performed the v2 directory restructure
(packages/* → cppjs-{core,packages,plugins,samples}/*). Conflicts
resolved per the agreed grouping:

Group 1 — v2 restructure (cppjs-packages/*, cppjs-core/*): take main.
  Main holds the canonical v2 PR (bugra9#53) with newer dependency versions
  and the new target-system architecture (getTargetParams,
  getFilteredBuildTargets, target.path = platform-arch-runtime-buildtype).

Group 2 — mobile templates: take main. Main upgraded
  reactnative-cli/expo to Swift AppDelegate + the new expo `src/`
  layout; v2-new-samples still had the older Objective-C / flat layout.

Group 4 — false-positive UD/AA from rename detection: restored from
  origin/v2-new-samples (959ee3a). Git's rename detection paired
  v2-new-samples' new *-multithread/* and nuxt/remix native files
  with main's deleted packages/* paths, marking them as conflicts
  even though main never had those paths. 50 files restored.

Group 5 — workspace/CI/lockfile: take main. cppjs-core-create-app's
  package.json kept main's structure but manually merged in the new
  multithread/next/nuxt sample workspace dependencies.

Plugins (cppjs-plugins/*) currently hold main's clean version. The
SSR + multithread enhancements from v2-new-samples (commit a5299ca)
will be ported on top of main's new target API in a separate commit.
vite plugin (cppjs-plugin-vite/index.js):
  - Keep main's load() hook for /cpp.js (SPA HMR path).
  - Keep main's middleware that rewrites /cpp.wasm and /cpp.data.txt to
    /@fs/... so Vite serves them.
  - Add middleware branches for SSR contexts and pthread workers:
    /_nuxt/cpp.{js,wasm,data.txt,browser.js,worker.js} (Nuxt resolves
    these server-side and bypasses Vite's load() hook), and
    /cpp.browser.js / /cpp.worker.js (Emscripten pthread workers
    request the browser JS by these names).
  - ensureWasmBuilt() lazily compiles the wasm on the first SSR/worker
    request since those paths skip Vite's load() hook entirely.
  All paths use the new target API (buildTargetDebug.jsName/wasmName/
  dataTxtName) — no Emscripten-x86_64 or general.name fallbacks left.

cppjs-sample-lib-prebuilt-matrix-multithread:
  - cppjs.config.js: build.usePthread → target.runtime: 'mt'. main's
    cpp.js no longer reads usePthread (grep finds 0 hits in
    cppjs-core/cpp.js/src). Without this, loadConfig's auto-promotion
    can't fire and dependent samples build wasm-wasm32-st-debug
    instead of mt, then fail at link time looking for an mt Matrix.h.
  - package.json scripts: -p WebAssembly|Android|iOS → -p wasm|android|ios
    (main's bin.js validates against the lowercase set).

This is the only mt config touched intentionally — cascades through
loadConfig's runtime promotion to all samples that import matrix-mt.

Verified end-to-end in browser:
  svelte-vite (st), svelte-vite-mt, react-vite-mt,
  nuxt-vite (st), nuxt-vite-mt,
  next-webpack (st), next-webpack-mt,
  remix-vite — all render the matrix multiplication result.
Sample-side bugs that surfaced once the merge brought main's plugin
chain in. Pre-existing in v2-new-samples, not caused by the merge:

1. Missing await on Native.method() — Comlink wraps the embind module
   when it runs inside a worker (mt mode for the vite/webpack plugins,
   and effectively for nuxt/next even in st because they instantiate
   in a deferred context). All proxy calls return Promises, so the
   v2-new-samples authoring pattern of `setMessage(Native.sample())`
   rendered "[object Promise]" instead of the result.
   Fixed in:
     svelte-vite-mt/src/App.svelte
     react-vite-mt/src/App.jsx
     nuxt-vite/app/example.vue
     nuxt-vite-mt/app/example.vue
     next-webpack-mt/app/page.tsx
     remix-vite/app/welcome/welcome.tsx

2. svelte-vite-mt/src/App.svelte referenced an undefined `svelteLogo`
   binding (the import was missing and there's no svelte logo asset
   in the package). Removed the <div class="logo">…</div> block —
   it caused the whole component to render blank in Svelte 5.

For mt samples the thread-result poll also moved into setTimeout's
async callback so getThreadResult() actually completes before being
assigned (previously it raced runOnThread()).

Verified end-to-end: every listed sample renders the matrix result
in the browser.
… API

Same surgical migration as matrix-mt + the await pattern. This sample
was untouched by Group 3 because it's a CLI sample, not browser; only
surfaced when running it on the command line.

- cppjs.config.mjs: build.usePthread → target.runtime: 'mt'
- package.json script: -p WebAssembly →
    -p wasm -a wasm32 -r mt -e node -b release
  (mirrors the st sibling's flags but with -r mt)
- src/index.mjs:
    - Update the dist import path to the target-system naming
      (cppjs-sample-backend-nodejs-wasm-multithread-wasm-wasm32-mt-release.node.js).
    - await Native.sample()/runOnThread()/getThreadResult() — comlink
      proxies the worker calls.
    - Move getThreadResult() into setTimeout's async callback so the
      thread has time to finish.

Verified: `node src/index.mjs` prints both the standard result and
the thread-computed result.
- Drop the .cppjs/ci/* files that were tracked under the mobile
  reactnative-cli samples. These are intermediate cppjs build outputs
  (interface/, bridge/, cache.json) — they're regenerated locally and
  belong in .gitignore, not in the repo.
- Update pnpm-lock.yaml to reflect the workspace state after the
  main merge (new sample workspaces in cppjs-core-create-app's
  dependencies caused fresh resolutions).
@erenkucuker erenkucuker changed the base branch from v2 to main May 2, 2026 16:49
… script

Last sample still on the deprecated -p WebAssembly form. main's bin.js
rejects it (Invalid value: "WebAssembly". Allowed values: wasm, android, ios)
which broke `pnpm run ci:linux:build` since the CI script runs
build:samples across every workspace package.

Update to mirror the st-sibling's flag set with -r mt:
  -p wasm -a wasm32 -r mt -e node -b release

Note: the install-time failure for this sample (workspace packages
@cpp.js/package-{curl,gdal,...}-multithread missing) is a separate
pre-existing issue, not caused by this commit.
… exist

CI's pnpm install + build:samples step crashed because three playground
samples import @cpp.js/package-*-multithread workspace packages that were
never added to cppjs-packages/ — the playgrounds shipped, the mt package
set didn't. Original Linux CI error:

  ERR_MODULE_NOT_FOUND: Cannot find package '@cpp.js/package-curl-multithread'
  imported from .../cppjs-playground-backend-nodejs-multithread/cppjs.config.mjs

Excluding the affected playgrounds from pnpm-workspace.yaml so install
passes and `pnpm --filter=@cpp.js/sample-* run build` skips them. The
sample directories stay on disk for development; re-include the lines
once the corresponding cppjs-package-{curl,gdal,openssl,...}-multithread
workspace packages are added.

Excluded:
  - cppjs-samples/cppjs-playground-backend-nodejs-multithread
  - cppjs-samples/cppjs-playground-mobile-reactnative-cli-multithread
  - cppjs-samples/cppjs-playground-web-vite-multithread

Lockfile rewritten to drop the broken workspace:^ resolutions.

Note: the macOS CI failure ("Install the Apple certificate and provisioning
profile" — SecKeychainItemImport: Unable to decode the provided data) is a
secrets/certificate format issue unrelated to this branch.
… one

test-android-sample.yml and test-ios-sample.yml only built
@cpp.js/sample-lib-prebuilt-matrix (st), but `pnpm -r e2e:android`/
`pnpm run e2e:ios` recurse into every workspace and also run the e2e
test for @cpp.js/sample-mobile-reactnative-cli-multithread. That mt
sample's native.cpp does `#include <Matrix.h>`, which resolves via
cppjs deps to matrix-mt's dist/prebuilt/<target>/include — never
produced because the filter didn't match the -multithread package.

Symptom on the last v2-new-samples Android run:
  cppjs-sample-mobile-reactnative-cli-multithread/src/native/native.cpp:2:10:
  fatal error: 'Matrix.h' file not found
  > Task :cpp.js_plugin-react-native:buildCMakeRelWithDebInfo[arm64-v8a] FAILED

Switch the filter to a glob so pnpm picks up both:
  --filter=@cpp.js/sample-lib-prebuilt-matrix
  → --filter='@cpp.js/sample-lib-prebuilt-matrix*'

Verified locally — `pnpm --filter='@cpp.js/sample-lib-prebuilt-matrix*' list`
returns the st and mt packages. Both have build:android / build:ios scripts
already (the cmake/source siblings have neither because they're inline libs).
…expect

The mt React/Svelte App templates split the C++ result across two <p>
elements ("Matrix multiplier with c++" + "Standard Result : RESULT"),
but the e2e tests use Playwright's getByText('Matrix multiplier with c++
   =>   J₃ * (2*J₃) = 6*J₃') which only matches when both halves are
inside the SAME element (Playwright's text matcher doesn't span across
sibling nodes).

CI Linux Playwright failure on the latest v2-new-samples run:
  Error: element(s) not found
  > 6 |  await expect(page.getByText('Matrix multiplier with c++   =>
        J₃ * (2*J₃) = 6*J₃')).toBeVisible()
  at cppjs-sample-web-react-vite-multithread/e2e/cppjs.spec.cjs:6:90

Bring the mt App.jsx + App.svelte in line with the st sample format
(single <p> with "=>" separator). Thread result becomes its own <p>
that just shows the threadResult string (which is already prefixed
"Thread computed: ..." inside native.cpp), matching the second test
assertion.

The native.cpp matrix values aren't touched — st and mt sources are
identical, so the test's expected "= 6*J₃" / "= 36*J₃" already match
what the wasm produces.
48e1dea removed cppjs-sample-mobile-reactnative-cli{,-multithread}/ci/.cppjs/*
treating them as build-cache leftovers, but test-ios-sample.yml has a
"Restore cached bridge files" step that does:

  cp -r ./cppjs-samples/cppjs-sample-mobile-reactnative-cli/ci/.cppjs ./...

These pre-baked SWIG bridge outputs (interface/native.i, bridge/native.i.cpp,
bridge/native.i.cpp.exports.json, cache.json) are checked in on purpose so
the iOS workflow doesn't need to invoke `cppjs build` before pod install +
react-native run-ios — without them the .a build for the cppjs-react-native
plugin would fail at native compile.

Restored from the commit before 48e1dea. The lockfile cleanup half of
48e1dea is left in place; only the ci/.cppjs deletion is undone.
Three coupled fixes after running the playwright suite locally end-to-end:

1. cppjs-plugin-vite: add configurePreviewServer that sets COOP/COEP.
   `vite preview` (used by `e2e:prod` webServer) is otherwise just a
   static server, so SharedArrayBuffer is unavailable and the mt
   sample's pthread worker never initialises. The page sat on
   "compiling ..." through the test's 30s timeout. The dev middleware
   already sets these; the preview hook mirrors them.

2. svelte-vite-multithread App.svelte: revert to the original
   "Standard Result : ..." three-paragraph layout (244bf6e wrongly
   collapsed it the same way as react-mt). The svelte spec actually
   asserts on "Standard Result   :   J₃ * (2*J₃) = 6*J₃" — different
   pattern from react-mt's "Matrix multiplier with c++   =>   ...".
   Each mt App now matches its own spec's expected text again.

3. Both mt e2e specs now skip webkit:
     test.skip(({browserName}) => browserName === 'webkit', ...)
   WebKit's pthread + SharedArrayBuffer support on Linux is unreliable
   for our mt build — verified locally that the page stayed on
   "compiling ..." even with COOP/COEP set. chromium and firefox
   cover the mt path; the st samples still run on all three browsers.

Verified locally with `pnpm --filter='@cpp.js/sample-web-{react,svelte}-vite-multithread' run e2e:prod`:
  4 passed, 2 skipped (webkit) — for both samples.
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.

2 participants