filly 0.2.0__tar.gz → 0.2.1__tar.gz

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 (180) hide show
  1. {filly-0.2.0 → filly-0.2.1}/.github/workflows/wheels.yml +10 -10
  2. {filly-0.2.0 → filly-0.2.1}/PKG-INFO +1 -1
  3. {filly-0.2.0 → filly-0.2.1}/docs/explanation/web.md +4 -0
  4. {filly-0.2.0 → filly-0.2.1}/pyproject.toml +1 -1
  5. {filly-0.2.0 → filly-0.2.1}/tests/test_web.py +20 -6
  6. {filly-0.2.0 → filly-0.2.1}/tests/web/run_page.mjs +10 -5
  7. {filly-0.2.0 → filly-0.2.1}/web/filly.js +31 -2
  8. {filly-0.2.0 → filly-0.2.1}/.gitignore +0 -0
  9. {filly-0.2.0 → filly-0.2.1}/CMakeLists.txt +0 -0
  10. {filly-0.2.0 → filly-0.2.1}/LICENSE +0 -0
  11. {filly-0.2.0 → filly-0.2.1}/NOTES.md +0 -0
  12. {filly-0.2.0 → filly-0.2.1}/README.md +0 -0
  13. {filly-0.2.0 → filly-0.2.1}/docs/explanation/assumptions.md +0 -0
  14. {filly-0.2.0 → filly-0.2.1}/docs/explanation/design.md +0 -0
  15. {filly-0.2.0 → filly-0.2.1}/docs/explanation/filament.md +0 -0
  16. {filly-0.2.0 → filly-0.2.1}/docs/explanation/material-precompilation.md +0 -0
  17. {filly-0.2.0 → filly-0.2.1}/docs/how-to/build.md +0 -0
  18. {filly-0.2.0 → filly-0.2.1}/docs/how-to/gl-hosts.md +0 -0
  19. {filly-0.2.0 → filly-0.2.1}/docs/how-to/profile.md +0 -0
  20. {filly-0.2.0 → filly-0.2.1}/docs/how-to/psychopy.md +0 -0
  21. {filly-0.2.0 → filly-0.2.1}/docs/how-to/reference-comparison.md +0 -0
  22. {filly-0.2.0 → filly-0.2.1}/docs/how-to/stress-test.md +0 -0
  23. {filly-0.2.0 → filly-0.2.1}/docs/how-to/web.md +0 -0
  24. {filly-0.2.0 → filly-0.2.1}/docs/images/README.md +0 -0
  25. {filly-0.2.0 → filly-0.2.1}/docs/images/amber-orthographic.png +0 -0
  26. {filly-0.2.0 → filly-0.2.1}/docs/images/amber-perspective.png +0 -0
  27. {filly-0.2.0 → filly-0.2.1}/docs/images/horse.gif +0 -0
  28. {filly-0.2.0 → filly-0.2.1}/docs/images/horse.png +0 -0
  29. {filly-0.2.0 → filly-0.2.1}/docs/images/iridescence-environment.png +0 -0
  30. {filly-0.2.0 → filly-0.2.1}/docs/images/iridescence-studio.png +0 -0
  31. {filly-0.2.0 → filly-0.2.1}/docs/reference/api.md +0 -0
  32. {filly-0.2.0 → filly-0.2.1}/docs/reference/performance.md +0 -0
  33. {filly-0.2.0 → filly-0.2.1}/docs/reference/sample-assets.csv +0 -0
  34. {filly-0.2.0 → filly-0.2.1}/docs/reference/sample-assets.md +0 -0
  35. {filly-0.2.0 → filly-0.2.1}/docs/reference/upstream-issues.md +0 -0
  36. {filly-0.2.0 → filly-0.2.1}/docs/reference/validation.md +0 -0
  37. {filly-0.2.0 → filly-0.2.1}/docs/tutorials/offscreen.md +0 -0
  38. {filly-0.2.0 → filly-0.2.1}/examples/assets/ATTRIBUTION.md +0 -0
  39. {filly-0.2.0 → filly-0.2.1}/examples/assets/wooden_playground_horse.glb +0 -0
  40. {filly-0.2.0 → filly-0.2.1}/examples/drifting_grating.py +0 -0
  41. {filly-0.2.0 → filly-0.2.1}/examples/moderngl_shared.py +0 -0
  42. {filly-0.2.0 → filly-0.2.1}/examples/pick.py +0 -0
  43. {filly-0.2.0 → filly-0.2.1}/examples/psychopy_shared.py +0 -0
  44. {filly-0.2.0 → filly-0.2.1}/examples/psychopy_stress.py +0 -0
  45. {filly-0.2.0 → filly-0.2.1}/examples/pyglet_shared.py +0 -0
  46. {filly-0.2.0 → filly-0.2.1}/examples/screenshot.py +0 -0
  47. {filly-0.2.0 → filly-0.2.1}/examples/shapes.py +0 -0
  48. {filly-0.2.0 → filly-0.2.1}/examples/stereo.py +0 -0
  49. {filly-0.2.0 → filly-0.2.1}/examples/zengl_shared.py +0 -0
  50. {filly-0.2.0 → filly-0.2.1}/native/animation.inc +0 -0
  51. {filly-0.2.0 → filly-0.2.1}/native/archive_materials.cpp +0 -0
  52. {filly-0.2.0 → filly-0.2.1}/native/bindings.cpp +0 -0
  53. {filly-0.2.0 → filly-0.2.1}/native/egl_platform.cpp +0 -0
  54. {filly-0.2.0 → filly-0.2.1}/native/egl_platform.h +0 -0
  55. {filly-0.2.0 → filly-0.2.1}/native/engine_config.h +0 -0
  56. {filly-0.2.0 → filly-0.2.1}/native/features.inc +0 -0
  57. {filly-0.2.0 → filly-0.2.1}/native/gl_interop.cpp +0 -0
  58. {filly-0.2.0 → filly-0.2.1}/native/gl_interop.h +0 -0
  59. {filly-0.2.0 → filly-0.2.1}/native/gl_interop_web.cpp +0 -0
  60. {filly-0.2.0 → filly-0.2.1}/native/gltf_prepare.cpp +0 -0
  61. {filly-0.2.0 → filly-0.2.1}/native/gltf_prepare.h +0 -0
  62. {filly-0.2.0 → filly-0.2.1}/native/json.cpp +0 -0
  63. {filly-0.2.0 → filly-0.2.1}/native/json.h +0 -0
  64. {filly-0.2.0 → filly-0.2.1}/native/libwebp.cmake +0 -0
  65. {filly-0.2.0 → filly-0.2.1}/native/materials/check_refraction.cmake +0 -0
  66. {filly-0.2.0 → filly-0.2.1}/native/materials/diffuse_transmission.mat.in +0 -0
  67. {filly-0.2.0 → filly-0.2.1}/native/materials/embed.cmake +0 -0
  68. {filly-0.2.0 → filly-0.2.1}/native/materials/encode.mat.in +0 -0
  69. {filly-0.2.0 → filly-0.2.1}/native/materials/fxaa.mat +0 -0
  70. {filly-0.2.0 → filly-0.2.1}/native/materials/materials.cmake +0 -0
  71. {filly-0.2.0 → filly-0.2.1}/native/materials/output.cmake +0 -0
  72. {filly-0.2.0 → filly-0.2.1}/native/materials/specular_glossiness.mat.in +0 -0
  73. {filly-0.2.0 → filly-0.2.1}/native/materials/surface.mat.in +0 -0
  74. {filly-0.2.0 → filly-0.2.1}/native/materials/unlit.mat.in +0 -0
  75. {filly-0.2.0 → filly-0.2.1}/native/materials.h +0 -0
  76. {filly-0.2.0 → filly-0.2.1}/native/memory.inc +0 -0
  77. {filly-0.2.0 → filly-0.2.1}/native/output_pass.cpp +0 -0
  78. {filly-0.2.0 → filly-0.2.1}/native/output_pass.h +0 -0
  79. {filly-0.2.0 → filly-0.2.1}/native/refraction.h +0 -0
  80. {filly-0.2.0 → filly-0.2.1}/native/renderer.cpp +0 -0
  81. {filly-0.2.0 → filly-0.2.1}/native/renderer.h +0 -0
  82. {filly-0.2.0 → filly-0.2.1}/native/resources.inc +0 -0
  83. {filly-0.2.0 → filly-0.2.1}/native/shapes.cpp +0 -0
  84. {filly-0.2.0 → filly-0.2.1}/native/slots.inc +0 -0
  85. {filly-0.2.0 → filly-0.2.1}/native/vendor/cgltf/LICENSE +0 -0
  86. {filly-0.2.0 → filly-0.2.1}/native/vendor/cgltf/README.md +0 -0
  87. {filly-0.2.0 → filly-0.2.1}/native/vendor/cgltf/cgltf.h +0 -0
  88. {filly-0.2.0 → filly-0.2.1}/native/vendor/meshoptimizer/LICENSE.md +0 -0
  89. {filly-0.2.0 → filly-0.2.1}/native/vendor/meshoptimizer/README.md +0 -0
  90. {filly-0.2.0 → filly-0.2.1}/native/vendor/meshoptimizer/indexcodec.cpp +0 -0
  91. {filly-0.2.0 → filly-0.2.1}/native/vendor/meshoptimizer/meshoptimizer.h +0 -0
  92. {filly-0.2.0 → filly-0.2.1}/native/vendor/meshoptimizer/vertexcodec.cpp +0 -0
  93. {filly-0.2.0 → filly-0.2.1}/native/vendor/meshoptimizer/vertexfilter.cpp +0 -0
  94. {filly-0.2.0 → filly-0.2.1}/native/webp_provider.cpp +0 -0
  95. {filly-0.2.0 → filly-0.2.1}/native/webp_provider.h +0 -0
  96. {filly-0.2.0 → filly-0.2.1}/spec.md +0 -0
  97. {filly-0.2.0 → filly-0.2.1}/src/filly/__init__.py +0 -0
  98. {filly-0.2.0 → filly-0.2.1}/src/filly/_memory.py +0 -0
  99. {filly-0.2.0 → filly-0.2.1}/src/filly/_stress.py +0 -0
  100. {filly-0.2.0 → filly-0.2.1}/src/filly/benchmark.py +0 -0
  101. {filly-0.2.0 → filly-0.2.1}/src/filly/integrations/__init__.py +0 -0
  102. {filly-0.2.0 → filly-0.2.1}/src/filly/integrations/_host.py +0 -0
  103. {filly-0.2.0 → filly-0.2.1}/src/filly/integrations/moderngl.py +0 -0
  104. {filly-0.2.0 → filly-0.2.1}/src/filly/integrations/psychopy.py +0 -0
  105. {filly-0.2.0 → filly-0.2.1}/src/filly/integrations/pyglet.py +0 -0
  106. {filly-0.2.0 → filly-0.2.1}/src/filly/integrations/zengl.py +0 -0
  107. {filly-0.2.0 → filly-0.2.1}/src/filly/samples/ATTRIBUTION.md +0 -0
  108. {filly-0.2.0 → filly-0.2.1}/src/filly/samples/__init__.py +0 -0
  109. {filly-0.2.0 → filly-0.2.1}/src/filly/samples/suzanne.glb +0 -0
  110. {filly-0.2.0 → filly-0.2.1}/tests/conftest.py +0 -0
  111. {filly-0.2.0 → filly-0.2.1}/tests/data/README.md +0 -0
  112. {filly-0.2.0 → filly-0.2.1}/tests/data/box/Box.gltf +0 -0
  113. {filly-0.2.0 → filly-0.2.1}/tests/data/box/Box0.bin +0 -0
  114. {filly-0.2.0 → filly-0.2.1}/tests/data/draco-box/Box.bin +0 -0
  115. {filly-0.2.0 → filly-0.2.1}/tests/data/draco-box/Box.gltf +0 -0
  116. {filly-0.2.0 → filly-0.2.1}/tests/data/green.ktx2 +0 -0
  117. {filly-0.2.0 → filly-0.2.1}/tests/data/green.webp +0 -0
  118. {filly-0.2.0 → filly-0.2.1}/tests/data/quadrants.webp +0 -0
  119. {filly-0.2.0 → filly-0.2.1}/tests/test_animation_pointer.py +0 -0
  120. {filly-0.2.0 → filly-0.2.1}/tests/test_asset.py +0 -0
  121. {filly-0.2.0 → filly-0.2.1}/tests/test_camera_aspect.py +0 -0
  122. {filly-0.2.0 → filly-0.2.1}/tests/test_controls.py +0 -0
  123. {filly-0.2.0 → filly-0.2.1}/tests/test_draco.py +0 -0
  124. {filly-0.2.0 → filly-0.2.1}/tests/test_effects.py +0 -0
  125. {filly-0.2.0 → filly-0.2.1}/tests/test_encoding.py +0 -0
  126. {filly-0.2.0 → filly-0.2.1}/tests/test_features.py +0 -0
  127. {filly-0.2.0 → filly-0.2.1}/tests/test_framing.py +0 -0
  128. {filly-0.2.0 → filly-0.2.1}/tests/test_gl_hosts.py +0 -0
  129. {filly-0.2.0 → filly-0.2.1}/tests/test_gltf_surface_camera.py +0 -0
  130. {filly-0.2.0 → filly-0.2.1}/tests/test_headless.py +0 -0
  131. {filly-0.2.0 → filly-0.2.1}/tests/test_imported_texture.py +0 -0
  132. {filly-0.2.0 → filly-0.2.1}/tests/test_interop.py +0 -0
  133. {filly-0.2.0 → filly-0.2.1}/tests/test_iridescence_dielectric.py +0 -0
  134. {filly-0.2.0 → filly-0.2.1}/tests/test_large_scene.py +0 -0
  135. {filly-0.2.0 → filly-0.2.1}/tests/test_lifecycle.py +0 -0
  136. {filly-0.2.0 → filly-0.2.1}/tests/test_light_pointer.py +0 -0
  137. {filly-0.2.0 → filly-0.2.1}/tests/test_lighting.py +0 -0
  138. {filly-0.2.0 → filly-0.2.1}/tests/test_logging.py +0 -0
  139. {filly-0.2.0 → filly-0.2.1}/tests/test_material_limits.py +0 -0
  140. {filly-0.2.0 → filly-0.2.1}/tests/test_material_paths.py +0 -0
  141. {filly-0.2.0 → filly-0.2.1}/tests/test_mesh.py +0 -0
  142. {filly-0.2.0 → filly-0.2.1}/tests/test_native_imports.py +0 -0
  143. {filly-0.2.0 → filly-0.2.1}/tests/test_native_preparation.py +0 -0
  144. {filly-0.2.0 → filly-0.2.1}/tests/test_node_tree.py +0 -0
  145. {filly-0.2.0 → filly-0.2.1}/tests/test_pick.py +0 -0
  146. {filly-0.2.0 → filly-0.2.1}/tests/test_psychopy.py +0 -0
  147. {filly-0.2.0 → filly-0.2.1}/tests/test_refraction.py +0 -0
  148. {filly-0.2.0 → filly-0.2.1}/tests/test_render_calls.py +0 -0
  149. {filly-0.2.0 → filly-0.2.1}/tests/test_renderer.py +0 -0
  150. {filly-0.2.0 → filly-0.2.1}/tests/test_rendering_options.py +0 -0
  151. {filly-0.2.0 → filly-0.2.1}/tests/test_samples.py +0 -0
  152. {filly-0.2.0 → filly-0.2.1}/tests/test_scene_extensions.py +0 -0
  153. {filly-0.2.0 → filly-0.2.1}/tests/test_stress.py +0 -0
  154. {filly-0.2.0 → filly-0.2.1}/tests/test_textures.py +0 -0
  155. {filly-0.2.0 → filly-0.2.1}/tests/test_volume.py +0 -0
  156. {filly-0.2.0 → filly-0.2.1}/tests/web/api.html +0 -0
  157. {filly-0.2.0 → filly-0.2.1}/tests/web/handover.html +0 -0
  158. {filly-0.2.0 → filly-0.2.1}/tests/web/package-lock.json +0 -0
  159. {filly-0.2.0 → filly-0.2.1}/tests/web/package.json +0 -0
  160. {filly-0.2.0 → filly-0.2.1}/tools/benchmark_refraction.py +0 -0
  161. {filly-0.2.0 → filly-0.2.1}/tools/benchmark_uploads.py +0 -0
  162. {filly-0.2.0 → filly-0.2.1}/tools/build_filament_linux.py +0 -0
  163. {filly-0.2.0 → filly-0.2.1}/tools/build_filament_web.sh +0 -0
  164. {filly-0.2.0 → filly-0.2.1}/tools/build_filly_web.sh +0 -0
  165. {filly-0.2.0 → filly-0.2.1}/tools/build_web_container.ps1 +0 -0
  166. {filly-0.2.0 → filly-0.2.1}/tools/check_native_imports.py +0 -0
  167. {filly-0.2.0 → filly-0.2.1}/tools/check_sample_assets.py +0 -0
  168. {filly-0.2.0 → filly-0.2.1}/tools/ci_linux.sh +0 -0
  169. {filly-0.2.0 → filly-0.2.1}/tools/compare_reference.py +0 -0
  170. {filly-0.2.0 → filly-0.2.1}/tools/fetch_filament.py +0 -0
  171. {filly-0.2.0 → filly-0.2.1}/tools/make_suzanne.py +0 -0
  172. {filly-0.2.0 → filly-0.2.1}/tools/profile_frame.py +0 -0
  173. {filly-0.2.0 → filly-0.2.1}/tools/profile_matrix.py +0 -0
  174. {filly-0.2.0 → filly-0.2.1}/tools/profile_rdc_replay.py +0 -0
  175. {filly-0.2.0 → filly-0.2.1}/tools/profile_tracy.py +0 -0
  176. {filly-0.2.0 → filly-0.2.1}/tools/web/Dockerfile +0 -0
  177. {filly-0.2.0 → filly-0.2.1}/uv.lock +0 -0
  178. {filly-0.2.0 → filly-0.2.1}/web/CMakeLists.txt +0 -0
  179. {filly-0.2.0 → filly-0.2.1}/web/bindings.cpp +0 -0
  180. {filly-0.2.0 → filly-0.2.1}/web/gl_tracking.js +0 -0
@@ -32,19 +32,19 @@ jobs:
32
32
  matrix:
33
33
  os: [ubuntu-24.04, windows-2022]
34
34
  steps:
35
- - uses: actions/checkout@v4
36
- - uses: actions/setup-python@v5
35
+ - uses: actions/checkout@v7
36
+ - uses: actions/setup-python@v7
37
37
  with:
38
38
  python-version: '3.12'
39
39
  - name: Cache Linux SDK
40
40
  if: runner.os == 'Linux'
41
- uses: actions/cache@v4
41
+ uses: actions/cache@v6
42
42
  with:
43
43
  path: .deps/filament-linux
44
44
  key: filament-linux-x86_64-manylinux228-${{ hashFiles('tools/build_filament_linux.py', 'tools/ci_linux.sh') }}
45
45
  - name: Cache Windows SDK
46
46
  if: runner.os == 'Windows'
47
- uses: actions/cache@v4
47
+ uses: actions/cache@v6
48
48
  with:
49
49
  path: .deps
50
50
  key: filament-windows-x86_64-${{ hashFiles('tools/fetch_filament.py') }}
@@ -66,7 +66,7 @@ jobs:
66
66
  - name: Check extension imports
67
67
  shell: bash
68
68
  run: python tools/check_native_imports.py wheelhouse/*.whl
69
- - uses: actions/upload-artifact@v4
69
+ - uses: actions/upload-artifact@v7
70
70
  with:
71
71
  name: wheels-${{ matrix.os }}
72
72
  path: wheelhouse/*.whl
@@ -76,8 +76,8 @@ jobs:
76
76
  name: sdist
77
77
  runs-on: ubuntu-24.04
78
78
  steps:
79
- - uses: actions/checkout@v4
80
- - uses: actions/setup-python@v5
79
+ - uses: actions/checkout@v7
80
+ - uses: actions/setup-python@v7
81
81
  with:
82
82
  python-version: '3.12'
83
83
  - name: Check that the tag matches the version
@@ -92,7 +92,7 @@ jobs:
92
92
  raise SystemExit(f"Tag {tag} does not match version {version} in pyproject.toml")
93
93
  - name: Build the sdist
94
94
  run: pipx run build --sdist
95
- - uses: actions/upload-artifact@v4
95
+ - uses: actions/upload-artifact@v7
96
96
  with:
97
97
  name: sdist
98
98
  path: dist/*.tar.gz
@@ -109,7 +109,7 @@ jobs:
109
109
  permissions:
110
110
  id-token: write
111
111
  steps:
112
- - uses: actions/download-artifact@v4
112
+ - uses: actions/download-artifact@v8
113
113
  with:
114
114
  path: dist
115
115
  merge-multiple: true
@@ -126,7 +126,7 @@ jobs:
126
126
  permissions:
127
127
  id-token: write
128
128
  steps:
129
- - uses: actions/download-artifact@v4
129
+ - uses: actions/download-artifact@v8
130
130
  with:
131
131
  path: dist
132
132
  merge-multiple: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: filly
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A Python 3D renderer for glTF scenes, built on Google Filament
5
5
  Author: Alex Forrence
6
6
  License-Expression: MIT
@@ -155,6 +155,10 @@ Firefox has no `KHR_parallel_shader_compile`. Filament then compiles at the firs
155
155
  `write(fn)`) keep only the bookkeeping.
156
156
  - Files load from memory: `loadUrl()` fetches a `.glb`, or a `.gltf` and the buffers and images
157
157
  it names, and writes them to Emscripten's in-memory file system for the load.
158
+ - `filly.js` compiles `filly-core.wasm` while it downloads only if the server sends it as
159
+ `application/wasm`. Some static hosts, Pavlovia among them, send another type. Then
160
+ `filly.js` compiles the downloaded bytes. Emscripten's own loader would log an error and
161
+ download the file again.
158
162
 
159
163
  ## Output compared with the desktop
160
164
 
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "filly"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "A Python 3D renderer for glTF scenes, built on Google Filament"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -108,8 +108,9 @@ def _web_build():
108
108
  return build
109
109
 
110
110
 
111
- def _run_page(browser, page, folder):
112
- """Serve the web build, the pages, and tree.glb from folder; return the page's testResult."""
111
+ def _run_page(browser, page, folder, wasm_type=None, report=False):
112
+ """Serve the web build, the pages, and tree.glb from folder; return the page's testResult,
113
+ or with `report`, also the console messages. `wasm_type`: the Content-Type of .wasm files."""
113
114
  executable = os.environ.get(f"FILLY_TEST_{browser.upper()}", EXECUTABLES.get(browser, ""))
114
115
  node = shutil.which("node")
115
116
  if not node:
@@ -128,12 +129,13 @@ def _run_page(browser, page, folder):
128
129
  (folder / "tree.glb").write_bytes(tree_glb())
129
130
  (folder / "instances.glb").write_bytes(instances_glb())
130
131
  shutil.copytree(ROOT / "tests" / "data" / "draco-box", folder / "draco-box")
131
- result = subprocess.run([node, str(WEB / "run_page.mjs"), str(folder), page, browser, executable],
132
+ command = [node, str(WEB / "run_page.mjs"), str(folder), page, browser, executable]
133
+ result = subprocess.run(command + ([wasm_type] if wasm_type else []),
132
134
  capture_output=True, text=True, timeout=300, cwd=WEB)
133
135
  assert result.returncode == 0, result.stderr[-3000:]
134
- report = json.loads(result.stdout.strip().splitlines()[-1])
135
- assert report["pageErrors"] == [], report["pageErrors"]
136
- return report["result"]
136
+ output = json.loads(result.stdout.strip().splitlines()[-1])
137
+ assert output["pageErrors"] == [], output["pageErrors"]
138
+ return output if report else output["result"]
137
139
 
138
140
 
139
141
  @pytest.fixture(scope="module", params=BROWSERS)
@@ -390,6 +392,18 @@ def test_gpu_frame_time(page_results):
390
392
  assert large > 2 * small, value
391
393
 
392
394
 
395
+ def test_wasm_without_wasm_type(browser_folder):
396
+ """A host that sends the .wasm file as application/octet-stream, as Pavlovia does: the module
397
+ loads without the console error and second download of Emscripten's fallback."""
398
+ browser, folder = browser_folder
399
+ output = _run_page(browser, "handover.html", folder, wasm_type="application/octet-stream",
400
+ report=True)
401
+ assert output["consoleErrors"] == [], output["consoleErrors"]
402
+ warnings = [text for text in output["consoleWarnings"] if "wasm" in text.lower()]
403
+ assert warnings == [], warnings
404
+ assert output["result"]["readValues"]["width"] == 512
405
+
406
+
393
407
  def test_handover(handover_results):
394
408
  calls = handover_results["calls"]
395
409
  # Property reads after the hand-back leave the context with the page.
@@ -1,17 +1,18 @@
1
1
  // Serve a folder, open one page in a browser, and print the page's window.testResult as JSON.
2
2
  //
3
- // Usage: node run_page.mjs FOLDER PAGE BROWSER EXECUTABLE
3
+ // Usage: node run_page.mjs FOLDER PAGE BROWSER EXECUTABLE [WASM_TYPE]
4
4
  //
5
5
  // The page sets window.testResult when it is done. Page errors and console errors are reported
6
- // with the result. The server sends no special headers.
6
+ // with the result, and console warnings too. The server sends no special headers; WASM_TYPE
7
+ // replaces the Content-Type of .wasm files (default application/wasm).
7
8
  import fs from "node:fs";
8
9
  import http from "node:http";
9
10
  import path from "node:path";
10
11
  import puppeteer from "puppeteer-core";
11
12
 
12
- const [folder, pageName, browserName, executable] = process.argv.slice(2);
13
+ const [folder, pageName, browserName, executable, wasmType] = process.argv.slice(2);
13
14
  const types = { ".html": "text/html", ".mjs": "text/javascript", ".js": "text/javascript",
14
- ".wasm": "application/wasm", ".json": "application/json" };
15
+ ".wasm": wasmType ?? "application/wasm", ".json": "application/json" };
15
16
  const server = http.createServer((request, response) =>
16
17
  {
17
18
  const file = path.join(folder, decodeURIComponent(new URL(request.url, "http://host").pathname));
@@ -28,7 +29,7 @@ const server = http.createServer((request, response) =>
28
29
  });
29
30
  }).listen(0);
30
31
 
31
- const report = { pageErrors: [], consoleErrors: [] };
32
+ const report = { pageErrors: [], consoleErrors: [], consoleWarnings: [] };
32
33
  const browser = await puppeteer.launch({
33
34
  executablePath: executable,
34
35
  browser: browserName === "firefox" ? "firefox" : "chrome",
@@ -45,6 +46,10 @@ try
45
46
  {
46
47
  report.consoleErrors.push(message.text());
47
48
  }
49
+ else if (message.type() === "warn")
50
+ {
51
+ report.consoleWarnings.push(message.text());
52
+ }
48
53
  });
49
54
  await page.goto(`http://localhost:${server.address().port}/${pageName}`);
50
55
  await page.waitForFunction(() => window.testResult !== undefined, { timeout: 120000 });
@@ -48,11 +48,40 @@ let loadedModule = null;
48
48
  /** Load the WebAssembly module once per page. filly-core.wasm is resolved next to this file. */
49
49
  export function loadModule()
50
50
  {
51
- modulePromise ??= createFillyModule({ locateFile: (file) => new URL(file, import.meta.url).href })
52
- .then((module) => (loadedModule = module));
51
+ if (!modulePromise)
52
+ {
53
+ // Emscripten's instantiateWasm hook has no way to report a failure.
54
+ let fail;
55
+ const failed = new Promise((resolve, reject) => (fail = reject));
56
+ const created = createFillyModule({
57
+ locateFile: (file) => new URL(file, import.meta.url).href,
58
+ instantiateWasm: (imports, receive) =>
59
+ {
60
+ instantiateWasm(new URL("filly-core.wasm", import.meta.url).href, imports)
61
+ .then(({ instance, module }) => receive(instance, module), fail);
62
+ return {};
63
+ },
64
+ });
65
+ modulePromise = Promise.race([created, failed]).then((module) => (loadedModule = module));
66
+ }
53
67
  return modulePromise;
54
68
  }
55
69
 
70
+ // Static hosts, Pavlovia among them, can send .wasm files without the application/wasm type that
71
+ // streaming compilation needs. Emscripten's loader then logs an error and fetches the file again.
72
+ async function instantiateWasm(url, imports)
73
+ {
74
+ const response = await fetch(url);
75
+ if (!response.ok)
76
+ {
77
+ throw new FillyError(`Could not fetch ${url}: ${response.status} ${response.statusText}`);
78
+ }
79
+ const type = response.headers.get("Content-Type")?.split(";")[0].trim();
80
+ return type === "application/wasm"
81
+ ? WebAssembly.instantiateStreaming(response, imports)
82
+ : WebAssembly.instantiate(await response.arrayBuffer(), imports);
83
+ }
84
+
56
85
  function moduleNow()
57
86
  {
58
87
  if (!loadedModule)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes