react-native-gtkx 0.4.0-alpha.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/apis/host.gtkx.js.map +1 -1
  2. package/dist/components/modal.d.ts +1 -1
  3. package/dist/components/modal.js +16 -8
  4. package/dist/components/modal.js.map +1 -1
  5. package/dist/gtkx/bridge/adw.js.map +1 -1
  6. package/dist/gtkx/bridge/core.d.ts +1 -2
  7. package/dist/gtkx/bridge/core.js +2 -5
  8. package/dist/gtkx/bridge/core.js.map +1 -1
  9. package/dist/gtkx/bridge/geometry.js +1 -1
  10. package/dist/gtkx/bridge/geometry.js.map +1 -1
  11. package/dist/gtkx/bridge/layout-manager.js +18 -5
  12. package/dist/gtkx/bridge/layout-manager.js.map +1 -1
  13. package/dist/gtkx/bridge/slot-portal.js.map +1 -1
  14. package/dist/gtkx/bridge/svg-node.js +13 -6
  15. package/dist/gtkx/bridge/svg-node.js.map +1 -1
  16. package/dist/gtkx/bridge/view-box.js +18 -9
  17. package/dist/gtkx/bridge/view-box.js.map +1 -1
  18. package/dist/gtkx/bridge/widgets.generated.adw.js +1 -1
  19. package/dist/gtkx/bridge/widgets.generated.adw.js.map +1 -1
  20. package/dist/mcp/data/generated.d.ts +58 -42
  21. package/dist/mcp/data/generated.js +63 -43
  22. package/dist/mcp/data/generated.js.map +1 -1
  23. package/dist/runner/host-dev.js +5 -0
  24. package/dist/runner/host-dev.js.map +1 -1
  25. package/dist/runner/host.js +15 -0
  26. package/dist/runner/host.js.map +1 -1
  27. package/dist/runner/index.d.ts +27 -0
  28. package/dist/runner/index.js +206 -1
  29. package/dist/runner/index.js.map +1 -1
  30. package/dist/sea/assemble.d.ts +9 -0
  31. package/dist/sea/assemble.js +16 -3
  32. package/dist/sea/assemble.js.map +1 -1
  33. package/dist/sea/bundle.d.ts +37 -2
  34. package/dist/sea/bundle.js +76 -4
  35. package/dist/sea/bundle.js.map +1 -1
  36. package/dist/sea/native-shim.js +1 -1
  37. package/dist/sea/native-shim.js.map +1 -1
  38. package/dist/testing/index.js +28 -0
  39. package/dist/testing/index.js.map +1 -1
  40. package/dist/vite/index.js +3 -3
  41. package/dist/vite/index.js.map +1 -1
  42. package/dist/vitest/index.d.ts +1 -1
  43. package/dist/vitest/index.js.map +1 -1
  44. package/package.json +9 -9
  45. package/dist/gtkx/bridge/use-signal.d.ts +0 -2
  46. package/dist/gtkx/bridge/use-signal.js +0 -41
  47. package/dist/gtkx/bridge/use-signal.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,2EAA2E;AAC3E,yEAAyE;AACzE,uEAAuE;AACvE,oEAAoE;AACpE,uEAAuE;AACvE,4CAA4C;AAC5C,EAAE;AACF,kEAAkE;AAClE,qCAAqC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAqB,MAAM,oBAAoB,CAAA;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAkBxC,kEAAkE;AAClE,MAAM,sBAAsB,GAAG,EAAE,CAAA;AAEjC,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,IAAc,EAAE,GAAW,EAAU,EAAE;IACnE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IAClE,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,wEAAwE;AACxE,MAAM,KAAK,GAAG,CACZ,WAA2B,EAC3B,WAAmB,EACnB,OAAe,EACP,EAAE;IACV,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,WAAW,eAAe,CAAC,CAAA;IAC1E,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,WAAW,eAAe,CAEzD,CAAA;IACD,MAAM,GAAG,GACP,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAA;IAC3E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,GAAG,WAAW,uBAAuB,OAAO,UAAU,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,CAAA;AAC5C,CAAC,CAAA;AAID,iGAAiG;AACjG,MAAM,iBAAiB,GAAG,CAAC,QAAyB,EAAY,EAAE,CAChE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;KAChC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,gBAAgB,CAAC;KACjE,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/B,6EAA6E;AAC7E,8EAA8E;AAC9E,wFAAwF;AACxF,4EAA4E;AAC5E,0EAA0E;AAC1E,6EAA6E;AAC7E,8EAA8E;AAC9E,wEAAwE;AACxE,yEAAyE;AACzE,+BAA+B;AAC/B,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,+DAA+D;AAC/D,MAAM,kBAAkB,GAAG,KAAK,EAAE,IAAY,EAAiB,EAAE;IAC/D,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;IAChE,IAAI,CAAC;QACH,MAAM,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,GACtE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;QACtE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;QACzC,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CACV,yEAAyE,CAC1E,CAAA;YACD,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC9C,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAC7D,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAA;QAC5D,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,CAC/C,4BAA4B,CAC7B,CAAA;QACD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAA;QACrE,MAAM,OAAO,GAAG,UAAU,CAAC,sBAAsB,CAAoB,CAAA;QACrE,MAAM,KAAK,GAAG,UAAU,CAAC,0BAA0B,CAAoB,CAAA;QACvE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;YAC9B,SAAS;YACT,OAAO;YACP,EAAE,EAAE;gBACF,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;gBAC1C,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;gBACzC,OAAO,EAAE,OAAO,CAAC,OAAO;aACzB;YACD,GAAG,EAAE;gBACH,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC;gBAC3C,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC;gBAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB;YACD,eAAe,EAAE,iBAAiB,CAAC,KAAK,CAAC;SAC1C,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,CACV,MAAM,CAAC,aAAa;YAClB,CAAC,CAAC,yDAAyD;YAC3D,CAAC,CAAC,kDAAkD,CACvD,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,gEAAgE;YAC9D,8BAA8B,CACjC,CAAA;QACD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAE,MAAc,EAAQ,EAAE;IACvE,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAA;IAC5D,MAAM,MAAM,GAAG,GAAG,CAChB,OAAO,CAAC,QAAQ,EAChB;QACE,KAAK,CAAC,UAAU,EAAE,cAAc,EAAE,cAAc,CAAC;QACjD,QAAQ;QACR,YAAY;QACZ,OAAO;QACP,OAAO;QACP,OAAO;QACP,cAAc;QACd,SAAS;QACT,iBAAiB;QACjB,MAAM;KACP,EACD,IAAI,CACL,CAAA;IACD,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,KAAK,EAAE,MAAc,EAAoB,EAAE;IAChE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,SAAS,CAAC,CAAA;QAChD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAA;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;IAC3D,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAClD,IAAI,MAAM,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,OAAM;QACR,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;IAC1D,CAAC;IACD,OAAO,CAAC,KAAK,CACX,uDAAuD,MAAM,IAAI,CAClE,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAA;AAED,IAAI,UAAU,GAAwB,IAAI,CAAA;AAE1C,MAAM,SAAS,GAAG,CAChB,MAAc,EACd,QAAgB,EAChB,GAAW,EACM,EAAE,CACnB,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,uEAAuE;IACvE,wEAAwE;IACxE,wDAAwD;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACtE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;QAC1D,GAAG;QACH,KAAK,EAAE,SAAS;KACjB,CAAC,CAAA;IACF,UAAU,GAAG,KAAK,CAAA;IAClB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,UAAU,GAAG,IAAI,CAAA;QACjB,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IACpB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEJ,MAAM,WAAW,GAAG,KAAK,EACvB,MAAiB,EACjB,IAAkB,EACF,EAAE;IAClB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAA;IAChC,MAAM,MAAM,GAAG,oBAAoB,IAAI,EAAE,CAAA;IACzC,IAAI,KAAK,GAAwB,IAAI,CAAA;IACrC,IAAI,MAAM,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CACV,uDAAuD,MAAM,EAAE,CAChE,CAAA;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CACV,wDAAwD,MAAM,GAAG,CAClE,CAAA;QACD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAA;QACnE,KAAK,GAAG,KAAK,CACX,OAAO,CAAC,QAAQ,EAChB;YACE,KAAK,CAAC,UAAU,EAAE,cAAc,EAAE,cAAc,CAAC;YACjD,OAAO;YACP,QAAQ;YACR,IAAI;SACL,EACD,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CACvC,CAAA;QACD,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC5B,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;IAC/D,MAAM,SAAS,GAAG,GAAG,MAAM,IAAI,KAAK,8CAA8C,CAAA;IAClF,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAS,EAAE;QACvC,UAAU,EAAE,IAAI,EAAE,CAAA;QAClB,KAAK,EAAE,IAAI,EAAE,CAAA;QACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC,CAAA;IACD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IACvC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,uEAAuE;IACvE,kEAAkE;IAClE,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,eAAe,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACrE,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAA;IAC9E,CAAC;AACH,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,KAAK,EACpB,KAAe,EACf,MAAiB,EACjB,IAAkB,EACH,EAAE;IACjB,MAAM,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC/B,OAAM;IACR,CAAC;IACD,MAAM,MAAM,GACV,IAAI,CAAC,YAAY;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE,eAAe,CAAC,CAAA;IAC1E,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAChE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AACtB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,aAAa,GAAG,CAAC,IAAY,EAAU,EAAE;IAC7C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CACxD,gBAAgB,CACI,CAAA;QACtB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAA;QAC5C,OAAO,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAA;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,2EAA2E;AAC3E,yEAAyE;AACzE,yEAAyE;AACzE,wEAAwE;AACxE,yEAAyE;AACzE,oEAAoE;AACpE,4EAA4E;AAC5E,6BAA6B;AAC7B,EAAE;AACF,wDAAwD;AACxD,yEAAyE;AACzE,sEAAsE;AACtE,8BAA8B;AAC9B,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,SAAS;AACT,0EAA0E;AAC1E,kEAAkE;AAClE,8DAA8D;AAC9D,MAAM,UAAU,GAAG,KAAK,EACtB,KAAe,EACf,MAAiB,EACjB,IAAoB,EACL,EAAE;IACjB,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAChC,MAAM,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,CAAA;IAC9E,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC3C,OAAO,CAAC,IAAI,CAAC,mDAAmD,MAAM,EAAE,CAAC,CAAA;IACzE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,OAAM;IACR,CAAC;IACD,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,SAAS,GACb,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,CAAA;IAC9E,sEAAsE;IACtE,iBAAiB;IACjB,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG;QACpB,CAAC,CAAC,MAAM,WAAW,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,YAAY,EAAE,MAAM;YACpB,OAAO,EAAE,SAAS;SACnB,CAAC;QACJ,CAAC,CAAC,MAAM,gBAAgB,CAAC;YACrB,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,YAAY,EAAE,MAAM;YACpB,OAAO,EAAE,SAAS;SACnB,CAAC,CAAA;IACN,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAClD,OAAO,CAAC,IAAI,CACV,IAAI,CAAC,GAAG;QACN,CAAC,CAAC,sDAAsD,SAAS,GAAG;YAChE,IAAI,SAAS,kCAAkC;QACnD,CAAC,CAAC,sDAAsD,SAAS,GAAG;YAChE,IAAI,SAAS,4BAA4B,SAAS,KAAK,CAC9D,CAAA;AACH,CAAC,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,kFAAkF;QACpF,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,qBAAqB;gBAC3B,WAAW,EAAE,4BAA4B;gBACzC,OAAO,EAAE,UAAU;aACpB;YACD;gBACE,IAAI,EAAE,wBAAwB;gBAC9B,WAAW,EACT,sFAAsF;aACzF;YACD;gBACE,IAAI,EAAE,iBAAiB;gBACvB,WAAW,EAAE,8CAA8C;aAC5D;YACD;gBACE,IAAI,EAAE,OAAO;gBACb,WAAW,EACT,oFAAoF;aACvF;YACD;gBACE,IAAI,EAAE,iBAAiB;gBACvB,WAAW,EAAE,iDAAiD;aAC/D;SACF;QACD,IAAI,EAAE,QAAQ;KACf;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,uFAAuF;QACzF,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,qBAAqB;gBAC3B,WAAW,EAAE,4BAA4B;gBACzC,OAAO,EAAE,UAAU;aACpB;YACD;gBACE,IAAI,EAAE,wBAAwB;gBAC9B,WAAW,EACT,mEAAmE;aACtE;YACD;gBACE,IAAI,EAAE,cAAc;gBACpB,WAAW,EACT,iEAAiE;oBACjE,8CAA8C;aACjD;YACD;gBACE,IAAI,EAAE,OAAO;gBACb,WAAW,EACT,kEAAkE;oBAClE,2DAA2D;oBAC3D,wCAAwC;aAC3C;YACD;gBACE,IAAI,EAAE,qBAAqB;gBAC3B,WAAW,EACT,mDAAmD;oBACnD,sCAAsC;aACzC;SACF;QACD,IAAI,EAAE,UAAU;KACjB;CACF,CAAA","sourcesContent":["// The `run-linux` CLI command (registered through the package's\n// react-native.config.js, the react-native-windows model): ensure the gtkx\n// codegen store, then either build a release jsbundle with Metro and run\n// it in the Node+GTK host (./host.ts), or — with --dev — start/reuse a\n// Metro dev server and supervise the DEV host (./host-dev.ts): Fast\n// Refresh applies edits to the live window, and a full-refresh request\n// (exit code 65) restarts the host process.\n//\n// Like the hosts, this module must stay runnable under bare Node:\n// builtins and bare specifiers only.\nimport { spawn, spawnSync, type ChildProcess } from \"node:child_process\"\nimport { mkdirSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { basename, dirname, extname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\n\ntype CliConfig = { root: string }\ntype RunLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n skipBundling?: boolean\n dev?: boolean\n port?: string\n}\ntype BuildLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n standalone?: boolean\n sea?: boolean\n seaOutput?: string\n}\n\n/** Exit code host-dev.ts uses to request a supervisor restart. */\nconst FULL_REFRESH_EXIT_CODE = 65\n\nconst run = (command: string, args: string[], cwd: string): number => {\n const result = spawnSync(command, args, { cwd, stdio: \"inherit\" })\n return result.status ?? 1\n}\n\n/** Resolve an executable script shipped by a dependency's bin field. */\nconst binOf = (\n requireFrom: NodeJS.Require,\n packageName: string,\n binName: string,\n): string => {\n const packageJsonPath = requireFrom.resolve(`${packageName}/package.json`)\n const manifest = requireFrom(`${packageName}/package.json`) as {\n bin?: string | Record<string, string>\n }\n const bin =\n typeof manifest.bin === \"string\" ? manifest.bin : manifest.bin?.[binName]\n if (!bin) {\n throw new Error(`${packageName} does not expose a \"${binName}\" binary`)\n }\n return join(dirname(packageJsonPath), bin)\n}\n\ntype PackageManifest = { version: string; exports?: Record<string, unknown> }\n\n/** The `@gtkx/react` subpath exports (its own `exports` map, minus `.` and `./package.json`). */\nconst reactSubexportsOf = (manifest: PackageManifest): string[] =>\n Object.keys(manifest.exports ?? {})\n .filter((key) => key.startsWith(\"./\") && key !== \"./package.json\")\n .map((key) => key.slice(2))\n\n// @gtkx/cli is meant for apps: its `codegen` command resolves gtkx.config.ts\n// from a cwd and trusts a freshness stamp, which is what the retired rc.2-era\n// workaround this replaced was dodging (running from a reconstructed \"project that owns\n// the hosting node_modules\" purely to keep that cwd resolution honest — see\n// gtkx-org/gtkx#468, #470). A library generating bindings on a consumer's\n// behalf should use the programmatic @gtkx/codegen API instead: it takes the\n// GIR libraries and store paths directly, so there is no cwd to get wrong and\n// no stamp to misread — and it runs its own fingerprint-based freshness\n// check in-process, so a missing/pruned store is regenerated rather than\n// misreported as \"up to date\".\n//\n// `root` (the app's real project root, resolved by the react-native CLI, not\n// us) is the right place to resolve gtkx.config.ts from, but NOT necessarily\n// where @gtkx/* actually lives on disk: in a workspace, npm hoists them to an\n// ancestor's node_modules, so `root/node_modules` can be a directory with no\n// @gtkx/* in it at all (confirmed against this repo's own examples/, which\n// are workspace members with nothing hoisted locally). The store — and the\n// @gtkx/gi and @gtkx/jsx links every other @gtkx/* package resolves through\n// its OWN up-the-tree lookup — must live in whichever node_modules actually\n// hosts @gtkx/runtime, so that's resolved rather than assumed.\nconst ensureCodegenStore = async (root: string): Promise<void> => {\n console.warn(\"[react-native-gtkx] ensuring gtkx codegen store…\")\n try {\n const [{ runCodegen, resolveGirPath, resolveLibraries }, { loadConfig }] =\n await Promise.all([import(\"@gtkx/codegen\"), import(\"@gtkx/config\")])\n const { config } = await loadConfig(root)\n if (config.codegen === false) {\n console.warn(\n \"[react-native-gtkx] codegen: disabled for this project (gtkx.config.ts)\",\n )\n return\n }\n const girPath = resolveGirPath(config.girPath)\n const libraries = resolveLibraries(config.libraries, girPath)\n const appRequire = createRequire(join(root, \"package.json\"))\n const runtimePackageJsonPath = appRequire.resolve(\n \"@gtkx/runtime/package.json\",\n )\n const nodeModules = dirname(dirname(dirname(runtimePackageJsonPath)))\n const runtime = appRequire(runtimePackageJsonPath) as PackageManifest\n const react = appRequire(\"@gtkx/react/package.json\") as PackageManifest\n const result = await runCodegen({\n libraries,\n girPath,\n gi: {\n storeDir: join(nodeModules, \".gtkx\", \"gi\"),\n linkDir: join(nodeModules, \"@gtkx\", \"gi\"),\n version: runtime.version,\n },\n jsx: {\n storeDir: join(nodeModules, \".gtkx\", \"jsx\"),\n linkDir: join(nodeModules, \"@gtkx\", \"jsx\"),\n version: react.version,\n },\n reactSubexports: reactSubexportsOf(react),\n })\n console.warn(\n result.isRegenerated\n ? \"[react-native-gtkx] codegen: regenerated stale bindings\"\n : \"[react-native-gtkx] codegen: bindings up to date\",\n )\n } catch (error) {\n console.error(\n \"[react-native-gtkx] gtkx codegen failed — are GTK4/libadwaita \" +\n \"development files installed?\",\n )\n console.error(error)\n process.exit(1)\n }\n}\n\nconst bundle = (root: string, entryFile: string, output: string): void => {\n const appRequire = createRequire(join(root, \"package.json\"))\n const status = run(\n process.execPath,\n [\n binOf(appRequire, \"react-native\", \"react-native\"),\n \"bundle\",\n \"--platform\",\n \"linux\",\n \"--dev\",\n \"false\",\n \"--entry-file\",\n entryFile,\n \"--bundle-output\",\n output,\n ],\n root,\n )\n if (status !== 0) {\n process.exit(status)\n }\n}\n\nconst isMetroRunning = async (server: string): Promise<boolean> => {\n try {\n const response = await fetch(`${server}/status`)\n return (await response.text()).includes(\"packager-status:running\")\n } catch {\n return false\n }\n}\n\nconst waitForMetro = async (server: string): Promise<void> => {\n for (let attempt = 0; attempt < 120; attempt += 1) {\n if (await isMetroRunning(server)) {\n return\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n console.error(\n `[react-native-gtkx] Metro dev server never came up (${server}).`,\n )\n process.exit(1)\n}\n\nlet activeHost: ChildProcess | null = null\n\nconst spawnHost = (\n script: string,\n argument: string,\n cwd: string,\n): Promise<number> =>\n new Promise((resolve) => {\n // join over `new URL(script, import.meta.url)`: the global URL and the\n // node:url URL come from different type copies when the dependency tree\n // splits @types/node, and the two structurally diverge.\n const hostPath = join(dirname(fileURLToPath(import.meta.url)), script)\n const child = spawn(process.execPath, [hostPath, argument], {\n cwd,\n stdio: \"inherit\",\n })\n activeHost = child\n child.on(\"exit\", (code) => {\n activeHost = null\n resolve(code ?? 1)\n })\n })\n\nconst runLinuxDev = async (\n config: CliConfig,\n args: RunLinuxArgs,\n): Promise<never> => {\n const port = args.port ?? \"8081\"\n const server = `http://localhost:${port}`\n let metro: ChildProcess | null = null\n if (await isMetroRunning(server)) {\n console.warn(\n `[react-native-gtkx] reusing the Metro dev server at ${server}`,\n )\n } else {\n console.warn(\n `[react-native-gtkx] starting the Metro dev server at ${server}…`,\n )\n const appRequire = createRequire(join(config.root, \"package.json\"))\n metro = spawn(\n process.execPath,\n [\n binOf(appRequire, \"react-native\", \"react-native\"),\n \"start\",\n \"--port\",\n port,\n ],\n { cwd: config.root, stdio: \"inherit\" },\n )\n await waitForMetro(server)\n }\n const entry = basename(args.entryFile, extname(args.entryFile))\n const bundleUrl = `${server}/${entry}.bundle?platform=linux&dev=true&minify=false`\n const shutdown = (code: number): never => {\n activeHost?.kill()\n metro?.kill()\n process.exit(code)\n }\n process.on(\"SIGINT\", () => shutdown(0))\n process.on(\"SIGTERM\", () => shutdown(0))\n // Supervisor: a full-refresh request restarts the host with the window\n // reopening on the fresh bundle; any other exit ends the session.\n for (;;) {\n const code = await spawnHost(\"./host-dev.js\", bundleUrl, config.root)\n if (code !== FULL_REFRESH_EXIT_CODE) {\n shutdown(code)\n }\n console.warn(\"[react-native-gtkx] restarting the app after a full refresh…\")\n }\n}\n\nconst runLinux = async (\n _argv: string[],\n config: CliConfig,\n args: RunLinuxArgs,\n): Promise<void> => {\n await ensureCodegenStore(config.root)\n if (args.dev) {\n await runLinuxDev(config, args)\n return\n }\n const output =\n args.bundleOutput ??\n join(config.root, \"node_modules\", \".react-native-gtkx\", \"main.jsbundle\")\n if (!args.skipBundling) {\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n }\n const status = await spawnHost(\"./host.js\", output, config.root)\n process.exit(status)\n}\n\n/**\n * The executable name a `--sea` build defaults to: the app's package name\n * without its scope, so the artifact is `dist/hn-app`, not `dist/app`.\n */\nconst appBinaryName = (root: string): string => {\n try {\n const manifest = createRequire(join(root, \"package.json\"))(\n \"./package.json\",\n ) as { name?: string }\n const name = manifest.name?.split(\"/\").pop()\n return name && /^[\\w.-]+$/.test(name) ? name : \"app\"\n } catch {\n return \"app\"\n }\n}\n\n// The android/ios counterpart to run-linux's dev-only bundling: bundle for\n// distribution and stop, the way a release APK/IPA build does not launch\n// the app it produces. Deliberately skips ensureCodegenStore() — codegen\n// generates the @gtkx/gi bindings host.js imports to talk to GTK at RUN\n// time; bundling never touches them (Metro only reads/transforms JS, and\n// the GTK/react/yoga modules are proxied rather than imported — see\n// ../metro's HOST_MODULE_EXTERNALS). A machine that only builds never needs\n// GTK dev headers installed.\n//\n// --standalone and --sea are the exception: both inline\n// \"virtual:gtkx-config\", which re-exports @gtkx/jsx/metadata — a codegen\n// product — so they DO need the store, and therefore GTK dev headers.\n// Only those paths ensure it.\n//\n// The three artifacts, cheapest to heaviest, are deliberately one command\n// with flags rather than three commands: they share the Metro bundle step,\n// and the choice between them is a distribution question, not a different\n// build.\n// (default) main.jsbundle + a runtime node_modules + a system node\n// --standalone one .cjs file, no node_modules, + a system node\n// --sea one executable, nothing preinstalled at all\nconst buildLinux = async (\n _argv: string[],\n config: CliConfig,\n args: BuildLinuxArgs,\n): Promise<void> => {\n if (args.sea || args.standalone) {\n await ensureCodegenStore(config.root)\n }\n const output = args.bundleOutput ?? join(config.root, \"dist\", \"main.jsbundle\")\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n console.warn(`[react-native-gtkx] wrote the release bundle to ${output}`)\n if (!args.sea && !args.standalone) {\n return\n }\n const name = appBinaryName(config.root)\n const seaOutput =\n args.seaOutput ?? join(config.root, \"dist\", args.sea ? name : `${name}.cjs`)\n // Dynamically imported so the bundler is never loaded on the ordinary\n // jsbundle path.\n const { assembleSea, bundleStandalone } = await import(\"../sea/assemble.js\")\n const bytes = args.sea\n ? await assembleSea({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n : await bundleStandalone({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n const megabytes = (bytes / 1024 / 1024).toFixed(0)\n console.warn(\n args.sea\n ? `[react-native-gtkx] wrote the single executable to ${seaOutput} ` +\n `(${megabytes} MB — Node itself is most of it)`\n : `[react-native-gtkx] wrote the standalone script to ${seaOutput} ` +\n `(${megabytes} MB — run it with \\`node ${seaOutput}\\`)`,\n )\n}\n\n/** Commands contributed to the RN CLI by the package's react-native.config.js. */\nexport const commands = [\n {\n name: \"run-linux\",\n description:\n \"Bundle the app with Metro for the linux platform and run it in the Node+GTK host\",\n options: [\n {\n name: \"--entry-file <path>\",\n description: \"Path to the app entry file\",\n default: \"index.js\",\n },\n {\n name: \"--bundle-output <path>\",\n description:\n \"Where to write the jsbundle (default: node_modules/.react-native-gtkx/main.jsbundle)\",\n },\n {\n name: \"--skip-bundling\",\n description: \"Reuse the existing bundle at --bundle-output\",\n },\n {\n name: \"--dev\",\n description:\n \"Development mode: Metro dev server + Fast Refresh (edits apply to the live window)\",\n },\n {\n name: \"--port <number>\",\n description: \"Metro dev server port for --dev (default: 8081)\",\n },\n ],\n func: runLinux,\n },\n {\n name: \"build-linux\",\n description:\n \"Bundle the app with Metro for the linux platform for distribution, without running it\",\n options: [\n {\n name: \"--entry-file <path>\",\n description: \"Path to the app entry file\",\n default: \"index.js\",\n },\n {\n name: \"--bundle-output <path>\",\n description:\n \"Where to write the release jsbundle (default: dist/main.jsbundle)\",\n },\n {\n name: \"--standalone\",\n description:\n \"Also produce one self-contained .cjs — no node_modules, run it \" +\n \"with a system node (dist/<package name>.cjs)\",\n },\n {\n name: \"--sea\",\n description:\n \"Also produce a single executable (Node SEA): one file that runs \" +\n \"with no node_modules and no system Node — at the cost of \" +\n \"carrying a whole Node binary (~120 MB)\",\n },\n {\n name: \"--sea-output <path>\",\n description:\n \"Where to write the --sea / --standalone artifact \" +\n \"(default: dist/<package name>[.cjs])\",\n },\n ],\n func: buildLinux,\n },\n]\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"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","sourcesContent":["// The `run-linux` CLI command (registered through the package's\n// react-native.config.js, the react-native-windows model): ensure the gtkx\n// codegen store, then either build a release jsbundle with Metro and run\n// it in the Node+GTK host (./host.ts), or — with --dev — start/reuse a\n// Metro dev server and supervise the DEV host (./host-dev.ts): Fast\n// Refresh applies edits to the live window, and a full-refresh request\n// (exit code 65) restarts the host process.\n//\n// Like the hosts, this module must stay runnable under bare Node:\n// builtins and bare specifiers only.\nimport { spawn, spawnSync, type ChildProcess } from \"node:child_process\"\nimport { existsSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { basename, dirname, extname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\n\ntype CliConfig = { root: string }\ntype RunLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n skipBundling?: boolean\n dev?: boolean\n port?: string\n}\ntype BuildLinuxArgs = {\n entryFile: string\n bundleOutput?: string\n standalone?: boolean\n sea?: boolean\n seaOutput?: string\n}\ntype DeployLinuxArgs = {\n entryFile: string\n target?: string\n out?: string\n printManifests?: boolean\n skipBuild?: boolean\n}\n\n/** Exit code host-dev.ts uses to request a supervisor restart. */\nconst FULL_REFRESH_EXIT_CODE = 65\n\nconst fail = (message: string): never => {\n console.error(`[react-native-gtkx] ${message}`)\n process.exit(1)\n}\n\nconst run = (command: string, args: string[], cwd: string): number => {\n const result = spawnSync(command, args, { cwd, stdio: \"inherit\" })\n return result.status ?? 1\n}\n\n/** Resolve an executable script shipped by a dependency's bin field. */\nconst binOf = (\n requireFrom: NodeJS.Require,\n packageName: string,\n binName: string,\n): string => {\n const packageJsonPath = requireFrom.resolve(`${packageName}/package.json`)\n const manifest = requireFrom(`${packageName}/package.json`) as {\n bin?: string | Record<string, string>\n }\n const bin =\n typeof manifest.bin === \"string\" ? manifest.bin : manifest.bin?.[binName]\n if (!bin) {\n throw new Error(`${packageName} does not expose a \"${binName}\" binary`)\n }\n return join(dirname(packageJsonPath), bin)\n}\n\ntype PackageManifest = { version: string; exports?: Record<string, unknown> }\n\n/** The `@gtkx/react` subpath exports (its own `exports` map, minus `.` and `./package.json`). */\nconst reactSubexportsOf = (manifest: PackageManifest): string[] =>\n Object.keys(manifest.exports ?? {})\n .filter((key) => key.startsWith(\"./\") && key !== \"./package.json\")\n .map((key) => key.slice(2))\n\n// @gtkx/cli is meant for apps: its `codegen` command resolves gtkx.config.ts\n// from a cwd and trusts a freshness stamp, which is what the retired rc.2-era\n// workaround this replaced was dodging (running from a reconstructed \"project that owns\n// the hosting node_modules\" purely to keep that cwd resolution honest — see\n// gtkx-org/gtkx#468, #470). A library generating bindings on a consumer's\n// behalf should use the programmatic @gtkx/codegen API instead: it takes the\n// GIR libraries and store paths directly, so there is no cwd to get wrong and\n// no stamp to misread — and it runs its own fingerprint-based freshness\n// check in-process, so a missing/pruned store is regenerated rather than\n// misreported as \"up to date\".\n//\n// `root` (the app's real project root, resolved by the react-native CLI, not\n// us) is the right place to resolve gtkx.config.ts from, but NOT necessarily\n// where @gtkx/* actually lives on disk: in a workspace, npm hoists them to an\n// ancestor's node_modules, so `root/node_modules` can be a directory with no\n// @gtkx/* in it at all (confirmed against this repo's own examples/, which\n// are workspace members with nothing hoisted locally). The store — and the\n// @gtkx/gi and @gtkx/jsx links every other @gtkx/* package resolves through\n// its OWN up-the-tree lookup — must live in whichever node_modules actually\n// hosts @gtkx/runtime, so that's resolved rather than assumed.\nconst ensureCodegenStore = async (root: string): Promise<void> => {\n console.warn(\"[react-native-gtkx] ensuring gtkx codegen store…\")\n try {\n const [{ runCodegen, resolveGirPath, resolveLibraries }, { loadConfig }] =\n await Promise.all([import(\"@gtkx/codegen\"), import(\"@gtkx/config\")])\n const { config } = await loadConfig(root)\n if (config.codegen === false) {\n console.warn(\n \"[react-native-gtkx] codegen: disabled for this project (gtkx.config.ts)\",\n )\n return\n }\n const girPath = resolveGirPath(config.girPath)\n const libraries = resolveLibraries(config.libraries, girPath)\n const appRequire = createRequire(join(root, \"package.json\"))\n const runtimePackageJsonPath = appRequire.resolve(\n \"@gtkx/runtime/package.json\",\n )\n const nodeModules = dirname(dirname(dirname(runtimePackageJsonPath)))\n const runtime = appRequire(runtimePackageJsonPath) as PackageManifest\n const react = appRequire(\"@gtkx/react/package.json\") as PackageManifest\n const result = await runCodegen({\n libraries,\n girPath,\n gi: {\n storeDir: join(nodeModules, \".gtkx\", \"gi\"),\n linkDir: join(nodeModules, \"@gtkx\", \"gi\"),\n version: runtime.version,\n },\n jsx: {\n storeDir: join(nodeModules, \".gtkx\", \"jsx\"),\n linkDir: join(nodeModules, \"@gtkx\", \"jsx\"),\n version: react.version,\n },\n reactSubexports: reactSubexportsOf(react),\n })\n console.warn(\n result.isRegenerated\n ? \"[react-native-gtkx] codegen: regenerated stale bindings\"\n : \"[react-native-gtkx] codegen: bindings up to date\",\n )\n } catch (error) {\n console.error(\n \"[react-native-gtkx] gtkx codegen failed — are GTK4/libadwaita \" +\n \"development files installed?\",\n )\n console.error(error)\n process.exit(1)\n }\n}\n\nconst bundle = (root: string, entryFile: string, output: string): void => {\n const appRequire = createRequire(join(root, \"package.json\"))\n const status = run(\n process.execPath,\n [\n binOf(appRequire, \"react-native\", \"react-native\"),\n \"bundle\",\n \"--platform\",\n \"linux\",\n \"--dev\",\n \"false\",\n \"--entry-file\",\n entryFile,\n \"--bundle-output\",\n output,\n ],\n root,\n )\n if (status !== 0) {\n process.exit(status)\n }\n}\n\nconst isMetroRunning = async (server: string): Promise<boolean> => {\n try {\n const response = await fetch(`${server}/status`)\n return (await response.text()).includes(\"packager-status:running\")\n } catch {\n return false\n }\n}\n\nconst waitForMetro = async (server: string): Promise<void> => {\n for (let attempt = 0; attempt < 120; attempt += 1) {\n if (await isMetroRunning(server)) {\n return\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n console.error(\n `[react-native-gtkx] Metro dev server never came up (${server}).`,\n )\n process.exit(1)\n}\n\nlet activeHost: ChildProcess | null = null\n\nconst spawnHost = (\n script: string,\n argument: string,\n cwd: string,\n): Promise<number> =>\n new Promise((resolve) => {\n // join over `new URL(script, import.meta.url)`: the global URL and the\n // node:url URL come from different type copies when the dependency tree\n // splits @types/node, and the two structurally diverge.\n const hostPath = join(dirname(fileURLToPath(import.meta.url)), script)\n const child = spawn(process.execPath, [hostPath, argument], {\n cwd,\n stdio: \"inherit\",\n })\n activeHost = child\n child.on(\"exit\", (code) => {\n activeHost = null\n resolve(code ?? 1)\n })\n })\n\nconst runLinuxDev = async (\n config: CliConfig,\n args: RunLinuxArgs,\n): Promise<never> => {\n const port = args.port ?? \"8081\"\n const server = `http://localhost:${port}`\n let metro: ChildProcess | null = null\n if (await isMetroRunning(server)) {\n console.warn(\n `[react-native-gtkx] reusing the Metro dev server at ${server}`,\n )\n } else {\n console.warn(\n `[react-native-gtkx] starting the Metro dev server at ${server}…`,\n )\n const appRequire = createRequire(join(config.root, \"package.json\"))\n metro = spawn(\n process.execPath,\n [\n binOf(appRequire, \"react-native\", \"react-native\"),\n \"start\",\n \"--port\",\n port,\n ],\n { cwd: config.root, stdio: \"inherit\" },\n )\n await waitForMetro(server)\n }\n const entry = basename(args.entryFile, extname(args.entryFile))\n const bundleUrl = `${server}/${entry}.bundle?platform=linux&dev=true&minify=false`\n const shutdown = (code: number): never => {\n activeHost?.kill()\n metro?.kill()\n process.exit(code)\n }\n process.on(\"SIGINT\", () => shutdown(0))\n process.on(\"SIGTERM\", () => shutdown(0))\n // Supervisor: a full-refresh request restarts the host with the window\n // reopening on the fresh bundle; any other exit ends the session.\n for (;;) {\n const code = await spawnHost(\"./host-dev.js\", bundleUrl, config.root)\n if (code !== FULL_REFRESH_EXIT_CODE) {\n shutdown(code)\n }\n console.warn(\"[react-native-gtkx] restarting the app after a full refresh…\")\n }\n}\n\nconst runLinux = async (\n _argv: string[],\n config: CliConfig,\n args: RunLinuxArgs,\n): Promise<void> => {\n await ensureCodegenStore(config.root)\n if (args.dev) {\n await runLinuxDev(config, args)\n return\n }\n const output =\n args.bundleOutput ??\n join(config.root, \"node_modules\", \".react-native-gtkx\", \"main.jsbundle\")\n if (!args.skipBundling) {\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n }\n const status = await spawnHost(\"./host.js\", output, config.root)\n process.exit(status)\n}\n\n/**\n * The executable name a `--sea` build defaults to: the app's package name\n * without its scope, so the artifact is `dist/hn-app`, not `dist/app`.\n */\nconst appBinaryName = (root: string): string => {\n try {\n const manifest = createRequire(join(root, \"package.json\"))(\n \"./package.json\",\n ) as { name?: string }\n const name = manifest.name?.split(\"/\").pop()\n return name && /^[\\w.-]+$/.test(name) ? name : \"app\"\n } catch {\n return \"app\"\n }\n}\n\n// The android/ios counterpart to run-linux's dev-only bundling: bundle for\n// distribution and stop, the way a release APK/IPA build does not launch\n// the app it produces. Deliberately skips ensureCodegenStore() — codegen\n// generates the @gtkx/gi bindings host.js imports to talk to GTK at RUN\n// time; bundling never touches them (Metro only reads/transforms JS, and\n// the GTK/react/yoga modules are proxied rather than imported — see\n// ../metro's HOST_MODULE_EXTERNALS). A machine that only builds never needs\n// GTK dev headers installed.\n//\n// --standalone and --sea are the exception: both inline\n// \"virtual:gtkx-config\", which re-exports @gtkx/jsx/metadata — a codegen\n// product — so they DO need the store, and therefore GTK dev headers.\n// Only those paths ensure it.\n//\n// The three artifacts, cheapest to heaviest, are deliberately one command\n// with flags rather than three commands: they share the Metro bundle step,\n// and the choice between them is a distribution question, not a different\n// build.\n// (default) main.jsbundle + a runtime node_modules + a system node\n// --standalone one .cjs file, no node_modules, + a system node\n// --sea one executable, nothing preinstalled at all\nconst buildLinux = async (\n _argv: string[],\n config: CliConfig,\n args: BuildLinuxArgs,\n): Promise<void> => {\n if (args.sea || args.standalone) {\n await ensureCodegenStore(config.root)\n }\n const output = args.bundleOutput ?? join(config.root, \"dist\", \"main.jsbundle\")\n mkdirSync(dirname(output), { recursive: true })\n bundle(config.root, args.entryFile, output)\n console.warn(`[react-native-gtkx] wrote the release bundle to ${output}`)\n if (!args.sea && !args.standalone) {\n return\n }\n const name = appBinaryName(config.root)\n const seaOutput =\n args.seaOutput ?? join(config.root, \"dist\", args.sea ? name : `${name}.cjs`)\n // Dynamically imported so the bundler is never loaded on the ordinary\n // jsbundle path.\n const { assembleSea, bundleStandalone } = await import(\"../sea/assemble.js\")\n const bytes = args.sea\n ? await assembleSea({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n : await bundleStandalone({\n appRoot: config.root,\n jsbundlePath: output,\n outFile: seaOutput,\n })\n const megabytes = (bytes / 1024 / 1024).toFixed(0)\n console.warn(\n args.sea\n ? `[react-native-gtkx] wrote the single executable to ${seaOutput} ` +\n `(${megabytes} MB — Node itself is most of it)`\n : `[react-native-gtkx] wrote the standalone script to ${seaOutput} ` +\n `(${megabytes} MB — run it with \\`node ${seaOutput}\\`)`,\n )\n}\n\n// `deploy-linux`: `npx gtkx deploy` packages a project's `dist/` into\n// .deb/.rpm/.AppImage/.flatpak, but it is vite-shaped by construction — its\n// payload stager (@gtkx/cli's stagePayload) unconditionally requires\n// `dist/bundle.mjs` and copies the rest of `dist/` verbatim, `--skip-build`\n// included. A Metro app never produces that file (Metro externalizes\n// @gtkx/*/react/yoga-layout instead of inlining them — see ../metro's\n// HOST_MODULE_EXTERNALS), so `gtkx deploy` cannot package one on its own.\n// This command is the bridge: on the vite path it is a thin proxy (the app\n// already looks exactly like what `gtkx deploy` expects); on the Metro path\n// it builds a real Metro release, reshapes that build into the same\n// dist/bundle.mjs shape a vite build would have produced, and only then\n// calls into `gtkx deploy --skip-build`.\n//\n// Registered the same way as run-linux/build-linux (react-native.config.js),\n// so the RN CLI exposes it to every app that depends on react-native-gtkx —\n// regardless of which toolchain that particular app actually builds with:\n// `npx react-native config` from a vite-path example already lists\n// run-linux/build-linux today (confirmed against examples/monitor, which has\n// no `react-native` dependency of its own — the command surface comes along\n// because react-native-gtkx is a dependency, and this workspace happens to\n// hoist `react-native` where every example's own `npx` lookup can still find\n// it). So this command has to tell the two toolchains apart itself; neither\n// run-linux nor build-linux do that today (they are Metro-only by\n// construction), so there is no existing helper to reuse — see\n// isViteProject below for the detection this command invents.\n\n/** Every extension `gtkx.config.ts` is allowed to use (c12's own candidate\n * list, mirrored rather than imported since @gtkx/config does not export\n * it) — used only for the friendlier \"you're missing one\" error below;\n * @gtkx/config's own loader remains the actual authority. */\nconst GTKX_CONFIG_CANDIDATES = [\"ts\", \"js\", \"mjs\", \"cjs\", \"mts\", \"cts\"].map(\n (extension) => `gtkx.config.${extension}`,\n)\n\nconst hasGtkxConfig = (root: string): boolean =>\n GTKX_CONFIG_CANDIDATES.some((name) => existsSync(join(root, name)))\n\n/** Vite's own convention for \"this directory is a vite project\" — every\n * vite-path example in this repo (gallery, monitor, tasks-app, tasks-nav)\n * has exactly one of these at its root, and no Metro app does (hn-app and\n * rn-app have `metro.config.js` and a root `index.js` instead). Exported so\n * the detection itself is unit-testable without spawning anything. */\nexport const VITE_CONFIG_CANDIDATES = [\n \"vite.config.ts\",\n \"vite.config.js\",\n \"vite.config.mjs\",\n \"vite.config.mts\",\n]\n\nexport const isViteProject = (root: string): boolean =>\n VITE_CONFIG_CANDIDATES.some((name) => existsSync(join(root, name)))\n\n/** `--target`/`--out`/`--print-manifests` — passed through unchanged to\n * `gtkx deploy` on both paths. `--skip-build` is handled separately by each\n * path below: it means something different on each (see deployLinuxMetro). */\nconst commonDeployArgs = (args: DeployLinuxArgs): string[] => {\n const passthrough: string[] = []\n if (args.target !== undefined) {\n passthrough.push(\"--target\", args.target)\n }\n if (args.out !== undefined) {\n passthrough.push(\"--out\", args.out)\n }\n if (args.printManifests) {\n passthrough.push(\"--print-manifests\")\n }\n return passthrough\n}\n\nconst runGtkxDeploy = (root: string, args: string[]): number => {\n const appRequire = createRequire(join(root, \"package.json\"))\n return run(\n process.execPath,\n [binOf(appRequire, \"@gtkx/cli\", \"gtkx\"), \"deploy\", ...args],\n root,\n )\n}\n\n// The vite path IS what `gtkx deploy` already expects — no build of ours to\n// run, no staging to do. A missing gtkx.config.ts or `deploy` block surfaces\n// through gtkx's own error (stdio is inherited below), which already names\n// exactly what to add and where (a ready-to-paste `deploy` block derived\n// from package.json for the latter).\nconst deployLinuxVite = (config: CliConfig, args: DeployLinuxArgs): void => {\n const gtkxArgs = [\n ...commonDeployArgs(args),\n ...(args.skipBuild ? [\"--skip-build\"] : []),\n ]\n process.exit(runGtkxDeploy(config.root, gtkxArgs))\n}\n\nconst DEPLOY_SCRATCH_BUNDLE = \"deploy.jsbundle\"\n\n/**\n * Reshapes a Metro build into the one file `gtkx deploy --skip-build`\n * actually checks for (`dist/bundle.mjs`) plus whatever it needs beside it,\n * by reusing --standalone's own bundler rather than inventing a second one:\n * bundleStandalone already produces a single self-contained CJS file with\n * the whole HOST_MODULE_EXTERNALS closure AND the native addon (as a\n * base64 literal, extracted to a per-user cache on first run) inlined — see\n * ../sea/native-shim.ts. That statically satisfies everything a vite build's\n * dist/bundle.mjs would otherwise need a separate dist/gtkx.node for.\n *\n * The one thing it is NOT is an ES module — rolldown emits it as CJS (see\n * ../sea/bundle.ts's header for why: a Node SEA's main script is forced to\n * CJS, and --standalone shares that bundler). `dist/bundle.mjs` cannot just\n * be that file under a different name: Node parses a `.mjs` file as ESM\n * unconditionally, and `module.exports = …`/bare `require(…)` are\n * ReferenceErrors there. So this writes the real artifact under its own\n * name and a two-line ESM shim at dist/bundle.mjs that hands off to it via\n * `createRequire` — synchronous, so no top-level await, and it resolves\n * \"./<name>.cjs\" from its OWN location (import.meta.url), which is exactly\n * where stagePayload copies it (both files land in the same directory,\n * `lib/<binaryName>/`), regardless of the installed package's cwd.\n */\nconst stageMetroDeployDist = async (\n root: string,\n entryFile: string,\n): Promise<string> => {\n const scratchDir = join(root, \"node_modules\", \".react-native-gtkx\")\n mkdirSync(scratchDir, { recursive: true })\n const jsbundlePath = join(scratchDir, DEPLOY_SCRATCH_BUNDLE)\n bundle(root, entryFile, jsbundlePath)\n\n const distDir = join(root, \"dist\")\n // Cleared, not merged into: gtkx deploy stages every file it finds under\n // dist/ (barring an icons/ dir and its own build metadata), so a stale\n // main.jsbundle or a previous run's artifacts left over from a plain\n // `build-linux` would otherwise ship inside the package too.\n rmSync(distDir, { recursive: true, force: true })\n mkdirSync(distDir, { recursive: true })\n\n const name = appBinaryName(root)\n const standaloneOutput = join(distDir, `${name}.cjs`)\n const { bundleStandalone } = await import(\"../sea/assemble.js\")\n await bundleStandalone({\n appRoot: root,\n jsbundlePath,\n outFile: standaloneOutput,\n // gtkx deploy's third-party-notices step reads dist/gtkx-packages.json\n // unconditionally (--skip-build included) — see bundleStandalone's own\n // comment for why this is the one flag deploy-linux passes that\n // build-linux --standalone never does.\n shouldWritePackageManifest: true,\n })\n\n writeFileSync(\n join(distDir, \"bundle.mjs\"),\n [\n \"// Generated by `react-native deploy-linux` — do not edit by hand.\",\n \"// gtkx deploy's payload stager only recognizes a vite-shaped\",\n `// dist/bundle.mjs; this hands off to the real Metro-built artifact`,\n `// next to it (${name}.cjs, which inlines the whole runtime closure`,\n \"// and the native addon — see stageMetroDeployDist in\",\n \"// react-native-gtkx/runner for the full explanation).\",\n 'import { createRequire } from \"node:module\"',\n \"\",\n `createRequire(import.meta.url)(${JSON.stringify(`./${name}.cjs`)})`,\n \"\",\n ].join(\"\\n\"),\n )\n console.warn(`[react-native-gtkx] staged a vite-shaped dist/ at ${distDir}`)\n return distDir\n}\n\nconst deployLinuxMetro = async (\n config: CliConfig,\n args: DeployLinuxArgs,\n): Promise<void> => {\n const root = config.root\n if (!hasGtkxConfig(root)) {\n fail(\n `no gtkx.config.ts found at ${root} — deploy-linux needs one on the ` +\n \"Metro path too (the same file the codegen store already \" +\n \"requires), exporting a `deploy` block from defineConfig(). See \" +\n \"docs/guide/packaging.md.\",\n )\n }\n\n const distBundle = join(root, \"dist\", \"bundle.mjs\")\n if (args.skipBuild) {\n if (!existsSync(distBundle)) {\n fail(\n `--skip-build was given but ${distBundle} does not exist yet — ` +\n \"run deploy-linux without --skip-build at least once first.\",\n )\n }\n console.warn(\n \"[react-native-gtkx] --skip-build: reusing the already-staged dist/\",\n )\n } else {\n await ensureCodegenStore(root)\n await stageMetroDeployDist(root, args.entryFile)\n }\n\n // gtkx deploy's own entry resolution runs unconditionally (even with\n // --skip-build), and its default (src/index.{tsx,jsx,ts,js}) is the vite\n // convention, not Metro's — pass the Metro entry file through explicitly\n // so it resolves, even though the value itself goes unused once staging\n // is skipped.\n const gtkxArgs = [\"--skip-build\", ...commonDeployArgs(args), args.entryFile]\n process.exit(runGtkxDeploy(root, gtkxArgs))\n}\n\nconst deployLinux = async (\n _argv: string[],\n config: CliConfig,\n args: DeployLinuxArgs,\n): Promise<void> => {\n if (isViteProject(config.root)) {\n deployLinuxVite(config, args)\n return\n }\n await deployLinuxMetro(config, args)\n}\n\n/** Commands contributed to the RN CLI by the package's react-native.config.js. */\nexport const commands = [\n {\n name: \"run-linux\",\n description:\n \"Bundle the app with Metro for the linux platform and run it in the Node+GTK host\",\n options: [\n {\n name: \"--entry-file <path>\",\n description: \"Path to the app entry file\",\n default: \"index.js\",\n },\n {\n name: \"--bundle-output <path>\",\n description:\n \"Where to write the jsbundle (default: node_modules/.react-native-gtkx/main.jsbundle)\",\n },\n {\n name: \"--skip-bundling\",\n description: \"Reuse the existing bundle at --bundle-output\",\n },\n {\n name: \"--dev\",\n description:\n \"Development mode: Metro dev server + Fast Refresh (edits apply to the live window)\",\n },\n {\n name: \"--port <number>\",\n description: \"Metro dev server port for --dev (default: 8081)\",\n },\n ],\n func: runLinux,\n },\n {\n name: \"build-linux\",\n description:\n \"Bundle the app with Metro for the linux platform for distribution, without running it\",\n options: [\n {\n name: \"--entry-file <path>\",\n description: \"Path to the app entry file\",\n default: \"index.js\",\n },\n {\n name: \"--bundle-output <path>\",\n description:\n \"Where to write the release jsbundle (default: dist/main.jsbundle)\",\n },\n {\n name: \"--standalone\",\n description:\n \"Also produce one self-contained .cjs — no node_modules, run it \" +\n \"with a system node (dist/<package name>.cjs)\",\n },\n {\n name: \"--sea\",\n description:\n \"Also produce a single executable (Node SEA): one file that runs \" +\n \"with no node_modules and no system Node — at the cost of \" +\n \"carrying a whole Node binary (~120 MB)\",\n },\n {\n name: \"--sea-output <path>\",\n description:\n \"Where to write the --sea / --standalone artifact \" +\n \"(default: dist/<package name>[.cjs])\",\n },\n ],\n func: buildLinux,\n },\n {\n name: \"deploy-linux\",\n description:\n \"Package the app for distribution (.deb/.rpm/.AppImage/.flatpak) — vite path proxies `gtkx deploy`, Metro path builds and stages first\",\n options: [\n {\n name: \"--entry-file <path>\",\n description: \"Path to the app entry file (Metro path only)\",\n default: \"index.js\",\n },\n {\n name: \"--target <formats>\",\n description:\n \"Comma-separated package formats to build (deb, rpm, appimage, flatpak)\",\n },\n {\n name: \"--out <path>\",\n description:\n \"Output directory relative to the project root (default: build)\",\n },\n {\n name: \"--print-manifests\",\n description:\n \"Write the generated desktop-entry/AppStream metadata, then stop without packaging\",\n },\n {\n name: \"--skip-build\",\n description:\n \"Package the already-staged dist/ instead of rebuilding (vite: passed through to `gtkx deploy`; Metro: also skips this command's own staging)\",\n },\n ],\n func: deployLinux,\n },\n]\n"]}
@@ -15,11 +15,20 @@ export type AssembleSeaOptions = {
15
15
  * system `node`. Everything the SEA is except the embedded Node runtime —
16
16
  * so ~120 MB smaller, at the cost of a `nodejs` dependency to declare.
17
17
  * Returns its size in bytes.
18
+ *
19
+ * `shouldWritePackageManifest` is for deploy-linux's own Metro-path staging
20
+ * (../runner/index.ts): `gtkx deploy` requires a `gtkx-packages.json` inside
21
+ * `dist/` before it will package anything, vite-built or not (its
22
+ * third-party-notices step reads it unconditionally, --skip-build included)
23
+ * — writing it here, from the real module graph this bundling step just
24
+ * produced, is cheap and accurate; an ordinary `build-linux --standalone`
25
+ * has no use for it, so it stays off by default.
18
26
  */
19
27
  export declare const bundleStandalone: (options: {
20
28
  appRoot: string;
21
29
  jsbundlePath: string;
22
30
  outFile: string;
31
+ shouldWritePackageManifest?: boolean;
23
32
  }) => Promise<number>;
24
33
  /**
25
34
  * Produces a single executable at {@link AssembleSeaOptions.outFile} and
@@ -16,7 +16,7 @@
16
16
  import { spawnSync } from "node:child_process";
17
17
  import { chmodSync, copyFileSync, mkdirSync, statSync, writeFileSync, } from "node:fs";
18
18
  import { dirname, join } from "node:path";
19
- import { bundleMetroSea } from "./bundle.js";
19
+ import { BUNDLED_PACKAGES_FILENAME, bundleMetroSea, collectBundledPackages, renderBundledPackagesManifest, } from "./bundle.js";
20
20
  /** The fuse postject looks for inside the node binary to place the blob. */
21
21
  const SENTINEL_FUSE = "NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2";
22
22
  /** Pinned: postject has no stable release, and the SEA docs name this one. */
@@ -64,17 +64,30 @@ const stripSymbols = (file) => {
64
64
  * system `node`. Everything the SEA is except the embedded Node runtime —
65
65
  * so ~120 MB smaller, at the cost of a `nodejs` dependency to declare.
66
66
  * Returns its size in bytes.
67
+ *
68
+ * `shouldWritePackageManifest` is for deploy-linux's own Metro-path staging
69
+ * (../runner/index.ts): `gtkx deploy` requires a `gtkx-packages.json` inside
70
+ * `dist/` before it will package anything, vite-built or not (its
71
+ * third-party-notices step reads it unconditionally, --skip-build included)
72
+ * — writing it here, from the real module graph this bundling step just
73
+ * produced, is cheap and accurate; an ordinary `build-linux --standalone`
74
+ * has no use for it, so it stays off by default.
67
75
  */
68
76
  export const bundleStandalone = async (options) => {
69
77
  const { appRoot, jsbundlePath, outFile } = options;
70
78
  mkdirSync(dirname(outFile), { recursive: true });
71
79
  console.warn("[react-native-gtkx] bundling a standalone script…");
72
- await bundleMetroSea({
80
+ const { moduleIds } = await bundleMetroSea({
73
81
  appRoot,
74
82
  jsbundlePath,
75
83
  outFile,
76
84
  nativeAddonSource: "inline",
77
85
  });
86
+ if (options.shouldWritePackageManifest) {
87
+ const distDir = dirname(outFile);
88
+ const packages = collectBundledPackages(moduleIds, distDir);
89
+ writeFileSync(join(distDir, BUNDLED_PACKAGES_FILENAME), renderBundledPackagesManifest(packages));
90
+ }
78
91
  return statSync(outFile).size;
79
92
  };
80
93
  /**
@@ -89,7 +102,7 @@ export const assembleSea = async (options) => {
89
102
  mkdirSync(dirname(outFile), { recursive: true });
90
103
  console.warn("[react-native-gtkx] bundling for a single executable…");
91
104
  const bundlePath = join(workDir, "sea-bundle.cjs");
92
- const nativeAddon = await bundleMetroSea({
105
+ const { nativeAddon } = await bundleMetroSea({
93
106
  appRoot,
94
107
  jsbundlePath,
95
108
  outFile: bundlePath,
@@ -1 +1 @@
1
- {"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../src/sea/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["// Turns a Metro-built app into ONE executable file: bundle everything into\n// a CJS entry (./bundle.ts), generate a SEA blob from it, then inject that\n// blob into a copy of the `node` binary. This is the whole of what \"SEA\"\n// means — Node's Single Executable Application format is literally a copy\n// of the node binary with a V8 code-cache blob appended, which is why the\n// result necessarily carries Node's own weight (~117 MB on linux-arm64,\n// against <7 MB for the app code and its native addon).\n//\n// Follows gtkx's own tutorial (gtkx-org/gtkx examples/tutorial/scripts/\n// build-sea.sh) for these mechanics; ./bundle.ts's header documents where\n// the bundling half deliberately diverges.\n//\n// Kept out of ../runner/index.ts and reached through a dynamic import so\n// the bundler is only loaded when a SEA is actually asked for; the\n// ordinary `build-linux` path never touches it.\nimport { spawnSync } from \"node:child_process\"\nimport {\n chmodSync,\n copyFileSync,\n mkdirSync,\n statSync,\n writeFileSync,\n} from \"node:fs\"\nimport { dirname, join } from \"node:path\"\nimport { bundleMetroSea } from \"./bundle.js\"\n\n/** The fuse postject looks for inside the node binary to place the blob. */\nconst SENTINEL_FUSE = \"NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2\"\n\n/** Pinned: postject has no stable release, and the SEA docs name this one. */\nconst POSTJECT = \"postject@1.0.0-alpha.6\"\n\nexport type AssembleSeaOptions = {\n /** The app root — where gtkx.config.ts and package.json live. */\n appRoot: string\n /** The release jsbundle `build-linux` just wrote. */\n jsbundlePath: string\n /** Where the finished executable is written. */\n outFile: string\n /** Scratch directory for the intermediate CJS bundle, the SEA config and\n * the prep blob (default: alongside the jsbundle). */\n workDir?: string\n}\n\nconst run = (command: string, args: string[]): void => {\n const result = spawnSync(command, args, { stdio: \"inherit\" })\n if (result.error) {\n throw result.error\n }\n if (result.status !== 0) {\n throw new Error(`${command} ${args.join(\" \")} exited with ${result.status}`)\n }\n}\n\n/**\n * Drops the debug symbols from the copied Node binary. Worth a step of its\n * own because the saving is not marginal: the `node` binary distributed by\n * NodeSource for Ubuntu ships `with debug_info, not stripped` — measured at\n * 117 MB, and 98 MB after `strip --strip-all`. Nothing in a SEA needs those\n * symbols; the only cost is that a crash inside Node's own C++ produces an\n * unsymbolicated backtrace.\n *\n * Runs BEFORE postject, never after: `--strip-all` removes non-allocated\n * sections, which is exactly what the injected NODE_SEA_BLOB is.\n *\n * Best-effort — a build machine without binutils still produces a working\n * (larger) executable rather than failing, so this cannot become a new\n * install requirement for a build that worked yesterday.\n */\nconst stripSymbols = (file: string): void => {\n const before = statSync(file).size\n const result = spawnSync(\"strip\", [\"--strip-all\", file], {\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n })\n if (result.error || result.status !== 0) {\n console.warn(\n \"[react-native-gtkx] skipped stripping symbols (no usable `strip`) — \" +\n \"the executable will be tens of MB larger than it needs to be\",\n )\n return\n }\n const saved = (before - statSync(file).size) / 1024 / 1024\n console.warn(\n `[react-native-gtkx] stripped debug symbols (-${saved.toFixed(0)} MB)`,\n )\n}\n\n/**\n * Produces the middle artifact: one self-contained CJS file with the app,\n * its whole node_modules closure and the native addon inlined, run by a\n * system `node`. Everything the SEA is except the embedded Node runtime —\n * so ~120 MB smaller, at the cost of a `nodejs` dependency to declare.\n * Returns its size in bytes.\n */\nexport const bundleStandalone = async (options: {\n appRoot: string\n jsbundlePath: string\n outFile: string\n}): Promise<number> => {\n const { appRoot, jsbundlePath, outFile } = options\n mkdirSync(dirname(outFile), { recursive: true })\n console.warn(\"[react-native-gtkx] bundling a standalone script…\")\n await bundleMetroSea({\n appRoot,\n jsbundlePath,\n outFile,\n nativeAddonSource: \"inline\",\n })\n return statSync(outFile).size\n}\n\n/**\n * Produces a single executable at {@link AssembleSeaOptions.outFile} and\n * returns its size in bytes. Requires network access on first run unless\n * postject is already in the npx cache.\n */\nexport const assembleSea = async (\n options: AssembleSeaOptions,\n): Promise<number> => {\n const { appRoot, jsbundlePath, outFile } = options\n const workDir = options.workDir ?? dirname(jsbundlePath)\n mkdirSync(workDir, { recursive: true })\n mkdirSync(dirname(outFile), { recursive: true })\n\n console.warn(\"[react-native-gtkx] bundling for a single executable…\")\n const bundlePath = join(workDir, \"sea-bundle.cjs\")\n const nativeAddon = await bundleMetroSea({\n appRoot,\n jsbundlePath,\n outFile: bundlePath,\n })\n console.warn(`[react-native-gtkx] native addon: ${nativeAddon.path}`)\n\n const configPath = join(workDir, \"sea-config.json\")\n writeFileSync(\n configPath,\n `${JSON.stringify(\n {\n main: bundlePath,\n output: join(workDir, \"sea-prep.blob\"),\n disableExperimentalSEAWarning: true,\n assets: { [nativeAddon.key]: nativeAddon.path },\n },\n null,\n 2,\n )}\\n`,\n )\n\n console.warn(\"[react-native-gtkx] generating the SEA blob…\")\n run(process.execPath, [\"--experimental-sea-config\", configPath])\n\n console.warn(\"[react-native-gtkx] copying the node binary…\")\n copyFileSync(process.execPath, outFile)\n if (process.platform === \"darwin\") {\n // The copy inherits a signature that no longer matches once the blob\n // is injected; macOS refuses to exec it until the signature is gone.\n run(\"codesign\", [\"--remove-signature\", outFile])\n }\n stripSymbols(outFile)\n\n console.warn(\"[react-native-gtkx] injecting the SEA blob…\")\n run(\"npx\", [\n \"--yes\",\n \"--ignore-scripts\",\n POSTJECT,\n outFile,\n \"NODE_SEA_BLOB\",\n join(workDir, \"sea-prep.blob\"),\n \"--sentinel-fuse\",\n SENTINEL_FUSE,\n ])\n\n chmodSync(outFile, 0o755)\n return statSync(outFile).size\n}\n"]}
1
+ {"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../src/sea/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["// Turns a Metro-built app into ONE executable file: bundle everything into\n// a CJS entry (./bundle.ts), generate a SEA blob from it, then inject that\n// blob into a copy of the `node` binary. This is the whole of what \"SEA\"\n// means — Node's Single Executable Application format is literally a copy\n// of the node binary with a V8 code-cache blob appended, which is why the\n// result necessarily carries Node's own weight (~117 MB on linux-arm64,\n// against <7 MB for the app code and its native addon).\n//\n// Follows gtkx's own tutorial (gtkx-org/gtkx examples/tutorial/scripts/\n// build-sea.sh) for these mechanics; ./bundle.ts's header documents where\n// the bundling half deliberately diverges.\n//\n// Kept out of ../runner/index.ts and reached through a dynamic import so\n// the bundler is only loaded when a SEA is actually asked for; the\n// ordinary `build-linux` path never touches it.\nimport { spawnSync } from \"node:child_process\"\nimport {\n chmodSync,\n copyFileSync,\n mkdirSync,\n statSync,\n writeFileSync,\n} from \"node:fs\"\nimport { dirname, join } from \"node:path\"\nimport {\n BUNDLED_PACKAGES_FILENAME,\n bundleMetroSea,\n collectBundledPackages,\n renderBundledPackagesManifest,\n} from \"./bundle.js\"\n\n/** The fuse postject looks for inside the node binary to place the blob. */\nconst SENTINEL_FUSE = \"NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2\"\n\n/** Pinned: postject has no stable release, and the SEA docs name this one. */\nconst POSTJECT = \"postject@1.0.0-alpha.6\"\n\nexport type AssembleSeaOptions = {\n /** The app root — where gtkx.config.ts and package.json live. */\n appRoot: string\n /** The release jsbundle `build-linux` just wrote. */\n jsbundlePath: string\n /** Where the finished executable is written. */\n outFile: string\n /** Scratch directory for the intermediate CJS bundle, the SEA config and\n * the prep blob (default: alongside the jsbundle). */\n workDir?: string\n}\n\nconst run = (command: string, args: string[]): void => {\n const result = spawnSync(command, args, { stdio: \"inherit\" })\n if (result.error) {\n throw result.error\n }\n if (result.status !== 0) {\n throw new Error(`${command} ${args.join(\" \")} exited with ${result.status}`)\n }\n}\n\n/**\n * Drops the debug symbols from the copied Node binary. Worth a step of its\n * own because the saving is not marginal: the `node` binary distributed by\n * NodeSource for Ubuntu ships `with debug_info, not stripped` — measured at\n * 117 MB, and 98 MB after `strip --strip-all`. Nothing in a SEA needs those\n * symbols; the only cost is that a crash inside Node's own C++ produces an\n * unsymbolicated backtrace.\n *\n * Runs BEFORE postject, never after: `--strip-all` removes non-allocated\n * sections, which is exactly what the injected NODE_SEA_BLOB is.\n *\n * Best-effort — a build machine without binutils still produces a working\n * (larger) executable rather than failing, so this cannot become a new\n * install requirement for a build that worked yesterday.\n */\nconst stripSymbols = (file: string): void => {\n const before = statSync(file).size\n const result = spawnSync(\"strip\", [\"--strip-all\", file], {\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n })\n if (result.error || result.status !== 0) {\n console.warn(\n \"[react-native-gtkx] skipped stripping symbols (no usable `strip`) — \" +\n \"the executable will be tens of MB larger than it needs to be\",\n )\n return\n }\n const saved = (before - statSync(file).size) / 1024 / 1024\n console.warn(\n `[react-native-gtkx] stripped debug symbols (-${saved.toFixed(0)} MB)`,\n )\n}\n\n/**\n * Produces the middle artifact: one self-contained CJS file with the app,\n * its whole node_modules closure and the native addon inlined, run by a\n * system `node`. Everything the SEA is except the embedded Node runtime —\n * so ~120 MB smaller, at the cost of a `nodejs` dependency to declare.\n * Returns its size in bytes.\n *\n * `shouldWritePackageManifest` is for deploy-linux's own Metro-path staging\n * (../runner/index.ts): `gtkx deploy` requires a `gtkx-packages.json` inside\n * `dist/` before it will package anything, vite-built or not (its\n * third-party-notices step reads it unconditionally, --skip-build included)\n * — writing it here, from the real module graph this bundling step just\n * produced, is cheap and accurate; an ordinary `build-linux --standalone`\n * has no use for it, so it stays off by default.\n */\nexport const bundleStandalone = async (options: {\n appRoot: string\n jsbundlePath: string\n outFile: string\n shouldWritePackageManifest?: boolean\n}): Promise<number> => {\n const { appRoot, jsbundlePath, outFile } = options\n mkdirSync(dirname(outFile), { recursive: true })\n console.warn(\"[react-native-gtkx] bundling a standalone script…\")\n const { moduleIds } = await bundleMetroSea({\n appRoot,\n jsbundlePath,\n outFile,\n nativeAddonSource: \"inline\",\n })\n if (options.shouldWritePackageManifest) {\n const distDir = dirname(outFile)\n const packages = collectBundledPackages(moduleIds, distDir)\n writeFileSync(\n join(distDir, BUNDLED_PACKAGES_FILENAME),\n renderBundledPackagesManifest(packages),\n )\n }\n return statSync(outFile).size\n}\n\n/**\n * Produces a single executable at {@link AssembleSeaOptions.outFile} and\n * returns its size in bytes. Requires network access on first run unless\n * postject is already in the npx cache.\n */\nexport const assembleSea = async (\n options: AssembleSeaOptions,\n): Promise<number> => {\n const { appRoot, jsbundlePath, outFile } = options\n const workDir = options.workDir ?? dirname(jsbundlePath)\n mkdirSync(workDir, { recursive: true })\n mkdirSync(dirname(outFile), { recursive: true })\n\n console.warn(\"[react-native-gtkx] bundling for a single executable…\")\n const bundlePath = join(workDir, \"sea-bundle.cjs\")\n const { nativeAddon } = await bundleMetroSea({\n appRoot,\n jsbundlePath,\n outFile: bundlePath,\n })\n console.warn(`[react-native-gtkx] native addon: ${nativeAddon.path}`)\n\n const configPath = join(workDir, \"sea-config.json\")\n writeFileSync(\n configPath,\n `${JSON.stringify(\n {\n main: bundlePath,\n output: join(workDir, \"sea-prep.blob\"),\n disableExperimentalSEAWarning: true,\n assets: { [nativeAddon.key]: nativeAddon.path },\n },\n null,\n 2,\n )}\\n`,\n )\n\n console.warn(\"[react-native-gtkx] generating the SEA blob…\")\n run(process.execPath, [\"--experimental-sea-config\", configPath])\n\n console.warn(\"[react-native-gtkx] copying the node binary…\")\n copyFileSync(process.execPath, outFile)\n if (process.platform === \"darwin\") {\n // The copy inherits a signature that no longer matches once the blob\n // is injected; macOS refuses to exec it until the signature is gone.\n run(\"codesign\", [\"--remove-signature\", outFile])\n }\n stripSymbols(outFile)\n\n console.warn(\"[react-native-gtkx] injecting the SEA blob…\")\n run(\"npx\", [\n \"--yes\",\n \"--ignore-scripts\",\n POSTJECT,\n outFile,\n \"NODE_SEA_BLOB\",\n join(workDir, \"sea-prep.blob\"),\n \"--sentinel-fuse\",\n SENTINEL_FUSE,\n ])\n\n chmodSync(outFile, 0o755)\n return statSync(outFile).size\n}\n"]}
@@ -28,6 +28,35 @@ export type NativeAddonAsset = {
28
28
  * architecture with no error until the app actually launches.
29
29
  */
30
30
  export declare const resolveNativeAddon: (appRoot: string) => NativeAddonAsset;
31
+ /** One entry of the "which real npm package does this bundled code come
32
+ * from" manifest — see {@link collectBundledPackages}. */
33
+ export type BundledPackageRecord = {
34
+ name: string;
35
+ version: string | null;
36
+ /** Relative to whatever directory the manifest itself is written into. */
37
+ dir: string;
38
+ };
39
+ /** The exact filename `gtkx deploy`'s third-party-notices step reads —
40
+ * @gtkx/cli's own `gtkx:bundled-packages` vite plugin writes it as a build
41
+ * artifact of `gtkx build`, but is not part of @gtkx/cli's public API, so
42
+ * the name is duplicated here rather than imported (see
43
+ * @gtkx/cli/src/vite-plugins/bundled-packages.ts and
44
+ * src/deploy/notices/packages.ts for the two ends this mirrors). */
45
+ export declare const BUNDLED_PACKAGES_FILENAME = "gtkx-packages.json";
46
+ /**
47
+ * Mirrors @gtkx/cli's own `gtkx:bundled-packages` vite plugin: for every
48
+ * real module id rolldown pulled into the bundle, records which real npm
49
+ * package it came from (name/version, deduped, plus the package's real
50
+ * directory so `gtkx deploy`'s third-party-notices step can still read its
51
+ * LICENSE/copyright text later — same as it does for a vite build). `gtkx
52
+ * deploy --skip-build` requires this file to exist under `dist/` regardless
53
+ * of toolchain (its own build-skip check runs after this one), so the
54
+ * Metro deploy path needs a real, non-empty answer here, not a stub.
55
+ */
56
+ export declare const collectBundledPackages: (moduleIds: string[], distDir: string) => BundledPackageRecord[];
57
+ /** Renders {@link collectBundledPackages}' output in the exact shape
58
+ * @gtkx/cli's notice-reading side parses (`{ packages: [...] }`). */
59
+ export declare const renderBundledPackagesManifest: (packages: BundledPackageRecord[]) => string;
31
60
  /**
32
61
  * Builds the synthetic SEA entry source: every HOST_MODULE_EXTERNALS name
33
62
  * loaded through a dynamic `import()` (mirroring runner/host.ts's own
@@ -56,6 +85,12 @@ export declare const buildEntrySource: (jsbundlePath: string) => string;
56
85
  * HOST_MODULE_EXTERNALS and gtkx.config.ts's resolved values all inlined,
57
86
  * and the native addon import redirected to the SEA-asset extraction
58
87
  * shim. Returns the native addon that must be embedded as a SEA asset
59
- * under {@link NativeAddonAsset.key} for the result to run.
88
+ * under {@link NativeAddonAsset.key} for the result to run, plus the real
89
+ * module ids rolldown pulled into the bundle — {@link collectBundledPackages}
90
+ * turns those into the third-party-notices manifest a deploy needs (the
91
+ * ordinary --sea/--standalone paths ignore this half of the result).
60
92
  */
61
- export declare const bundleMetroSea: (options: MetroSeaBundleOptions) => Promise<NativeAddonAsset>;
93
+ export declare const bundleMetroSea: (options: MetroSeaBundleOptions) => Promise<{
94
+ nativeAddon: NativeAddonAsset;
95
+ moduleIds: string[];
96
+ }>;
@@ -48,7 +48,7 @@
48
48
  // import.meta.url no longer points at a file with real siblings on disk.
49
49
  import { mkdirSync, readdirSync, readFileSync } from "node:fs";
50
50
  import { createRequire } from "node:module";
51
- import { dirname, join } from "node:path";
51
+ import { dirname, join, relative } from "node:path";
52
52
  import { rolldown } from "rolldown";
53
53
  import { HOST_MODULE_EXTERNALS } from "../metro/index.js";
54
54
  import { buildGtkxConfigModule, virtualConfigModulePlugin, } from "./gtkx-config-module.js";
@@ -83,6 +83,73 @@ export const resolveNativeAddon = (appRoot) => {
83
83
  }
84
84
  return { path: first, key: NATIVE_ASSET_KEY };
85
85
  };
86
+ /** The exact filename `gtkx deploy`'s third-party-notices step reads —
87
+ * @gtkx/cli's own `gtkx:bundled-packages` vite plugin writes it as a build
88
+ * artifact of `gtkx build`, but is not part of @gtkx/cli's public API, so
89
+ * the name is duplicated here rather than imported (see
90
+ * @gtkx/cli/src/vite-plugins/bundled-packages.ts and
91
+ * src/deploy/notices/packages.ts for the two ends this mirrors). */
92
+ export const BUNDLED_PACKAGES_FILENAME = "gtkx-packages.json";
93
+ const stripQuery = (id) => id.split("?")[0] ?? id;
94
+ const packageIdentity = (dir) => {
95
+ try {
96
+ const parsed = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
97
+ if (typeof parsed !== "object" ||
98
+ parsed === null ||
99
+ Array.isArray(parsed)) {
100
+ return null;
101
+ }
102
+ const { name, version } = parsed;
103
+ if (typeof name !== "string") {
104
+ return null;
105
+ }
106
+ return { name, version: typeof version === "string" ? version : null };
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ };
112
+ /** Walks up from `dir` until a package.json with a usable "name" turns up —
113
+ * the same walk-to-nearest-manifest approach @gtkx/cli's vite plugin uses,
114
+ * so a module two directories deep inside a package (e.g. a package's own
115
+ * dist/esm/foo.js) still resolves to that package's own root. */
116
+ const packageContaining = (dir) => {
117
+ const identity = packageIdentity(dir);
118
+ if (identity !== null) {
119
+ return { ...identity, dir };
120
+ }
121
+ const parent = dirname(dir);
122
+ return parent === dir ? null : packageContaining(parent);
123
+ };
124
+ const packageForModule = (id) => {
125
+ const path = stripQuery(id);
126
+ return path.startsWith("/") ? packageContaining(dirname(path)) : null;
127
+ };
128
+ /**
129
+ * Mirrors @gtkx/cli's own `gtkx:bundled-packages` vite plugin: for every
130
+ * real module id rolldown pulled into the bundle, records which real npm
131
+ * package it came from (name/version, deduped, plus the package's real
132
+ * directory so `gtkx deploy`'s third-party-notices step can still read its
133
+ * LICENSE/copyright text later — same as it does for a vite build). `gtkx
134
+ * deploy --skip-build` requires this file to exist under `dist/` regardless
135
+ * of toolchain (its own build-skip check runs after this one), so the
136
+ * Metro deploy path needs a real, non-empty answer here, not a stub.
137
+ */
138
+ export const collectBundledPackages = (moduleIds, distDir) => {
139
+ const found = moduleIds
140
+ .map((id) => packageForModule(id))
141
+ .filter((entry) => entry !== null);
142
+ const unique = new Map();
143
+ for (const entry of found) {
144
+ unique.set(`${entry.name}@${entry.version ?? ""}`, entry);
145
+ }
146
+ return [...unique.values()]
147
+ .map((entry) => ({ ...entry, dir: relative(distDir, entry.dir) }))
148
+ .sort((a, b) => a.name.localeCompare(b.name));
149
+ };
150
+ /** Renders {@link collectBundledPackages}' output in the exact shape
151
+ * @gtkx/cli's notice-reading side parses (`{ packages: [...] }`). */
152
+ export const renderBundledPackagesManifest = (packages) => `${JSON.stringify({ packages }, null, 4)}\n`;
86
153
  /**
87
154
  * Builds the synthetic SEA entry source: every HOST_MODULE_EXTERNALS name
88
155
  * loaded through a dynamic `import()` (mirroring runner/host.ts's own
@@ -146,7 +213,10 @@ export const buildEntrySource = (jsbundlePath) => {
146
213
  * HOST_MODULE_EXTERNALS and gtkx.config.ts's resolved values all inlined,
147
214
  * and the native addon import redirected to the SEA-asset extraction
148
215
  * shim. Returns the native addon that must be embedded as a SEA asset
149
- * under {@link NativeAddonAsset.key} for the result to run.
216
+ * under {@link NativeAddonAsset.key} for the result to run, plus the real
217
+ * module ids rolldown pulled into the bundle — {@link collectBundledPackages}
218
+ * turns those into the third-party-notices manifest a deploy needs (the
219
+ * ordinary --sea/--standalone paths ignore this half of the result).
150
220
  */
151
221
  export const bundleMetroSea = async (options) => {
152
222
  const { appRoot, jsbundlePath, outFile } = options;
@@ -183,8 +253,9 @@ export const bundleMetroSea = async (options) => {
183
253
  virtualConfigModulePlugin(configModuleSource, appRoot),
184
254
  ],
185
255
  });
256
+ let output;
186
257
  try {
187
- await bundle.write({
258
+ output = await bundle.write({
188
259
  file: outFile,
189
260
  format: "cjs",
190
261
  minify: true,
@@ -197,6 +268,7 @@ export const bundleMetroSea = async (options) => {
197
268
  finally {
198
269
  await bundle.close();
199
270
  }
200
- return nativeAddon;
271
+ const moduleIds = output.output.flatMap((chunk) => chunk.type === "chunk" ? chunk.moduleIds : []);
272
+ return { nativeAddon, moduleIds };
201
273
  };
202
274
  //# sourceMappingURL=bundle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/sea/bundle.ts"],"names":[],"mappings":"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","sourcesContent":["// Bundles a Metro-built react-native-gtkx app (main.jsbundle) into a\n// single CJS file suitable for Node's --experimental-sea-config, undoing\n// exactly the externalization HOST_MODULE_EXTERNALS performs at Metro\n// build time.\n//\n// Design, and where this follows/diverges from gtkx's own tutorial\n// (gtkx-org/gtkx examples/tutorial/scripts/bundle.ts and\n// bundle-postject.ts — read before any of this was written):\n//\n// - Bundling mechanics (bundle → single minified CJS file) and the\n// SEA/postject pipeline itself (./assemble.ts) follow the tutorial\n// closely. The bundler is rolldown rather than the tutorial's esbuild —\n// NOT a preference: rolldown is vite's own engine (vite 8 depends on it\n// outright, esbuild is only an optional peer there), and vite is a hard\n// dependency of @gtkx/cli, which is a hard dependency of this package.\n// So rolldown is already installed for every consumer, and esbuild would\n// have been the one genuinely new bundler in the tree.\n// - Native addon: the tutorial's shim assumes the addon file sits BESIDE\n// the built executable (require resolved from\n// dirname(process.execPath)). That is two files, not one — the actual\n// central design decision this epic exists to make — so this diverges:\n// the addon is embedded IN the artifact (as a SEA asset, or as a base64\n// literal for the --standalone .cjs) and extracted to a per-user cache\n// directory on first run. See ./native-shim.ts's header for the full\n// reasoning.\n// - Metro's externals: the tutorial has no equivalent problem, its source\n// is already a single vite/rollup bundle. Metro deliberately\n// externalizes @gtkx/*, react and yoga-layout (../metro/index.ts,\n// HOST_MODULE_EXTERNALS) so main.jsbundle expects\n// globalThis.__hostModules/__hostRequire to exist before it runs (see\n// ../runner/host.ts). This module is a third host implementation\n// (host.ts and host-dev.ts are the other two — see host-dev.ts's header\n// for why they don't share code) that builds those globals from real,\n// STATICALLY imported modules — every name in HOST_MODULE_EXTERNALS\n// becomes a literal `import * as` statement in the generated entry — so\n// the bundler can inline them instead of the app needing a runtime\n// node_modules to dynamically load them from. gtkx.config.ts is also\n// resolved once here, at bundle time (see ./gtkx-config-module.ts).\n//\n// Not attempted here: the vite path. Investigated, not a drop-in of this\n// same technique — see docs/guide/packaging.md's \"Choosing an artifact\"\n// section for the concrete blocker found empirically while building this:\n// the vite bundle loads the native addon through a DYNAMICALLY obtained\n// require (`createRequire(import.meta.url)(\"./gtkx.node\")`), which a\n// bundler does not intercept the way it intercepts a static import\n// (verified: the resolve hook never fires for it), and which is unlikely\n// to resolve at all once running from inside a real SEA blob, where\n// import.meta.url no longer points at a file with real siblings on disk.\nimport { mkdirSync, readdirSync, readFileSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { dirname, join } from \"node:path\"\nimport { rolldown } from \"rolldown\"\nimport { HOST_MODULE_EXTERNALS } from \"../metro/index.js\"\nimport {\n buildGtkxConfigModule,\n virtualConfigModulePlugin,\n} from \"./gtkx-config-module.js\"\nimport {\n NATIVE_ASSET_KEY,\n nativeAddonShimPlugin,\n type NativeAddonSource,\n} from \"./native-shim.js\"\nimport { reactAnchorPlugin } from \"./react-anchor-plugin.js\"\n\nexport type MetroSeaBundleOptions = {\n /** The app root — where gtkx.config.ts lives and package.json resolves\n * HOST_MODULE_EXTERNALS' bare specifiers (react, @gtkx/*, ...) from. */\n appRoot: string\n /** Path to the release jsbundle produced by `build-linux`. */\n jsbundlePath: string\n /** Where to write the bundled CJS entry (e.g. dist/bundle.cjs). */\n outFile: string\n /** Where the native addon's bytes come from at runtime — \"sea-asset\"\n * for a real single executable, \"inline\" for a self-contained .cjs run\n * by a system Node (default: \"sea-asset\"). */\n nativeAddonSource?: NativeAddonSource\n}\n\nexport type NativeAddonAsset = {\n /** Absolute path to the platform's @gtkx/native-<platform>-<libc>.node\n * that npm installed for this machine. */\n path: string\n /** The SEA asset key it must be embedded under. */\n key: string\n}\n\n/**\n * Locates the ONE native addon file npm installed for this machine.\n * @gtkx/native picks exactly one optionalDependency per platform/libc at\n * install time (see @gtkx/native/index.js's NAPI-RS-generated loader) —\n * failing loudly on anything other than exactly one match matters here:\n * silently picking the wrong one would embed an addon for the wrong\n * architecture with no error until the app actually launches.\n */\nexport const resolveNativeAddon = (appRoot: string): NativeAddonAsset => {\n const appRequire = createRequire(join(appRoot, \"package.json\"))\n const nativePackageJson = appRequire.resolve(\"@gtkx/native/package.json\")\n // .../node_modules/@gtkx/native/package.json -> .../node_modules/@gtkx\n const scopeDir = dirname(dirname(nativePackageJson))\n const candidates = readdirSync(scopeDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && entry.name.startsWith(\"native-\"))\n .flatMap((entry) => {\n const dir = join(scopeDir, entry.name)\n return readdirSync(dir)\n .filter((file) => file.endsWith(\".node\"))\n .map((file) => join(dir, file))\n })\n const [first, ...rest] = candidates\n if (!first || rest.length > 0) {\n throw new Error(\n `expected exactly one @gtkx/native-*/*.node under ${scopeDir}, found ` +\n `${candidates.length} (${candidates.join(\", \") || \"none\"}) — ` +\n \"reinstall targeting a single platform.\",\n )\n }\n return { path: first, key: NATIVE_ASSET_KEY }\n}\n\n/**\n * Builds the synthetic SEA entry source: every HOST_MODULE_EXTERNALS name\n * loaded through a dynamic `import()` (mirroring runner/host.ts's own\n * `load()`, which does the same against a real node_modules at runtime),\n * assembled into globalThis.__hostModules, then the jsbundle text executed\n * the same way host.ts does.\n *\n * Dynamic import, not static, throughout: a Node SEA's main script is\n * CommonJS only — confirmed empirically, Node 24 executes the embedded\n * main as CJS regardless of a \"type\": \"module\" field in sea-config.json\n * or an .mjs extension — and top-level await is a hard error under a \"cjs\"\n * output format REGARDLESS of whether the module is reached via a static\n * or dynamic import (the restriction is format-wide, not per-module —\n * verified: switching yoga-layout's static import to a dynamic one alone\n * did not clear the error). yoga-layout's own entry point has exactly this\n * top-level await (it loads its WASM binary asynchronously — see\n * node_modules/yoga-layout/dist/src/index.js: `const Yoga =\n * wrapAssembly(await loadYoga())` at module scope). The actual fix: import\n * \"yoga-layout/load\" instead, which exports the same `await`, just inside\n * an async FUNCTION (`export async function loadYoga()`), not at the\n * file's top level — bundleable, and awaited here like everything else.\n */\nexport const buildEntrySource = (jsbundlePath: string): string => {\n const jsbundleSource = readFileSync(jsbundlePath, \"utf8\")\n const loadLines = HOST_MODULE_EXTERNALS.map((name) => {\n if (name === \"yoga-layout\") {\n return [\n ` {`,\n ` const { loadYoga, ...rest } = await import(\"yoga-layout/load\");`,\n ` hostModules[\"yoga-layout\"] = __interopHostModule({ ...rest, default: await loadYoga() });`,\n ` }`,\n ].join(\"\\n\")\n }\n return ` hostModules[${JSON.stringify(name)}] = __interopHostModule(await import(${JSON.stringify(name)}));`\n })\n return [\n `async function __gtkxSeaMain() {`,\n // Mirrors runner/host.ts's `load()` interop: import() handles both ESM\n // and CJS, merge a `default` for Babel's default-import interop when\n // the module has none of its own.\n ` const __interopHostModule = (ns) => {`,\n ` const merged = Object.assign({ __esModule: true }, ns);`,\n ` if (!(\"default\" in ns)) merged.default = ns;`,\n ` return merged;`,\n ` };`,\n ` const hostModules = {};`,\n ...loadLines,\n ` globalThis.__hostModules = hostModules;`,\n // Node builtin proxies resolve lazily through the host's own require —\n // real here, no createRequire indirection needed (see host.ts for why\n // it needs one: this file's import.meta.url is never used for\n // anything relative, only require() of bare/builtin specifiers).\n ` globalThis.__hostRequire = require;`,\n ` require(\"node:vm\").runInThisContext(${JSON.stringify(jsbundleSource)}, { filename: ${JSON.stringify(jsbundlePath)} });`,\n `}`,\n `__gtkxSeaMain().catch((error) => { console.error(error); process.exitCode = 1; });`,\n ].join(\"\\n\")\n}\n\n/**\n * Produces `outFile`, a single CJS file with the jsbundle, its\n * HOST_MODULE_EXTERNALS and gtkx.config.ts's resolved values all inlined,\n * and the native addon import redirected to the SEA-asset extraction\n * shim. Returns the native addon that must be embedded as a SEA asset\n * under {@link NativeAddonAsset.key} for the result to run.\n */\nexport const bundleMetroSea = async (\n options: MetroSeaBundleOptions,\n): Promise<NativeAddonAsset> => {\n const { appRoot, jsbundlePath, outFile } = options\n const nativeAddonSource = options.nativeAddonSource ?? \"sea-asset\"\n const configModuleSource = await buildGtkxConfigModule(appRoot)\n const nativeAddon = resolveNativeAddon(appRoot)\n const entrySource = buildEntrySource(jsbundlePath)\n\n mkdirSync(dirname(outFile), { recursive: true })\n\n // The entry is given a path inside appRoot that does not exist on disk,\n // rather than a `\\0`-prefixed virtual id: every bare specifier it\n // imports (react, @gtkx/*, yoga-layout) must resolve from the app's own\n // node_modules, and a real directory is what makes that happen.\n const entryId = join(appRoot, \"__gtkx-sea-entry.js\")\n\n const bundle = await rolldown({\n input: entryId,\n cwd: appRoot,\n platform: \"node\",\n plugins: [\n {\n name: \"gtkx-sea-entry\",\n resolveId: (source) => (source === entryId ? entryId : null),\n load: (id) => (id === entryId ? entrySource : null),\n },\n reactAnchorPlugin(appRoot),\n nativeAddonShimPlugin({\n specifier: \"@gtkx/native\",\n appRoot,\n source: nativeAddonSource,\n assetKey: nativeAddon.key,\n addonBytes:\n nativeAddonSource === \"inline\"\n ? readFileSync(nativeAddon.path)\n : undefined,\n }),\n virtualConfigModulePlugin(configModuleSource, appRoot),\n ],\n })\n try {\n await bundle.write({\n file: outFile,\n format: \"cjs\",\n minify: true,\n // Every HOST_MODULE_EXTERNALS name is reached through a dynamic\n // import; without this each one becomes its own chunk and the\n // \"single file\" the whole build exists to produce is a directory.\n codeSplitting: false,\n })\n } finally {\n await bundle.close()\n }\n\n return nativeAddon\n}\n"]}
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/sea/bundle.ts"],"names":[],"mappings":"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","sourcesContent":["// Bundles a Metro-built react-native-gtkx app (main.jsbundle) into a\n// single CJS file suitable for Node's --experimental-sea-config, undoing\n// exactly the externalization HOST_MODULE_EXTERNALS performs at Metro\n// build time.\n//\n// Design, and where this follows/diverges from gtkx's own tutorial\n// (gtkx-org/gtkx examples/tutorial/scripts/bundle.ts and\n// bundle-postject.ts — read before any of this was written):\n//\n// - Bundling mechanics (bundle → single minified CJS file) and the\n// SEA/postject pipeline itself (./assemble.ts) follow the tutorial\n// closely. The bundler is rolldown rather than the tutorial's esbuild —\n// NOT a preference: rolldown is vite's own engine (vite 8 depends on it\n// outright, esbuild is only an optional peer there), and vite is a hard\n// dependency of @gtkx/cli, which is a hard dependency of this package.\n// So rolldown is already installed for every consumer, and esbuild would\n// have been the one genuinely new bundler in the tree.\n// - Native addon: the tutorial's shim assumes the addon file sits BESIDE\n// the built executable (require resolved from\n// dirname(process.execPath)). That is two files, not one — the actual\n// central design decision this epic exists to make — so this diverges:\n// the addon is embedded IN the artifact (as a SEA asset, or as a base64\n// literal for the --standalone .cjs) and extracted to a per-user cache\n// directory on first run. See ./native-shim.ts's header for the full\n// reasoning.\n// - Metro's externals: the tutorial has no equivalent problem, its source\n// is already a single vite/rollup bundle. Metro deliberately\n// externalizes @gtkx/*, react and yoga-layout (../metro/index.ts,\n// HOST_MODULE_EXTERNALS) so main.jsbundle expects\n// globalThis.__hostModules/__hostRequire to exist before it runs (see\n// ../runner/host.ts). This module is a third host implementation\n// (host.ts and host-dev.ts are the other two — see host-dev.ts's header\n// for why they don't share code) that builds those globals from real,\n// STATICALLY imported modules — every name in HOST_MODULE_EXTERNALS\n// becomes a literal `import * as` statement in the generated entry — so\n// the bundler can inline them instead of the app needing a runtime\n// node_modules to dynamically load them from. gtkx.config.ts is also\n// resolved once here, at bundle time (see ./gtkx-config-module.ts).\n//\n// Not attempted here: the vite path. Investigated, not a drop-in of this\n// same technique — see docs/guide/packaging.md's \"Choosing an artifact\"\n// section for the concrete blocker found empirically while building this:\n// the vite bundle loads the native addon through a DYNAMICALLY obtained\n// require (`createRequire(import.meta.url)(\"./gtkx.node\")`), which a\n// bundler does not intercept the way it intercepts a static import\n// (verified: the resolve hook never fires for it), and which is unlikely\n// to resolve at all once running from inside a real SEA blob, where\n// import.meta.url no longer points at a file with real siblings on disk.\nimport { mkdirSync, readdirSync, readFileSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\nimport { dirname, join, relative } from \"node:path\"\nimport { rolldown, type RolldownOutput } from \"rolldown\"\nimport { HOST_MODULE_EXTERNALS } from \"../metro/index.js\"\nimport {\n buildGtkxConfigModule,\n virtualConfigModulePlugin,\n} from \"./gtkx-config-module.js\"\nimport {\n NATIVE_ASSET_KEY,\n nativeAddonShimPlugin,\n type NativeAddonSource,\n} from \"./native-shim.js\"\nimport { reactAnchorPlugin } from \"./react-anchor-plugin.js\"\n\nexport type MetroSeaBundleOptions = {\n /** The app root — where gtkx.config.ts lives and package.json resolves\n * HOST_MODULE_EXTERNALS' bare specifiers (react, @gtkx/*, ...) from. */\n appRoot: string\n /** Path to the release jsbundle produced by `build-linux`. */\n jsbundlePath: string\n /** Where to write the bundled CJS entry (e.g. dist/bundle.cjs). */\n outFile: string\n /** Where the native addon's bytes come from at runtime — \"sea-asset\"\n * for a real single executable, \"inline\" for a self-contained .cjs run\n * by a system Node (default: \"sea-asset\"). */\n nativeAddonSource?: NativeAddonSource\n}\n\nexport type NativeAddonAsset = {\n /** Absolute path to the platform's @gtkx/native-<platform>-<libc>.node\n * that npm installed for this machine. */\n path: string\n /** The SEA asset key it must be embedded under. */\n key: string\n}\n\n/**\n * Locates the ONE native addon file npm installed for this machine.\n * @gtkx/native picks exactly one optionalDependency per platform/libc at\n * install time (see @gtkx/native/index.js's NAPI-RS-generated loader) —\n * failing loudly on anything other than exactly one match matters here:\n * silently picking the wrong one would embed an addon for the wrong\n * architecture with no error until the app actually launches.\n */\nexport const resolveNativeAddon = (appRoot: string): NativeAddonAsset => {\n const appRequire = createRequire(join(appRoot, \"package.json\"))\n const nativePackageJson = appRequire.resolve(\"@gtkx/native/package.json\")\n // .../node_modules/@gtkx/native/package.json -> .../node_modules/@gtkx\n const scopeDir = dirname(dirname(nativePackageJson))\n const candidates = readdirSync(scopeDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && entry.name.startsWith(\"native-\"))\n .flatMap((entry) => {\n const dir = join(scopeDir, entry.name)\n return readdirSync(dir)\n .filter((file) => file.endsWith(\".node\"))\n .map((file) => join(dir, file))\n })\n const [first, ...rest] = candidates\n if (!first || rest.length > 0) {\n throw new Error(\n `expected exactly one @gtkx/native-*/*.node under ${scopeDir}, found ` +\n `${candidates.length} (${candidates.join(\", \") || \"none\"}) — ` +\n \"reinstall targeting a single platform.\",\n )\n }\n return { path: first, key: NATIVE_ASSET_KEY }\n}\n\n/** One entry of the \"which real npm package does this bundled code come\n * from\" manifest — see {@link collectBundledPackages}. */\nexport type BundledPackageRecord = {\n name: string\n version: string | null\n /** Relative to whatever directory the manifest itself is written into. */\n dir: string\n}\n\n/** The exact filename `gtkx deploy`'s third-party-notices step reads —\n * @gtkx/cli's own `gtkx:bundled-packages` vite plugin writes it as a build\n * artifact of `gtkx build`, but is not part of @gtkx/cli's public API, so\n * the name is duplicated here rather than imported (see\n * @gtkx/cli/src/vite-plugins/bundled-packages.ts and\n * src/deploy/notices/packages.ts for the two ends this mirrors). */\nexport const BUNDLED_PACKAGES_FILENAME = \"gtkx-packages.json\"\n\nconst stripQuery = (id: string): string => id.split(\"?\")[0] ?? id\n\nconst packageIdentity = (\n dir: string,\n): { name: string; version: string | null } | null => {\n try {\n const parsed: unknown = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n )\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n Array.isArray(parsed)\n ) {\n return null\n }\n const { name, version } = parsed as { name?: unknown; version?: unknown }\n if (typeof name !== \"string\") {\n return null\n }\n return { name, version: typeof version === \"string\" ? version : null }\n } catch {\n return null\n }\n}\n\n/** Walks up from `dir` until a package.json with a usable \"name\" turns up —\n * the same walk-to-nearest-manifest approach @gtkx/cli's vite plugin uses,\n * so a module two directories deep inside a package (e.g. a package's own\n * dist/esm/foo.js) still resolves to that package's own root. */\nconst packageContaining = (dir: string): BundledPackageRecord | null => {\n const identity = packageIdentity(dir)\n if (identity !== null) {\n return { ...identity, dir }\n }\n const parent = dirname(dir)\n return parent === dir ? null : packageContaining(parent)\n}\n\nconst packageForModule = (id: string): BundledPackageRecord | null => {\n const path = stripQuery(id)\n return path.startsWith(\"/\") ? packageContaining(dirname(path)) : null\n}\n\n/**\n * Mirrors @gtkx/cli's own `gtkx:bundled-packages` vite plugin: for every\n * real module id rolldown pulled into the bundle, records which real npm\n * package it came from (name/version, deduped, plus the package's real\n * directory so `gtkx deploy`'s third-party-notices step can still read its\n * LICENSE/copyright text later — same as it does for a vite build). `gtkx\n * deploy --skip-build` requires this file to exist under `dist/` regardless\n * of toolchain (its own build-skip check runs after this one), so the\n * Metro deploy path needs a real, non-empty answer here, not a stub.\n */\nexport const collectBundledPackages = (\n moduleIds: string[],\n distDir: string,\n): BundledPackageRecord[] => {\n const found = moduleIds\n .map((id) => packageForModule(id))\n .filter((entry): entry is BundledPackageRecord => entry !== null)\n const unique = new Map<string, BundledPackageRecord>()\n for (const entry of found) {\n unique.set(`${entry.name}@${entry.version ?? \"\"}`, entry)\n }\n return [...unique.values()]\n .map((entry) => ({ ...entry, dir: relative(distDir, entry.dir) }))\n .sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/** Renders {@link collectBundledPackages}' output in the exact shape\n * @gtkx/cli's notice-reading side parses (`{ packages: [...] }`). */\nexport const renderBundledPackagesManifest = (\n packages: BundledPackageRecord[],\n): string => `${JSON.stringify({ packages }, null, 4)}\\n`\n\n/**\n * Builds the synthetic SEA entry source: every HOST_MODULE_EXTERNALS name\n * loaded through a dynamic `import()` (mirroring runner/host.ts's own\n * `load()`, which does the same against a real node_modules at runtime),\n * assembled into globalThis.__hostModules, then the jsbundle text executed\n * the same way host.ts does.\n *\n * Dynamic import, not static, throughout: a Node SEA's main script is\n * CommonJS only — confirmed empirically, Node 24 executes the embedded\n * main as CJS regardless of a \"type\": \"module\" field in sea-config.json\n * or an .mjs extension — and top-level await is a hard error under a \"cjs\"\n * output format REGARDLESS of whether the module is reached via a static\n * or dynamic import (the restriction is format-wide, not per-module —\n * verified: switching yoga-layout's static import to a dynamic one alone\n * did not clear the error). yoga-layout's own entry point has exactly this\n * top-level await (it loads its WASM binary asynchronously — see\n * node_modules/yoga-layout/dist/src/index.js: `const Yoga =\n * wrapAssembly(await loadYoga())` at module scope). The actual fix: import\n * \"yoga-layout/load\" instead, which exports the same `await`, just inside\n * an async FUNCTION (`export async function loadYoga()`), not at the\n * file's top level — bundleable, and awaited here like everything else.\n */\nexport const buildEntrySource = (jsbundlePath: string): string => {\n const jsbundleSource = readFileSync(jsbundlePath, \"utf8\")\n const loadLines = HOST_MODULE_EXTERNALS.map((name) => {\n if (name === \"yoga-layout\") {\n return [\n ` {`,\n ` const { loadYoga, ...rest } = await import(\"yoga-layout/load\");`,\n ` hostModules[\"yoga-layout\"] = __interopHostModule({ ...rest, default: await loadYoga() });`,\n ` }`,\n ].join(\"\\n\")\n }\n return ` hostModules[${JSON.stringify(name)}] = __interopHostModule(await import(${JSON.stringify(name)}));`\n })\n return [\n `async function __gtkxSeaMain() {`,\n // Mirrors runner/host.ts's `load()` interop: import() handles both ESM\n // and CJS, merge a `default` for Babel's default-import interop when\n // the module has none of its own.\n ` const __interopHostModule = (ns) => {`,\n ` const merged = Object.assign({ __esModule: true }, ns);`,\n ` if (!(\"default\" in ns)) merged.default = ns;`,\n ` return merged;`,\n ` };`,\n ` const hostModules = {};`,\n ...loadLines,\n ` globalThis.__hostModules = hostModules;`,\n // Node builtin proxies resolve lazily through the host's own require —\n // real here, no createRequire indirection needed (see host.ts for why\n // it needs one: this file's import.meta.url is never used for\n // anything relative, only require() of bare/builtin specifiers).\n ` globalThis.__hostRequire = require;`,\n ` require(\"node:vm\").runInThisContext(${JSON.stringify(jsbundleSource)}, { filename: ${JSON.stringify(jsbundlePath)} });`,\n `}`,\n `__gtkxSeaMain().catch((error) => { console.error(error); process.exitCode = 1; });`,\n ].join(\"\\n\")\n}\n\n/**\n * Produces `outFile`, a single CJS file with the jsbundle, its\n * HOST_MODULE_EXTERNALS and gtkx.config.ts's resolved values all inlined,\n * and the native addon import redirected to the SEA-asset extraction\n * shim. Returns the native addon that must be embedded as a SEA asset\n * under {@link NativeAddonAsset.key} for the result to run, plus the real\n * module ids rolldown pulled into the bundle — {@link collectBundledPackages}\n * turns those into the third-party-notices manifest a deploy needs (the\n * ordinary --sea/--standalone paths ignore this half of the result).\n */\nexport const bundleMetroSea = async (\n options: MetroSeaBundleOptions,\n): Promise<{ nativeAddon: NativeAddonAsset; moduleIds: string[] }> => {\n const { appRoot, jsbundlePath, outFile } = options\n const nativeAddonSource = options.nativeAddonSource ?? \"sea-asset\"\n const configModuleSource = await buildGtkxConfigModule(appRoot)\n const nativeAddon = resolveNativeAddon(appRoot)\n const entrySource = buildEntrySource(jsbundlePath)\n\n mkdirSync(dirname(outFile), { recursive: true })\n\n // The entry is given a path inside appRoot that does not exist on disk,\n // rather than a `\\0`-prefixed virtual id: every bare specifier it\n // imports (react, @gtkx/*, yoga-layout) must resolve from the app's own\n // node_modules, and a real directory is what makes that happen.\n const entryId = join(appRoot, \"__gtkx-sea-entry.js\")\n\n const bundle = await rolldown({\n input: entryId,\n cwd: appRoot,\n platform: \"node\",\n plugins: [\n {\n name: \"gtkx-sea-entry\",\n resolveId: (source) => (source === entryId ? entryId : null),\n load: (id) => (id === entryId ? entrySource : null),\n },\n reactAnchorPlugin(appRoot),\n nativeAddonShimPlugin({\n specifier: \"@gtkx/native\",\n appRoot,\n source: nativeAddonSource,\n assetKey: nativeAddon.key,\n addonBytes:\n nativeAddonSource === \"inline\"\n ? readFileSync(nativeAddon.path)\n : undefined,\n }),\n virtualConfigModulePlugin(configModuleSource, appRoot),\n ],\n })\n let output: RolldownOutput\n try {\n output = await bundle.write({\n file: outFile,\n format: \"cjs\",\n minify: true,\n // Every HOST_MODULE_EXTERNALS name is reached through a dynamic\n // import; without this each one becomes its own chunk and the\n // \"single file\" the whole build exists to produce is a directory.\n codeSplitting: false,\n })\n } finally {\n await bundle.close()\n }\n\n const moduleIds = output.output.flatMap((chunk) =>\n chunk.type === \"chunk\" ? chunk.moduleIds : [],\n )\n\n return { nativeAddon, moduleIds }\n}\n"]}
@@ -81,7 +81,7 @@ if (!target) {
81
81
  // proven by both artifacts beats two, one of which is rarely exercised.
82
82
  const nativeModule = { exports: {} };
83
83
  process.dlopen(nativeModule, target);
84
- // The vite path's own build (dist/bundle.js, gtkx's CLI plugin) calls
84
+ // The vite path's own build (dist/bundle.mjs, gtkx's CLI plugin) calls
85
85
  // this immediately after loading the addon, before anything else touches
86
86
  // it; @gtkx/runtime's compiled JS never calls it itself (confirmed by
87
87
  // inspecting its dist — it only re-exports a handful of low-level