@swf2es/player-hosts 0.0.0-stage → 0.1.1

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 (405) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSE.third-party +759 -0
  3. package/README.md +43 -2
  4. package/dist/indexeddb.d.ts +27 -0
  5. package/dist/indexeddb.d.ts.map +1 -0
  6. package/dist/indexeddb.js +170 -0
  7. package/dist/indexeddb.js.map +1 -0
  8. package/dist/node-worker.d.ts +2 -0
  9. package/dist/node-worker.d.ts.map +1 -0
  10. package/dist/node-worker.js +12 -0
  11. package/dist/node-worker.js.map +1 -0
  12. package/dist/node.d.ts +8 -0
  13. package/dist/node.d.ts.map +1 -0
  14. package/dist/node.js +43 -0
  15. package/dist/node.js.map +1 -0
  16. package/dist/precompiled.d.ts +31 -0
  17. package/dist/precompiled.d.ts.map +1 -0
  18. package/dist/precompiled.js +125 -0
  19. package/dist/precompiled.js.map +1 -0
  20. package/dist/stage3d.d.ts +13 -0
  21. package/dist/stage3d.d.ts.map +1 -0
  22. package/dist/stage3d.js +61 -0
  23. package/dist/stage3d.js.map +1 -0
  24. package/dist/thread/codegen/codegen.js +308 -0
  25. package/dist/thread/codegen/index.js +405 -0
  26. package/dist/thread/format/abc-names.js +126 -0
  27. package/dist/thread/format/actions.js +222 -0
  28. package/dist/thread/format/air-descriptor.js +63 -0
  29. package/dist/thread/format/api-versions.js +22 -0
  30. package/dist/thread/format/bitmap.js +199 -0
  31. package/dist/thread/format/button.js +60 -0
  32. package/dist/thread/format/compression.js +200 -0
  33. package/dist/thread/format/display.js +305 -0
  34. package/dist/thread/format/filters.js +136 -0
  35. package/dist/thread/format/font.js +168 -0
  36. package/dist/thread/format/index.js +26 -0
  37. package/dist/thread/format/pbj.js +484 -0
  38. package/dist/thread/format/shape.js +411 -0
  39. package/dist/thread/format/sound.js +91 -0
  40. package/dist/thread/format/swf.js +163 -0
  41. package/dist/thread/format/tags.js +58 -0
  42. package/dist/thread/format/text.js +135 -0
  43. package/dist/thread/format/zip.js +91 -0
  44. package/dist/thread/native/audio/binary.js +3 -0
  45. package/dist/thread/native/audio/index.js +72 -0
  46. package/dist/thread/native/base64.js +9 -0
  47. package/dist/thread/native/compress/binary.js +3 -0
  48. package/dist/thread/native/compress/index.js +145 -0
  49. package/dist/thread/native/instance.js +49 -0
  50. package/dist/thread/native/mp3/binary.js +3 -0
  51. package/dist/thread/native/mp3/index.js +48 -0
  52. package/dist/thread/native/render/binary.js +3 -0
  53. package/dist/thread/native/render/bitmap-kernel.js +591 -0
  54. package/dist/thread/native/render/draw-kernel.js +204 -0
  55. package/dist/thread/native/render/dxt-encoder.js +94 -0
  56. package/dist/thread/native/render/index.js +10 -0
  57. package/dist/thread/native/render/lines.js +122 -0
  58. package/dist/thread/native/render/module.js +26 -0
  59. package/dist/thread/native/render/pixel-ops.js +235 -0
  60. package/dist/thread/native/render/tessellator.js +250 -0
  61. package/dist/thread/player/avm1/amf.js +507 -0
  62. package/dist/thread/player/avm1/avm1.js +1304 -0
  63. package/dist/thread/player/avm1/bindings.js +214 -0
  64. package/dist/thread/player/avm1/classes.js +75 -0
  65. package/dist/thread/player/avm1/clips.js +229 -0
  66. package/dist/thread/player/avm1/compile.js +140 -0
  67. package/dist/thread/player/avm1/external.js +79 -0
  68. package/dist/thread/player/avm1/focus.js +278 -0
  69. package/dist/thread/player/avm1/globals/BitmapData.js +542 -0
  70. package/dist/thread/player/avm1/globals/Button.js +31 -0
  71. package/dist/thread/player/avm1/globals/Color.js +115 -0
  72. package/dist/thread/player/avm1/globals/ExternalInterface.js +310 -0
  73. package/dist/thread/player/avm1/globals/FileReference.js +217 -0
  74. package/dist/thread/player/avm1/globals/Key.js +60 -0
  75. package/dist/thread/player/avm1/globals/LoadVars.js +208 -0
  76. package/dist/thread/player/avm1/globals/LocalConnection.js +92 -0
  77. package/dist/thread/player/avm1/globals/MovieClip.js +1070 -0
  78. package/dist/thread/player/avm1/globals/MovieClipLoader.js +90 -0
  79. package/dist/thread/player/avm1/globals/NetConnection.js +261 -0
  80. package/dist/thread/player/avm1/globals/PrintJob.js +37 -0
  81. package/dist/thread/player/avm1/globals/Selection.js +62 -0
  82. package/dist/thread/player/avm1/globals/SharedObject.js +245 -0
  83. package/dist/thread/player/avm1/globals/Sound.js +238 -0
  84. package/dist/thread/player/avm1/globals/Stage.js +12 -0
  85. package/dist/thread/player/avm1/globals/StyleSheet.js +205 -0
  86. package/dist/thread/player/avm1/globals/TextField.js +396 -0
  87. package/dist/thread/player/avm1/globals/TextFormat.js +194 -0
  88. package/dist/thread/player/avm1/globals/TextSnapshot.js +88 -0
  89. package/dist/thread/player/avm1/globals/XML.js +396 -0
  90. package/dist/thread/player/avm1/globals/XMLNode.js +413 -0
  91. package/dist/thread/player/avm1/globals/XMLSocket.js +205 -0
  92. package/dist/thread/player/avm1/globals/drawing.js +202 -0
  93. package/dist/thread/player/avm1/globals/filters.js +635 -0
  94. package/dist/thread/player/avm1/globals/geom.js +600 -0
  95. package/dist/thread/player/avm1/input.js +483 -0
  96. package/dist/thread/player/avm1/keyboard.js +113 -0
  97. package/dist/thread/player/avm1/loads.js +352 -0
  98. package/dist/thread/player/avm1/net.js +219 -0
  99. package/dist/thread/player/avm1/paths.js +104 -0
  100. package/dist/thread/player/avm1/pointer.js +512 -0
  101. package/dist/thread/player/avm1/queue.js +303 -0
  102. package/dist/thread/player/avm1/sound.js +106 -0
  103. package/dist/thread/player/avm1/swf.js +141 -0
  104. package/dist/thread/player/avm1/timers.js +113 -0
  105. package/dist/thread/player/bitmap/bitmap.js +627 -0
  106. package/dist/thread/player/bitmap/draw.js +68 -0
  107. package/dist/thread/player/bitmap/dxt.js +11 -0
  108. package/dist/thread/player/bitmap/filters.js +656 -0
  109. package/dist/thread/player/bitmap/images.js +240 -0
  110. package/dist/thread/player/bitmap/kernel.js +65 -0
  111. package/dist/thread/player/bitmap/ops.js +1239 -0
  112. package/dist/thread/player/bitmap/pixel-bender.js +911 -0
  113. package/dist/thread/player/bitmap/png.js +139 -0
  114. package/dist/thread/player/bitmap/turbulence.js +89 -0
  115. package/dist/thread/player/clock.js +182 -0
  116. package/dist/thread/player/display/bitmapobject.js +25 -0
  117. package/dist/thread/player/display/bounds.js +520 -0
  118. package/dist/thread/player/display/buttonobject.js +305 -0
  119. package/dist/thread/player/display/color.js +40 -0
  120. package/dist/thread/player/display/container.js +150 -0
  121. package/dist/thread/player/display/display.js +14 -0
  122. package/dist/thread/player/display/displayobject.js +664 -0
  123. package/dist/thread/player/display/drawing.js +613 -0
  124. package/dist/thread/player/display/filters.js +285 -0
  125. package/dist/thread/player/display/geometry.js +189 -0
  126. package/dist/thread/player/display/gradients.js +117 -0
  127. package/dist/thread/player/display/graphicsdata.js +592 -0
  128. package/dist/thread/player/display/instantiate.js +71 -0
  129. package/dist/thread/player/display/matrix3d.js +373 -0
  130. package/dist/thread/player/display/morph.js +226 -0
  131. package/dist/thread/player/display/movieclip.js +680 -0
  132. package/dist/thread/player/display/perspective.js +193 -0
  133. package/dist/thread/player/display/scale9.js +236 -0
  134. package/dist/thread/player/display/shapeobject.js +131 -0
  135. package/dist/thread/player/display/shapes.js +407 -0
  136. package/dist/thread/player/display/textobjects.js +222 -0
  137. package/dist/thread/player/display/timeline.js +471 -0
  138. package/dist/thread/player/display/value-lists.js +40 -0
  139. package/dist/thread/player/display/videoobject.js +6 -0
  140. package/dist/thread/player/display/walk.js +127 -0
  141. package/dist/thread/player/files.js +334 -0
  142. package/dist/thread/player/hosts.js +207 -0
  143. package/dist/thread/player/input/avm1.js +82 -0
  144. package/dist/thread/player/input/context-menu.js +63 -0
  145. package/dist/thread/player/input/keyboard.js +458 -0
  146. package/dist/thread/player/input/pointer.js +863 -0
  147. package/dist/thread/player/input/text-editor.js +319 -0
  148. package/dist/thread/player/input/touch.js +209 -0
  149. package/dist/thread/player/localconnection.js +90 -0
  150. package/dist/thread/player/media/audio.js +376 -0
  151. package/dist/thread/player/media/dynamic-sound.js +90 -0
  152. package/dist/thread/player/media/extract.js +135 -0
  153. package/dist/thread/player/media/mp3.js +152 -0
  154. package/dist/thread/player/media/sounds.js +507 -0
  155. package/dist/thread/player/media/streaming-audio.js +133 -0
  156. package/dist/thread/player/player.js +616 -0
  157. package/dist/thread/player/playerglobal/air/net/WebSocket.js +250 -0
  158. package/dist/thread/player/playerglobal/air-library.js +8 -0
  159. package/dist/thread/player/playerglobal/flash/accessibility/Accessibility.js +21 -0
  160. package/dist/thread/player/playerglobal/flash/crypto/generateRandomBytes.js +32 -0
  161. package/dist/thread/player/playerglobal/flash/data/EncryptedLocalStore.js +61 -0
  162. package/dist/thread/player/playerglobal/flash/desktop/Clipboard.js +173 -0
  163. package/dist/thread/player/playerglobal/flash/desktop/NativeApplication.js +179 -0
  164. package/dist/thread/player/playerglobal/flash/display/AVM1Movie.js +19 -0
  165. package/dist/thread/player/playerglobal/flash/display/Bitmap.js +58 -0
  166. package/dist/thread/player/playerglobal/flash/display/BitmapData.js +633 -0
  167. package/dist/thread/player/playerglobal/flash/display/DisplayObject.js +614 -0
  168. package/dist/thread/player/playerglobal/flash/display/DisplayObjectContainer.js +224 -0
  169. package/dist/thread/player/playerglobal/flash/display/Graphics.js +345 -0
  170. package/dist/thread/player/playerglobal/flash/display/InteractiveObject.js +87 -0
  171. package/dist/thread/player/playerglobal/flash/display/Loader.js +79 -0
  172. package/dist/thread/player/playerglobal/flash/display/LoaderInfo.js +128 -0
  173. package/dist/thread/player/playerglobal/flash/display/MovieClip.js +194 -0
  174. package/dist/thread/player/playerglobal/flash/display/NativeWindow.js +245 -0
  175. package/dist/thread/player/playerglobal/flash/display/Shader.js +26 -0
  176. package/dist/thread/player/playerglobal/flash/display/ShaderData.js +85 -0
  177. package/dist/thread/player/playerglobal/flash/display/ShaderInput.js +64 -0
  178. package/dist/thread/player/playerglobal/flash/display/ShaderJob.js +181 -0
  179. package/dist/thread/player/playerglobal/flash/display/ShaderParameter.js +23 -0
  180. package/dist/thread/player/playerglobal/flash/display/Shape.js +13 -0
  181. package/dist/thread/player/playerglobal/flash/display/SimpleButton.js +103 -0
  182. package/dist/thread/player/playerglobal/flash/display/Sprite.js +84 -0
  183. package/dist/thread/player/playerglobal/flash/display/Stage.js +231 -0
  184. package/dist/thread/player/playerglobal/flash/display/Stage3D.js +54 -0
  185. package/dist/thread/player/playerglobal/flash/display/shaders.js +228 -0
  186. package/dist/thread/player/playerglobal/flash/events/Event.js +58 -0
  187. package/dist/thread/player/playerglobal/flash/events/EventDispatcher.js +103 -0
  188. package/dist/thread/player/playerglobal/flash/events/GestureEvent.js +34 -0
  189. package/dist/thread/player/playerglobal/flash/events/HTTPStatusEvent.js +8 -0
  190. package/dist/thread/player/playerglobal/flash/events/KeyboardEvent.js +51 -0
  191. package/dist/thread/player/playerglobal/flash/events/MouseEvent.js +59 -0
  192. package/dist/thread/player/playerglobal/flash/events/PressAndTapGestureEvent.js +30 -0
  193. package/dist/thread/player/playerglobal/flash/events/TimerEvent.js +16 -0
  194. package/dist/thread/player/playerglobal/flash/events/TouchEvent.js +45 -0
  195. package/dist/thread/player/playerglobal/flash/external/ExternalInterface.js +73 -0
  196. package/dist/thread/player/playerglobal/flash/filesystem/File.js +340 -0
  197. package/dist/thread/player/playerglobal/flash/filesystem/FileStream.js +453 -0
  198. package/dist/thread/player/playerglobal/flash/filesystem/paths.js +156 -0
  199. package/dist/thread/player/playerglobal/flash/filesystem/writes.js +143 -0
  200. package/dist/thread/player/playerglobal/flash/filters/BevelFilter.js +4 -0
  201. package/dist/thread/player/playerglobal/flash/filters/BitmapFilter.js +205 -0
  202. package/dist/thread/player/playerglobal/flash/filters/BlurFilter.js +4 -0
  203. package/dist/thread/player/playerglobal/flash/filters/ColorMatrixFilter.js +11 -0
  204. package/dist/thread/player/playerglobal/flash/filters/ConvolutionFilter.js +26 -0
  205. package/dist/thread/player/playerglobal/flash/filters/DisplacementMapFilter.js +51 -0
  206. package/dist/thread/player/playerglobal/flash/filters/DropShadowFilter.js +4 -0
  207. package/dist/thread/player/playerglobal/flash/filters/GlowFilter.js +4 -0
  208. package/dist/thread/player/playerglobal/flash/filters/GradientBevelFilter.js +4 -0
  209. package/dist/thread/player/playerglobal/flash/filters/GradientGlowFilter.js +4 -0
  210. package/dist/thread/player/playerglobal/flash/filters/ShaderFilter.js +53 -0
  211. package/dist/thread/player/playerglobal/flash/geom/Matrix3D.js +361 -0
  212. package/dist/thread/player/playerglobal/flash/geom/PerspectiveProjection.js +122 -0
  213. package/dist/thread/player/playerglobal/flash/geom/Transform.js +245 -0
  214. package/dist/thread/player/playerglobal/flash/geom/Utils3D.js +85 -0
  215. package/dist/thread/player/playerglobal/flash/globalization/Collator.js +149 -0
  216. package/dist/thread/player/playerglobal/flash/globalization/CurrencyFormatter.js +272 -0
  217. package/dist/thread/player/playerglobal/flash/globalization/CurrencyParseResult.js +21 -0
  218. package/dist/thread/player/playerglobal/flash/globalization/DateTimeFormatter.js +463 -0
  219. package/dist/thread/player/playerglobal/flash/globalization/LocaleID.js +144 -0
  220. package/dist/thread/player/playerglobal/flash/globalization/NumberFormatter.js +444 -0
  221. package/dist/thread/player/playerglobal/flash/globalization/NumberParseResult.js +22 -0
  222. package/dist/thread/player/playerglobal/flash/globalization/StringTools.js +59 -0
  223. package/dist/thread/player/playerglobal/flash/globalization/locale.js +190 -0
  224. package/dist/thread/player/playerglobal/flash/media/Camera.js +89 -0
  225. package/dist/thread/player/playerglobal/flash/media/Microphone.js +126 -0
  226. package/dist/thread/player/playerglobal/flash/media/Sound.js +543 -0
  227. package/dist/thread/player/playerglobal/flash/media/SoundMixer.js +74 -0
  228. package/dist/thread/player/playerglobal/flash/media/SoundTransform.js +40 -0
  229. package/dist/thread/player/playerglobal/flash/media/Video.js +43 -0
  230. package/dist/thread/player/playerglobal/flash/net/FileFilter.js +27 -0
  231. package/dist/thread/player/playerglobal/flash/net/FileReference.js +197 -0
  232. package/dist/thread/player/playerglobal/flash/net/LocalConnection.js +167 -0
  233. package/dist/thread/player/playerglobal/flash/net/NetConnection.js +155 -0
  234. package/dist/thread/player/playerglobal/flash/net/SharedObject.js +299 -0
  235. package/dist/thread/player/playerglobal/flash/net/Socket.js +282 -0
  236. package/dist/thread/player/playerglobal/flash/net/URLRequest.js +93 -0
  237. package/dist/thread/player/playerglobal/flash/net/URLStream.js +146 -0
  238. package/dist/thread/player/playerglobal/flash/net/XMLSocket.js +14 -0
  239. package/dist/thread/player/playerglobal/flash/net/local-modern.js +142 -0
  240. package/dist/thread/player/playerglobal/flash/net/local-values.js +217 -0
  241. package/dist/thread/player/playerglobal/flash/net/navigateToURL.js +29 -0
  242. package/dist/thread/player/playerglobal/flash/profiler/Telemetry.js +25 -0
  243. package/dist/thread/player/playerglobal/flash/sensors/Accelerometer.js +12 -0
  244. package/dist/thread/player/playerglobal/flash/system/ApplicationDomain.js +69 -0
  245. package/dist/thread/player/playerglobal/flash/system/Capabilities.js +163 -0
  246. package/dist/thread/player/playerglobal/flash/system/FSCommandHost.js +17 -0
  247. package/dist/thread/player/playerglobal/flash/system/Security.js +46 -0
  248. package/dist/thread/player/playerglobal/flash/system/SecurityDomain.js +21 -0
  249. package/dist/thread/player/playerglobal/flash/system/System.js +73 -0
  250. package/dist/thread/player/playerglobal/flash/system/Worker.js +112 -0
  251. package/dist/thread/player/playerglobal/flash/text/Font.js +95 -0
  252. package/dist/thread/player/playerglobal/flash/text/StaticText.js +16 -0
  253. package/dist/thread/player/playerglobal/flash/text/StyleSheet.js +65 -0
  254. package/dist/thread/player/playerglobal/flash/text/TextField.js +707 -0
  255. package/dist/thread/player/playerglobal/flash/text/TextRenderer.js +77 -0
  256. package/dist/thread/player/playerglobal/flash/text/engine/FontDescription.js +141 -0
  257. package/dist/thread/player/playerglobal/flash/text/engine/TabStop.js +46 -0
  258. package/dist/thread/player/playerglobal/flash/trace/Trace.js +17 -0
  259. package/dist/thread/player/playerglobal/flash/ui/ContextMenu.js +17 -0
  260. package/dist/thread/player/playerglobal/flash/ui/GameInput.js +19 -0
  261. package/dist/thread/player/playerglobal/flash/ui/Keyboard.js +27 -0
  262. package/dist/thread/player/playerglobal/flash/ui/Mouse.js +127 -0
  263. package/dist/thread/player/playerglobal/flash/ui/Multitouch.js +46 -0
  264. package/dist/thread/player/playerglobal/flash/utils/ByteArray.js +155 -0
  265. package/dist/thread/player/playerglobal/flash/utils/Timer.js +25 -0
  266. package/dist/thread/player/playerglobal/flash/xml/XMLDocument.js +74 -0
  267. package/dist/thread/player/playerglobal/index.js +224 -0
  268. package/dist/thread/player/playerglobal/libraries.js +10 -0
  269. package/dist/thread/player/playerglobal/playerglobal-library.js +22 -0
  270. package/dist/thread/player/playerglobal/toplevel.js +122 -0
  271. package/dist/thread/player/scripting/clipboard.js +146 -0
  272. package/dist/thread/player/scripting/code.js +900 -0
  273. package/dist/thread/player/scripting/evaluate.js +144 -0
  274. package/dist/thread/player/scripting/events.js +172 -0
  275. package/dist/thread/player/scripting/handover.js +182 -0
  276. package/dist/thread/player/scripting/lazy.js +38 -0
  277. package/dist/thread/player/scripting/lifecycle.js +272 -0
  278. package/dist/thread/player/scripting/loads.js +860 -0
  279. package/dist/thread/player/scripting/sha256.js +95 -0
  280. package/dist/thread/player/scripting/symbols.js +348 -0
  281. package/dist/thread/player/scripting/timers.js +434 -0
  282. package/dist/thread/player/scripting/workers.js +923 -0
  283. package/dist/thread/player/scripting.js +1018 -0
  284. package/dist/thread/player/stage.js +4 -0
  285. package/dist/thread/player/text/csm.js +113 -0
  286. package/dist/thread/player/text/css.js +167 -0
  287. package/dist/thread/player/text/fonts.js +97 -0
  288. package/dist/thread/player/text/layout.js +393 -0
  289. package/dist/thread/player/text/static.js +109 -0
  290. package/dist/thread/player/text/text.js +431 -0
  291. package/dist/thread/player/workers/thread.js +159 -0
  292. package/dist/thread/player/workers/wire.js +198 -0
  293. package/dist/thread/player-hosts/web-worker.js +19 -0
  294. package/dist/thread/runtime/avm1/activation.js +89 -0
  295. package/dist/thread/runtime/avm1/case.js +249 -0
  296. package/dist/thread/runtime/avm1/clips.js +334 -0
  297. package/dist/thread/runtime/avm1/control.js +280 -0
  298. package/dist/thread/runtime/avm1/errors.js +50 -0
  299. package/dist/thread/runtime/avm1/functions.js +249 -0
  300. package/dist/thread/runtime/avm1/globals/array.js +549 -0
  301. package/dist/thread/runtime/avm1/globals/broadcaster.js +131 -0
  302. package/dist/thread/runtime/avm1/globals/date.js +436 -0
  303. package/dist/thread/runtime/avm1/globals/global.js +344 -0
  304. package/dist/thread/runtime/avm1/globals/math.js +139 -0
  305. package/dist/thread/runtime/avm1/globals/number.js +93 -0
  306. package/dist/thread/runtime/avm1/globals/string.js +201 -0
  307. package/dist/thread/runtime/avm1/globals/timers.js +129 -0
  308. package/dist/thread/runtime/avm1/host.js +5 -0
  309. package/dist/thread/runtime/avm1/index.js +14 -0
  310. package/dist/thread/runtime/avm1/inheritance.js +132 -0
  311. package/dist/thread/runtime/avm1/numbers.js +298 -0
  312. package/dist/thread/runtime/avm1/objects.js +896 -0
  313. package/dist/thread/runtime/avm1/operators.js +170 -0
  314. package/dist/thread/runtime/avm1/realm.js +529 -0
  315. package/dist/thread/runtime/avm1/runtime.js +882 -0
  316. package/dist/thread/runtime/avm1/scope.js +385 -0
  317. package/dist/thread/runtime/avm1/urls.js +180 -0
  318. package/dist/thread/runtime/avm1/values.js +97 -0
  319. package/dist/thread/runtime/avm2/amf-classes.js +66 -0
  320. package/dist/thread/runtime/avm2/amf.js +801 -0
  321. package/dist/thread/runtime/avm2/array-conversion.js +100 -0
  322. package/dist/thread/runtime/avm2/builtin-library.js +21 -0
  323. package/dist/thread/runtime/avm2/cache-fill.js +86 -0
  324. package/dist/thread/runtime/avm2/classes.js +211 -0
  325. package/dist/thread/runtime/avm2/definitions.js +69 -0
  326. package/dist/thread/runtime/avm2/descriptors.js +5 -0
  327. package/dist/thread/runtime/avm2/dictionary-keys.js +295 -0
  328. package/dist/thread/runtime/avm2/domain-memory.js +75 -0
  329. package/dist/thread/runtime/avm2/domain.js +280 -0
  330. package/dist/thread/runtime/avm2/dynamic-properties.js +182 -0
  331. package/dist/thread/runtime/avm2/enumeration.js +393 -0
  332. package/dist/thread/runtime/avm2/errors.js +45 -0
  333. package/dist/thread/runtime/avm2/float-library.js +66 -0
  334. package/dist/thread/runtime/avm2/float.js +26 -0
  335. package/dist/thread/runtime/avm2/hooks.js +19 -0
  336. package/dist/thread/runtime/avm2/index.js +38 -0
  337. package/dist/thread/runtime/avm2/messages.js +177 -0
  338. package/dist/thread/runtime/avm2/method-factories.js +95 -0
  339. package/dist/thread/runtime/avm2/modules.js +105 -0
  340. package/dist/thread/runtime/avm2/names.js +248 -0
  341. package/dist/thread/runtime/avm2/natives/aliases.js +47 -0
  342. package/dist/thread/runtime/avm2/natives/array.js +390 -0
  343. package/dist/thread/runtime/avm2/natives/bytearray.js +1227 -0
  344. package/dist/thread/runtime/avm2/natives/case.js +88 -0
  345. package/dist/thread/runtime/avm2/natives/concurrent.js +199 -0
  346. package/dist/thread/runtime/avm2/natives/date.js +581 -0
  347. package/dist/thread/runtime/avm2/natives/define.js +130 -0
  348. package/dist/thread/runtime/avm2/natives/describe.js +351 -0
  349. package/dist/thread/runtime/avm2/natives/dictionary.js +12 -0
  350. package/dist/thread/runtime/avm2/natives/float-vector.js +81 -0
  351. package/dist/thread/runtime/avm2/natives/float.js +96 -0
  352. package/dist/thread/runtime/avm2/natives/index.js +64 -0
  353. package/dist/thread/runtime/avm2/natives/json.js +514 -0
  354. package/dist/thread/runtime/avm2/natives/number.js +162 -0
  355. package/dist/thread/runtime/avm2/natives/object.js +237 -0
  356. package/dist/thread/runtime/avm2/natives/proxy.js +75 -0
  357. package/dist/thread/runtime/avm2/natives/regexp.js +485 -0
  358. package/dist/thread/runtime/avm2/natives/shell-workers.js +404 -0
  359. package/dist/thread/runtime/avm2/natives/shell.js +557 -0
  360. package/dist/thread/runtime/avm2/natives/sort.js +377 -0
  361. package/dist/thread/runtime/avm2/natives/string.js +132 -0
  362. package/dist/thread/runtime/avm2/natives/sync.js +821 -0
  363. package/dist/thread/runtime/avm2/natives/toplevel.js +139 -0
  364. package/dist/thread/runtime/avm2/natives/vector-elements.js +46 -0
  365. package/dist/thread/runtime/avm2/natives/vector.js +406 -0
  366. package/dist/thread/runtime/avm2/natives/xml/access.js +633 -0
  367. package/dist/thread/runtime/avm2/natives/xml/build.js +291 -0
  368. package/dist/thread/runtime/avm2/natives/xml/chars.js +112 -0
  369. package/dist/thread/runtime/avm2/natives/xml/escape.js +38 -0
  370. package/dist/thread/runtime/avm2/natives/xml/names.js +204 -0
  371. package/dist/thread/runtime/avm2/natives/xml/node.js +272 -0
  372. package/dist/thread/runtime/avm2/natives/xml/operators.js +69 -0
  373. package/dist/thread/runtime/avm2/natives/xml/parser.js +356 -0
  374. package/dist/thread/runtime/avm2/natives/xml/strings.js +191 -0
  375. package/dist/thread/runtime/avm2/natives/xml/values.js +122 -0
  376. package/dist/thread/runtime/avm2/natives/xml/xml.js +645 -0
  377. package/dist/thread/runtime/avm2/number-strings.js +110 -0
  378. package/dist/thread/runtime/avm2/numbers.js +558 -0
  379. package/dist/thread/runtime/avm2/options.js +16 -0
  380. package/dist/thread/runtime/avm2/player-messages.js +550 -0
  381. package/dist/thread/runtime/avm2/property-cache.js +135 -0
  382. package/dist/thread/runtime/avm2/runtime.js +2644 -0
  383. package/dist/thread/runtime/avm2/traits.js +509 -0
  384. package/dist/thread/runtime/index.js +7 -0
  385. package/dist/web-worker.d.ts +2 -0
  386. package/dist/web-worker.d.ts.map +1 -0
  387. package/dist/web-worker.js +20 -0
  388. package/dist/web-worker.js.map +1 -0
  389. package/dist/websocket.d.ts +4 -0
  390. package/dist/websocket.d.ts.map +1 -0
  391. package/dist/websocket.js +27 -0
  392. package/dist/websocket.js.map +1 -0
  393. package/dist/workers.d.ts +35 -0
  394. package/dist/workers.d.ts.map +1 -0
  395. package/dist/workers.js +171 -0
  396. package/dist/workers.js.map +1 -0
  397. package/package.json +62 -3
  398. package/src/indexeddb.ts +227 -0
  399. package/src/node-worker.ts +13 -0
  400. package/src/node.ts +49 -0
  401. package/src/precompiled.ts +166 -0
  402. package/src/stage3d.ts +76 -0
  403. package/src/web-worker.ts +24 -0
  404. package/src/websocket.ts +32 -0
  405. package/src/workers.ts +255 -0
@@ -0,0 +1,166 @@
1
+ // A ModuleCache of the modules the swf2es command compiled ahead of time,
2
+ // read-only: each found by the key the command wrote beside it, which is
3
+ // the one the player asks for when the SWF loads in the position the
4
+ // command compiled it for, with its log, which the player replays as it
5
+ // does a cached module's. A key the manifest lacks, as one taken by
6
+ // another compiler, whose identity keys name, is a miss, and the player
7
+ // compiles (see docs/architecture/modules.md, Caching modules).
8
+ import type { CachedModule, ModuleCache } from "@swf2es/player";
9
+
10
+ export interface PrecompiledModulesOptions {
11
+ /** A file the manifest names, or the manifest, read by its URL: fetched by default. */
12
+ read?: (url: URL) => Promise<string>;
13
+ /**
14
+ * Have the player import each module from its URL, as an ES module, not
15
+ * evaluate its text: for a page whose Content-Security-Policy refuses
16
+ * 'unsafe-eval'. The document then keeps the modules for as long as it
17
+ * lives.
18
+ */
19
+ importModules?: boolean;
20
+ }
21
+
22
+ /** The manifest's format this reads, the command's MANIFEST_VERSION: any other names no module. */
23
+ const MANIFEST_VERSION = 2;
24
+
25
+ interface Entry {
26
+ module: URL;
27
+ log: URL;
28
+ lengths: [number, number];
29
+ }
30
+
31
+ /**
32
+ * The modules of the manifest.json at `manifest` (a URL, resolved against
33
+ * the page's), and the logs beside them. The manifest is read at the first
34
+ * get, and again at the next if that failed. Asks for every module however
35
+ * small, so that with each precompiled none compiles.
36
+ */
37
+ export function precompiledModules(
38
+ manifest: string | URL,
39
+ options: PrecompiledModulesOptions = {},
40
+ ): ModuleCache {
41
+ const base = new URL(manifest, globalThis.location?.href);
42
+ const read = options.read ?? fetchText;
43
+ let entries: Promise<Map<string, Entry>> | null = null;
44
+ const rejected = new Set<string>();
45
+ const load = async () => {
46
+ const parsed = JSON.parse(await read(base));
47
+ const map = new Map<string, Entry>();
48
+ if (parsed?.manifestVersion !== MANIFEST_VERSION) {
49
+ return map;
50
+ }
51
+
52
+ for (const e of [parsed.libraries, parsed.abcs].flat()) {
53
+ const { key, module, log, lengths } = e ?? {};
54
+ if (
55
+ typeof key === "string" &&
56
+ typeof module === "string" &&
57
+ typeof log === "string" &&
58
+ Array.isArray(lengths) &&
59
+ lengths.length === 2
60
+ ) {
61
+ map.set(key, {
62
+ module: new URL(module, base),
63
+ log: new URL(log, base),
64
+ lengths: [...lengths] as [number, number],
65
+ });
66
+ }
67
+ }
68
+
69
+ return map;
70
+ };
71
+
72
+ return {
73
+ minBytes: 0,
74
+ async get(key: string): Promise<CachedModule | undefined> {
75
+ if (rejected.has(key)) {
76
+ return undefined;
77
+ }
78
+
79
+ entries ??= load();
80
+ let found: Entry | undefined;
81
+ try {
82
+ found = (await entries).get(key);
83
+ } catch (e) {
84
+ entries = null;
85
+ throw e;
86
+ }
87
+
88
+ if (!found) {
89
+ return undefined;
90
+ }
91
+
92
+ // Each file by a URL of its key: a module or log of another build,
93
+ // which an HTTP cache may hold under the same name, is never this
94
+ // key's, and an imported module's length is not checked.
95
+ const { lengths } = found;
96
+ const [module, log] = [found.module, found.log].map((url) => {
97
+ const keyed = new URL(url);
98
+ keyed.search = key;
99
+ return keyed;
100
+ });
101
+ if (options.importModules) {
102
+ return { module: "", log: await read(log), lengths, url: module.href };
103
+ }
104
+
105
+ const [text, logText] = await Promise.all([read(module), read(log)]);
106
+ return { module: text, log: logText, lengths };
107
+ },
108
+ async put() {},
109
+ // Its files cannot be deleted; the key is not answered again on this page.
110
+ async delete(key) {
111
+ rejected.add(key);
112
+ },
113
+ };
114
+ }
115
+
116
+ async function fetchText(url: URL): Promise<string> {
117
+ const response = await fetch(url);
118
+ if (!response.ok) {
119
+ throw new Error(`${url}: HTTP ${response.status}`);
120
+ }
121
+
122
+ return response.text();
123
+ }
124
+
125
+ /**
126
+ * Caches asked in order, the first that holds a module answering, as the
127
+ * modules compiled ahead of time and then an IndexedDB cache: a module
128
+ * compiled goes to each. A deletion naming the entry the player could not
129
+ * use goes only to the member that gave that entry, which then answers
130
+ * the key no more, so that the player, which asks again once, reads the
131
+ * next one's; one naming none goes to each. One that fails is passed
132
+ * over. Asks for the ABCs the member that asks for the smallest does,
133
+ * every member then asked for them.
134
+ */
135
+ export function chainCaches(...caches: ModuleCache[]): ModuleCache {
136
+ const sizes = caches.flatMap((c) => (c.minBytes === undefined ? [] : [c.minBytes]));
137
+ // By the entry, not the key: two reads of one key may have been answered by two members.
138
+ const answered = new WeakMap<CachedModule, ModuleCache>();
139
+ // A member that throws at the call skips none of the others.
140
+ const each = async (members: ModuleCache[], f: (cache: ModuleCache) => Promise<void>) => {
141
+ await Promise.allSettled(members.map((c) => Promise.resolve().then(() => f(c))));
142
+ };
143
+ return {
144
+ ...(sizes.length ? { minBytes: Math.min(...sizes) } : {}),
145
+ async get(key) {
146
+ for (const cache of caches) {
147
+ try {
148
+ const entry = await cache.get(key);
149
+ if (entry !== undefined) {
150
+ answered.set(entry, cache);
151
+ return entry;
152
+ }
153
+ } catch {
154
+ // The next may hold it.
155
+ }
156
+ }
157
+
158
+ return undefined;
159
+ },
160
+ put: (key, entry) => each(caches, (c) => c.put(key, entry)),
161
+ delete: (key, entry) => {
162
+ const from = entry && answered.get(entry);
163
+ return each(from ? [from] : caches, (c) => c.delete(key, entry));
164
+ },
165
+ };
166
+ }
package/src/stage3d.ts ADDED
@@ -0,0 +1,76 @@
1
+ import type { Context3D, Context3DLifecycle, Stage3DHost } from "@swf2es/player/context3d";
2
+
3
+ export interface Stage3DSurface {
4
+ canvas: HTMLCanvasElement;
5
+ context: Context3D;
6
+ /** Called once after resource disposal and listener removal, including failed attachment. */
7
+ destroy?: () => void;
8
+ }
9
+
10
+ /** The caller supplies a positioned, clipped parent, with the display-list canvas
11
+ * above slots 0..3. The adapter disposes resources before removing a surface. */
12
+ export function stage3DCanvasHost(
13
+ parent: HTMLElement,
14
+ create: (slot: number) => Stage3DSurface,
15
+ ): Stage3DHost {
16
+ const surfaces = new Map<number, Stage3DSurface & { detach: () => void }>();
17
+
18
+ return {
19
+ create(slot, lifecycle) {
20
+ if (surfaces.has(slot)) {
21
+ throw new Error("Stage3D surface must be removed before recreation");
22
+ }
23
+
24
+ const surface = create(slot);
25
+ const detach = observeLoss(surface.canvas, lifecycle);
26
+ try {
27
+ surface.canvas.style.position = "absolute";
28
+ surface.canvas.style.zIndex = String(slot);
29
+ parent.append(surface.canvas);
30
+ surfaces.set(slot, { ...surface, detach });
31
+ } catch (error) {
32
+ detach();
33
+ surface.context.dispose();
34
+ surface.canvas.remove();
35
+ surface.destroy?.();
36
+ throw error;
37
+ }
38
+
39
+ return surface.context;
40
+ },
41
+ place(slot, x, y, visible) {
42
+ const surface = surfaces.get(slot);
43
+ if (surface) {
44
+ const style = surface.canvas.style;
45
+ style.left = `${x}px`;
46
+ style.top = `${y}px`;
47
+ style.visibility = visible ? "visible" : "hidden";
48
+ }
49
+ },
50
+ remove(slot) {
51
+ const surface = surfaces.get(slot);
52
+ if (surface) {
53
+ surface.detach();
54
+ surface.canvas.remove();
55
+ surfaces.delete(slot);
56
+ surface.destroy?.();
57
+ }
58
+ },
59
+ };
60
+ }
61
+
62
+ /** The surface outlives its lost resources so the browser can signal recovery. */
63
+ export function observeLoss(canvas: HTMLCanvasElement, lifecycle: Context3DLifecycle): () => void {
64
+ const lost = (event: Event): void => {
65
+ event.preventDefault();
66
+ lifecycle.lost();
67
+ };
68
+ const restored = (): void => lifecycle.restored();
69
+ canvas.addEventListener("webglcontextlost", lost);
70
+ canvas.addEventListener("webglcontextrestored", restored);
71
+
72
+ return () => {
73
+ canvas.removeEventListener("webglcontextlost", lost);
74
+ canvas.removeEventListener("webglcontextrestored", restored);
75
+ };
76
+ }
@@ -0,0 +1,24 @@
1
+ // A Web Worker running one background flash.system.Worker (workers.ts).
2
+ import { runWorkerThread } from "@swf2es/player/worker";
3
+
4
+ // The DOM's types, not a worker's, are this package's: its global scope as a worker sees it.
5
+ const scope = globalThis as unknown as {
6
+ postMessage(message: unknown): void;
7
+ onmessage: ((event: MessageEvent) => void) | null;
8
+ };
9
+ runWorkerThread({
10
+ post: (message) => scope.postMessage(message),
11
+ listen: (receive) => {
12
+ scope.onmessage = (event) => {
13
+ // The host's first message: answered, it tells the host that what it
14
+ // posts reaches this worker, which it then counts on while the page's
15
+ // thread is blocked (workers.ts).
16
+ if (event.data?.type === "ping") {
17
+ scope.postMessage({ type: "ready" });
18
+ return;
19
+ }
20
+
21
+ receive(event.data);
22
+ };
23
+ },
24
+ });
@@ -0,0 +1,32 @@
1
+ // A binary WebSocket bridge for flash.net.Socket. The caller chooses its URL protocol.
2
+ import type { SocketHost } from "@swf2es/player";
3
+
4
+ /** Map the AS3 host and port to a WebSocket endpoint that relays a byte stream. */
5
+ export function webSocketSocketHost(
6
+ urlFor: (host: string, port: number) => string,
7
+ open: (url: string) => WebSocket = (url) => new WebSocket(url),
8
+ ): SocketHost {
9
+ return {
10
+ connect(host, port, events) {
11
+ const socket = open(urlFor(host, port));
12
+ socket.binaryType = "arraybuffer";
13
+ socket.addEventListener("open", () => events.open());
14
+ socket.addEventListener("message", ({ data }) => {
15
+ if (data instanceof ArrayBuffer) {
16
+ events.data(new Uint8Array(data));
17
+ } else {
18
+ events.error("Socket bridge sent a non-binary WebSocket message.");
19
+ socket.close();
20
+ }
21
+ });
22
+ socket.addEventListener("close", () => events.close());
23
+ socket.addEventListener("error", () => events.error("Error #2031: Socket Error."));
24
+
25
+ return {
26
+ // Browser WebSocket accepts typed arrays; the Socket native supplies ArrayBuffer-backed bytes.
27
+ send: (bytes) => socket.send(bytes as Uint8Array<ArrayBuffer>),
28
+ close: () => socket.close(),
29
+ };
30
+ },
31
+ };
32
+ }
package/src/workers.ts ADDED
@@ -0,0 +1,255 @@
1
+ // The browser's threads for flash.system.Worker (docs/workers.md): each
2
+ // background worker a module Web Worker running web-worker.ts, given
3
+ // codegen's compiled module so that it need not compile it again.
4
+ //
5
+ // A browser loads a Web Worker's modules only while the page's thread is
6
+ // in its event loop, which a primordial blocked in Mutex.lock or
7
+ // Condition.wait is not: Crossbridge starts a thread and waits for it in
8
+ // the same script. So a few workers are started ahead, as Emscripten's
9
+ // thread pool is, and a worker that starts takes one that has loaded,
10
+ // which runs what it is posted whatever the page's thread does; another
11
+ // is started in its place for the next.
12
+ //
13
+ // Nor does a worker that has run its script take the page's messages at
14
+ // once: Chrome holds what the page posts to a Web Worker until the page's
15
+ // thread has run its own task for the script's end, which may come after
16
+ // the worker's first message. A page that blocked first would hold the
17
+ // worker's start until it stopped blocking, past the script timeout. So a
18
+ // worker counts as loaded only once it answers a message the page posted
19
+ // it when it was made.
20
+ import type { WorkerHost } from "@swf2es/player";
21
+ import type { ThreadStart } from "@swf2es/player/worker";
22
+
23
+ export interface WebWorkerHostOptions {
24
+ /** codegen.wasm compiled, as the player's own codegen was made from. */
25
+ codegen: WebAssembly.Module;
26
+ /**
27
+ * The worker script: by default this package's dist/thread/, which
28
+ * holds web-worker.js and the modules it imports with their bare
29
+ * specifiers made relative (build-thread.ts), so that it loads wherever
30
+ * the package is served, as a worker sees no import map. One from
31
+ * another origin, as a CDN's, starts through a module of the page's own
32
+ * that imports it, which a Content-Security-Policy must allow as a
33
+ * worker's `blob:` source.
34
+ */
35
+ url?: string | URL;
36
+ /**
37
+ * How many Web Workers to keep started ahead, for workers a script starts
38
+ * and then waits for without returning to the event loop: by default as
39
+ * many as the machine has cores, from 2 up to 4. The page's hosts for one
40
+ * script URL share them, and they are let go a while after the last
41
+ * player that used them is.
42
+ */
43
+ spares?: number;
44
+ }
45
+
46
+ /** A host of Web Workers, and when the workers it started ahead have loaded. */
47
+ export interface WebWorkerHost extends WorkerHost {
48
+ /**
49
+ * Resolves once the workers started ahead have loaded, or failed to:
50
+ * a page that awaits it before it plays a SWF has them for a script
51
+ * that blocks at once.
52
+ */
53
+ readonly ready: Promise<void>;
54
+ }
55
+
56
+ /** A Web Worker started ahead: whether it has loaded, and the error it failed with meanwhile. */
57
+ interface Spare {
58
+ worker: Worker;
59
+ ready: boolean;
60
+ failed: string | null;
61
+ /** Resolves once it has loaded or failed, whoever took it meanwhile. */
62
+ settled: Promise<void>;
63
+ settle(): void;
64
+ }
65
+
66
+ /**
67
+ * How long after a Web Worker's terminate it is taken to have stopped. A
68
+ * browser does not say, and Chrome lets a busy worker's script run on for
69
+ * some seconds (2.5 to 4 s measured, in Chrome 156) before it stops it by
70
+ * force; Firefox's and Safari's were not measured. The player stops a
71
+ * terminated worker's thread so only when the worker has not stopped
72
+ * itself first (scripting/workers.ts).
73
+ */
74
+ const STOPPED_GRACE = 8000;
75
+
76
+ /** The workers started ahead, by script URL. */
77
+ const pools = new Map<string, Spare[]>();
78
+
79
+ /** How many hosts not yet released use each pool, and the timer that lets an unused one go. */
80
+ const users = new Map<string, { count: number; idle: ReturnType<typeof setTimeout> | null }>();
81
+
82
+ /** How long a pool no player uses keeps its workers, for the next player a page makes. */
83
+ const IDLE = 10_000;
84
+
85
+ function use(url: string | URL): void {
86
+ const key = String(url);
87
+ const u = users.get(key) ?? { count: 0, idle: null };
88
+ if (u.idle !== null) {
89
+ clearTimeout(u.idle);
90
+ u.idle = null;
91
+ }
92
+
93
+ u.count++;
94
+ users.set(key, u);
95
+ }
96
+
97
+ function release(url: string | URL): void {
98
+ const key = String(url);
99
+ const u = users.get(key);
100
+ if (!u || --u.count > 0) {
101
+ return;
102
+ }
103
+
104
+ u.idle = setTimeout(() => {
105
+ for (const spare of pools.get(key) ?? []) {
106
+ spare.settle();
107
+ spare.worker.terminate();
108
+ }
109
+
110
+ pools.delete(key);
111
+ users.delete(key);
112
+ }, IDLE);
113
+ }
114
+
115
+ /** The page's own modules that import a worker script from another origin, by its URL. */
116
+ const importers = new Map<string, string>();
117
+
118
+ function spawn(url: string | URL): Worker {
119
+ const worker = construct(url);
120
+ // Answered with "ready" once the page's messages reach the worker.
121
+ worker.postMessage({ type: "ping" });
122
+ return worker;
123
+ }
124
+
125
+ function construct(url: string | URL): Worker {
126
+ try {
127
+ return new Worker(url, { type: "module" });
128
+ } catch (error) {
129
+ // A browser starts a worker only on a script of the page's origin.
130
+ if (!(error instanceof DOMException && error.name === "SecurityError")) {
131
+ throw error;
132
+ }
133
+
134
+ const href = new URL(url, globalThis.location?.href).href;
135
+ let importer = importers.get(href);
136
+ if (importer === undefined) {
137
+ const source = `import ${JSON.stringify(href)};`;
138
+ importer = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
139
+ importers.set(href, importer);
140
+ }
141
+
142
+ return new Worker(importer, { type: "module" });
143
+ }
144
+ }
145
+
146
+ /** Keep `count` workers started ahead for `url`; where the page cannot start one, fewer. */
147
+ function fill(url: string | URL, count: number): Spare[] {
148
+ const key = String(url);
149
+ let pool = pools.get(key);
150
+ if (!pool) {
151
+ pool = [];
152
+ pools.set(key, pool);
153
+ }
154
+
155
+ while (pool.length < count) {
156
+ let worker: Worker;
157
+ try {
158
+ worker = spawn(url);
159
+ } catch {
160
+ // A policy that forbids the script: start() reports it.
161
+ break;
162
+ }
163
+
164
+ let settle = () => {};
165
+ const spare: Spare = {
166
+ worker,
167
+ ready: false,
168
+ failed: null,
169
+ settled: new Promise((resolve) => {
170
+ settle = resolve;
171
+ }),
172
+ settle: () => settle(),
173
+ };
174
+ worker.onmessage = (event) => {
175
+ if (event.data?.type === "ready") {
176
+ spare.ready = true;
177
+ spare.settle();
178
+ }
179
+ };
180
+ worker.onerror = (event) => {
181
+ event.preventDefault();
182
+ spare.failed = event.message;
183
+ spare.settle();
184
+ };
185
+ pool.push(spare);
186
+ }
187
+
188
+ return pool;
189
+ }
190
+
191
+ /** The pool's first worker that has loaded, else its first that has not failed. */
192
+ function take(pool: Spare[]): Spare | undefined {
193
+ for (const spare of pool.filter((s) => s.failed !== null)) {
194
+ spare.worker.terminate();
195
+ pool.splice(pool.indexOf(spare), 1);
196
+ }
197
+
198
+ const at = Math.max(
199
+ pool.findIndex((s) => s.ready),
200
+ 0,
201
+ );
202
+ return pool.splice(at, 1)[0];
203
+ }
204
+
205
+ /** Background workers on module Web Workers. */
206
+ export function webWorkerHost(options: WebWorkerHostOptions): WebWorkerHost {
207
+ const url = options.url ?? new URL("./thread/player-hosts/web-worker.js", import.meta.url);
208
+ const cores = (globalThis as { navigator?: { hardwareConcurrency?: number } }).navigator
209
+ ?.hardwareConcurrency;
210
+ const spares = options.spares ?? Math.min(4, Math.max(2, cores ?? 2));
211
+ use(url);
212
+ const pool = fill(url, spares);
213
+ let released = false;
214
+ return {
215
+ ready: Promise.all(pool.map((s) => s.settled)).then(() => {}),
216
+ release() {
217
+ if (!released) {
218
+ released = true;
219
+ release(url);
220
+ }
221
+ },
222
+ start(init, receive, failed) {
223
+ const spare = take(fill(url, spares));
224
+ const worker = spare?.worker ?? spawn(url);
225
+ // One in its place, loaded once the page's thread is free.
226
+ fill(url, spares);
227
+ // Taken before it loaded, it still settles the ready of the host that started it ahead.
228
+ worker.onmessage = (event) => {
229
+ // A worker taken before it loaded says so first.
230
+ if (event.data?.type === "ready") {
231
+ spare?.settle();
232
+ } else {
233
+ receive(event.data);
234
+ }
235
+ };
236
+ worker.onerror = (event) => {
237
+ event.preventDefault();
238
+ spare?.settle();
239
+ worker.terminate();
240
+ failed(new Error(`a background worker's thread failed: ${event.message}`));
241
+ };
242
+ const start: ThreadStart = { codegen: options.codegen, init };
243
+ worker.postMessage(start);
244
+ return {
245
+ post: (message) => worker.postMessage(message),
246
+ // A browser tells nobody when a Web Worker has stopped.
247
+ terminate: () => {
248
+ spare?.settle();
249
+ worker.terminate();
250
+ return new Promise((resolve) => setTimeout(resolve, STOPPED_GRACE));
251
+ },
252
+ };
253
+ },
254
+ };
255
+ }