chrisguttandin / timing-object

An implementation of the timing object specification.
MIT License
38 stars 1 forks source link

Can it be used in NodeJS? #228

Open LamentOfKaito opened 1 year ago

LamentOfKaito commented 1 year ago

TimingObject is a useful concept/API, but it relies on Web-specific APIs* to work. Other than that, this package is useful outside of brower environments. * Like TNativeEventTarget and event-target-factory.ts

Is it not possible to create a bundle for node where we use a polyfilled version of EventTarget (like https://www.npmjs.com/package/@ungap/event-target) or a different module altogether (node:events or the events package)?

As a side note, in event-target-factory, you are creating a <p> element just to use it as an EventTarget, even though you could create an instance of EventTarget (or a subclass) directly. This should reduce memory allocated and, more importantly, makes the code a little less dependent on the DOM.

See: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget

LamentOfKaito commented 1 year ago

One last point: Assuming we only use EventTarget (and not window.document.createElement), one can easily shim it using webpack

+  plugins: [
+    new webpack.ProvidePlugin({
+      EventTarget: '@ungap/event-target',
+    }),
+  ],

See: https://webpack.js.org/guides/shimming/

chrisguttandin commented 1 year ago

Hi @ReprimandedKaito,

I believe the usage of a paragraph as an EventTarget was a workaround because at the time there was no EventTarget constructor available in all browsers.

But luckily this has changed: https://caniuse.com/?search=EventTarget%20constructor.

And even better it's meanwhile also available in Node.js: https://nodejs.org/dist/latest-v20.x/docs/api/events.html#eventtarget-and-event-api.

Does it work if you manually replace the current code?

return () => {
    if (window === null) {
        throw new Error('A native EventTarget could not be created.');
    }

    return window.document.createElement('p');
};
return () => new EventTarget();

Or is there anything else which fails on Node.js?

LamentOfKaito commented 1 year ago

I don't know how I missed that. I knew about NodeEventTarget (which we can't use) but totally missed EventTarget.

I have edited the bundled version (build/es5/bundle.js) as you suggested

    var createEventTargetFactory = function createEventTargetFactory(window) {
      return function () {
-        if (window === null) {
-          throw new Error('A native EventTarget could not be created.');
-        }
-        return window.document.createElement('p');
+       return new EventTarget();
    };

and tested it on node v18.13. Everything seems to be working fine:

const {TimingObject} = require('timing-object');

const timingObject = new TimingObject();
timingObject.update({position: 0, velocity: 1});
timingObject.query();