[Evolution Proposition] Full rewrite of Wave.js in Typescript, general improvements & fixes
korbav opened this issue · comments
Hello @foobar404,
Since we are more and more persons to use Wave.js, I think this is the right moment to go a step further and to rewrite the library to make it cleaner, more consistent, and easier to maintain, using Typescript.
I spent some days on this task and I'm coming with an available tested proposition.
Since it would be a huge PR and I'm not sure how you wish (or don't wish) to integrate it, I put the proposition in my own temporary repository for the moment. You can take a look and decide what to do with it Here.
I'd be happy to help you with the integration if you need anything.
I tried to address the following concerns :
- Taking benefit of all typescript features.
- Typing variables (safer usage, clearer exposure, compiler checks benefit, easier readability & easier maintainability, autocompletion).
- Separation (isolation) of concerns for the different helpers (eg.
skipUserCheck
is only used withfromElement
). - Sanitization (Removing dead code, useless variables, optimizing code when possible, adding more consistency to the style).
- Using ESLint to adopt strong standards and protect commits.
- Using Webpack to facilitate (and make it more customizable) the build generation.
- Removal of draw-round-layers (was not doing anything,
origamijs
is no longer needed). - Creating unit tests with the
Jest
framework (It would be wonderful to increase the coverage rate in the future). - Using "standardized-audio-context" to deal with browsers specificities.
- Important note about
fromFile
: From my understanding, this helper is supposed to regularly call a callback with a single argument corresponding to a base64 image. If so, according to the code base, it seems this one was not correctly implemented (calling the callback at 'ended' event instead of during playing, I adjusted it correspondingly to make it work based on the understanding explained right before). - Adding width & height options for
fromFile
(which will allow optimizing the rendering and will still default to window size) - Adding an
existingMediaStreamSource
option tofromElement
options, so that if the user already has a source it can pass it to be used safely without facing an Error from the browser. Null by default. Useful if, for example, an existing source does exist on the audio element (to apply audio effects for example). - Adding a format parameter to be used to render the canvas with
fromFile
, default to"png"
- Fixing the multi-types feature (that was not working for me,
ctx.clearRect(0, 0, w, h)
was being called for each type instead of once before all). - Automatically closing the
AudioContext
for all 3 helpers, except if anexistingMediaStreamSource
is passed tofromElement
helper, if so, then it's not expectable to close the context since it's been created externally and might be still in use somewhere else. - Removing the "react-test" since it will lead to incompatibility issues with babel-jest that we are now using, creating instead 3 examples with vanilla js in examples/ folder. Appropriate npm scripts are available to launch these examples (npm run example-from-file /npm run example-from-stream /npm run example-from-element).
- The
fromElement
example shows an advanced example of multiple canvas with multiple effects on each one, the 2 other examples are basic. WaveJS.fromStream(...)
,WaveJS.fromFile(...)
andWaveJS.fromElement(...)
will now all return a on object containing adeactivate()
method. This method will stop all the operations (the examples files use it to automatically deactivate the visualizers after an arbitrary time of 10 seconds). If needed, in the future, we will be able to add more methods to this object in order to have more control over the current execution.- When used inside a browser, the library is available through the global object
WaveJS
. - When used server-side or with ES6, the library is available using
import WaveJS from 'wave.js-typescript';
and hopefully after the integration:import WaveJS from '@foobar404/wave';
.
The spirit and the usage of the library have not been altered. Though, there's a breaking change (which led me to set the 2.0.0 version) with the options parameter since it's now proper to different handlers (fromFile
, fromStream
, fromElement
).
These per-helper options must now be passed as a third argument instead of being mixed with the second argument.
This rewrite might also address the following issues :
And it integrates the following PRs :
Thank you for putting this together. I'd also recommend adding the ability for users to load their own custom visualizers. That way you wouldn't be limited to the built in ones. We'd need to standardize the API around this change. See #3 for a user who wanted this feature.
Also, in my opinion, the tying together audio and canvas elements leads to a lot of boilerplate code. If we could move to a Web Component oriented mindset, that'd be best for those wanting just a drop in solution. I'll start brainstorming ideas in this space and might add them below. Open WC is an example library which many projects use to implement Web Components
Thank you for putting this together. I'd also recommend adding the ability for users to load their own custom visualizers. That way you wouldn't be limited to the built in ones. We'd need to standardize the API around this change. See #3 for a user who wanted this feature.
Also, in my opinion, the tying together audio and canvas elements leads to a lot of boilerplate code. If we could move to a Web Component oriented mindset, that'd be best for those wanting just a drop in solution. I'll start brainstorming ideas in this space and might add them below. Open WC is an example library which many projects use to implement Web Components
Hi @JackWolfard, that would be really interesting to get this way. I'd be glad to take a look at your insights.
@korbav hey, I cant find any contact information for you. But I wanted to reach out and ask if you would be interested in helping me work on version 2.0.0 of wave.js. I'm currently working on a rewrite in typescript using webpack, I have a few new features in mind, let me know what you think.