Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,123 @@
/* global Process */
'use strict';
/**
* Combine the abilities of the event handling and asynchronous operations
* sequentializing together. So that every Stream could:
*
* 1. For the ordinary events, append steps to the main Process to queue
* the event handlers.
* 2. For other urgent events (interrupts), immediately execute the event
* handler without queuing it.
* 3. Only receive events when it's 'ready'. Before that, no source events
* would be forwarded and handled.
* 4. Once phase becomes 'stop', no events would be received again.
**/
(function(exports) {
var Stream = function(configs) {
this.configs = {
events: configs.events || [],
interrupts: configs.interrupts || []
};
if (configs.sources && 0 !== configs.sources.length) {
this.configs.sources = configs.sources;
} else {
this.configs.sources = [];
}
this._forwardTo = null;
// Need to delegate to Source.
this.onchange = this.onchange.bind(this);
};
Stream.prototype.phase = function() {
return this.process.states.phase;
};
Stream.prototype.start = function(forwardTo) {
this._forwardTo = forwardTo;
this.process = new Process();
this.process.start();
return this;
};
/**
* Kick off Source and start do things.
*/
Stream.prototype.ready = function() {
this.configs.sources.forEach((source) => {
source.start(this.onchange);
});
return this;
};
Stream.prototype.stop = function() {
this.process.stop();
this.configs.sources.forEach((source) => {
source.stop();
});
return this;
};
Stream.prototype.destroy = function() {
this.process.destroy();
return this;
};
Stream.prototype.next = function(step) {
this.process.next(step);
return this;
};
Stream.prototype.rescue = function(rescuer) {
this.process.rescue(rescuer);
return this;
};
/**
* Return a Promise get resolved when the stream turn to
* the specific phase. For example:
*
* stream.until('stop')
* .then(() => { console.log('stream stopped') });
* stream.start();
*/
Stream.prototype.until = function(phase) {
return this.process.until(phase);
};
/**
* Only when all tasks passed in get resolved,
* the process would go to the next.
*/
Stream.prototype.wait = function(tasks) {
this.process.wait(tasks);
return this;
};
/**
* It would receive events from Source, and than queue or not queue
* it, depends on whether the event is an interrupt.
*/
Stream.prototype.onchange = function(evt) {
if ('start' !== this.process.states.phase) {
return this;
}
if (-1 !== this.configs.interrupts.indexOf(evt.type)) {
// Interrupt would be handled immediately.
this._forwardTo(evt);
return this;
} else {
// Event would be handled after queuing.
// This is, if the event handle return a Promise or Process,
// that can be fulfilled later.
this.process.next(() => {
return this._forwardTo(evt);
});
return this;
}
};
exports.Stream = Stream;
})(window);