bloodyKnuckles / cycle-web-worker

Cycle.js Web Worker
12 stars 0 forks source link

A Different Interface? #1

Open aronallen opened 8 years ago

aronallen commented 8 years ago

So basically what I would like to do is to mount a component in a WebWorker context. It would work kind of like isolate except it would spin up the passed component in a WebWorker context.

To give the component in the WebWorker access to the API and DOM Source, we would need some DSL to specify the intents, furthermore since we can only pipe strings to and from the worker process, we need to convert the returned DOM stream from a string into snabbdom, there is a module called snabbdom-virtualize which can take a string and pass it into snabbdom. Going into the worker we would need to serialize DOM events, and perhaps even DOM elements.

A component running in a WebWorker would need to be more limited than a traditional Cycle component, and it would need some extra boilerplate, where it can communicate the intents in a DSL on start up.

Furthermore a developer should be able to define a transducer for a source, which would stringify incoming source events. And a transducer for the sink which would convert outgoing sink events.

Finally they need a initialization function that receives DSL commands for each source, and sets up listeners for those in a secure way, this DSL function should securely receive some strings, that it then evaluates and uses to call each source.

The DSL for communicating the intents could look something like this DOM select 'world' events 'click' API filter '/api/search' mergeAll It is not clear to me how it would work with higher order streams.

bloodyKnuckles commented 8 years ago

I think I get it, you're wanting to run the "main" cycle app in the main (UI) thread, and have the option to run sub-apps, or processes, in a web worker.

The first thing that comes to mind to look at, for at least inspiration regarding an events channel, is this generalized module I pulled out of the cycle-web-worker:

https://github.com/bloodyKnuckles/worker-event-bridge

bloodyKnuckles commented 8 years ago

(Thinking "out loud.") The cycle-web-worker project has a web worker driver:

https://github.com/bloodyKnuckles/cycle-web-worker/blob/master/src/makeWWDriver.js

This driver is situated in a web worker, so it's connection to the main thread is (singularly):

self.addEventListener('message' ...
self.postMessage ...

For a driver situated in the main thread it's connection to other threads would be the instantiated thread variable, such as:

var worker1 = new Worker('./worker1.js')
worker1.addEventListener('message' ...
worker1.postMessage ...

var worker2 = new Worker('./worker2.js')
worker2.addEventListener('message' ...
worker2.postMessage ...
bloodyKnuckles commented 8 years ago

A little more thinking here...

I see four Cycle.js web worker "situations":

  1. Driver in a web worker, communicates with main (cycle-web-worker),
  2. Driver in main thread, communicates with a web worker,
  3. Component in a web worker, communicates with main, and
  4. Component in main thread, communicates with a web worker.

The drivers would be for "impure/side-effect" type processes, and components would be for pure processes.

bloodyKnuckles commented 8 years ago

This might provide some inspiration:

https://github.com/deebloo/rxjs-worker

RXJS extensions for adding web worker functionality via operators and observables

// web worker
const myWorker = new Worker('path/to/web-worker.js');
const observable1 = Observable.fromWorker(myWorker);

// function
const observable2 = Observable.fromWorker(() => {
  self.postMessage('Hello World');
});

// string
const observable3 = Observable.fromWorker('path/to/web-worker.js');