todo/js/utilities/JSResource.js (45 lines of code) (raw):
// @flow
/**
* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import type {JSResourceReference} from 'JSResourceReference';
class Resource<T> implements JSResourceReference<T> {
static map: Map<string, Resource<T>> = new Map();
_moduleId: string;
_loader: () => Promise<T>;
_loadingPromise: ?Promise<T>;
_module: ?T;
constructor(moduleId: string, loader: () => Promise<T>) {
this._moduleId = moduleId;
this._loader = loader;
this._loadingPromise = undefined;
this._module = undefined;
}
getModuleId(): string {
return this._moduleId;
}
getModuleIfRequired(): ?T {
return this._module;
}
load(): Promise<T> {
if (!this._loadingPromise) {
this._loadingPromise = this._loader()
.then((module: T) => {
this._module = module;
return this._module;
})
.catch((error) => {
console.log(error);
throw error;
});
}
return this._loadingPromise;
}
}
export default function JSResource<T>(
moduleId: string,
loader: () => Promise<T>,
): JSResourceReference<T> {
let resource = Resource.map.get(moduleId);
if (resource == null) {
resource = new Resource(moduleId, loader);
Resource.map.set(moduleId, resource);
}
return resource;
}