UNPKG

@modern-js/runtime-utils

Version:

A Progressive React Framework for modern web development.

162 lines (161 loc) • 6.03 kB
"use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.d = (exports1, definition)=>{ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { enumerable: true, get: definition[key] }); }; })(); (()=>{ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); })(); (()=>{ __webpack_require__.r = (exports1)=>{ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { value: 'Module' }); Object.defineProperty(exports1, '__esModule', { value: true }); }; })(); var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { AbortedDeferredError: ()=>AbortedDeferredError, DeferredData: ()=>DeferredData, activeDeferreds: ()=>activeDeferreds, invariant: ()=>invariant }); function invariant(value, message) { if (false === value || null == value) throw new Error(message); } class AbortedDeferredError extends Error { } function isTrackedPromise(value) { return value instanceof Promise && true === value._tracked; } function unwrapTrackedPromise(value) { if (!isTrackedPromise(value)) return value; if (value._error) throw value._error; return value._data; } class DeferredData { trackPromise(key, value) { if (!(value instanceof Promise)) return value; this.deferredKeys.push(key); this.pendingKeysSet.add(key); const promise = Promise.race([ value, this.abortPromise ]).then((data)=>this.onSettle(promise, key, void 0, data), (error)=>this.onSettle(promise, key, error)); promise.catch(()=>{}); Object.defineProperty(promise, '_tracked', { get: ()=>true }); return promise; } onSettle(promise, key, error, data) { if (this.controller.signal.aborted && error instanceof AbortedDeferredError) { this.unlistenAbortSignal(); Object.defineProperty(promise, '_error', { get: ()=>error }); return Promise.reject(error); } this.pendingKeysSet.delete(key); if (this.done) this.unlistenAbortSignal(); if (void 0 === error && void 0 === data) { const undefinedError = new Error(`Deferred data for key "${key}" resolved/rejected with \`undefined\`, you must resolve/reject with a value or \`null\`.`); Object.defineProperty(promise, '_error', { get: ()=>undefinedError }); this.emit(false, key); return Promise.reject(undefinedError); } if (void 0 === data) { Object.defineProperty(promise, '_error', { get: ()=>error }); this.emit(false, key); return Promise.reject(error); } Object.defineProperty(promise, '_data', { get: ()=>data }); this.emit(false, key); return data; } emit(aborted, settledKey) { this.subscribers.forEach((subscriber)=>subscriber(aborted, settledKey)); } subscribe(fn) { this.subscribers.add(fn); return ()=>this.subscribers.delete(fn); } cancel() { this.controller.abort(); this.pendingKeysSet.forEach((v, k)=>this.pendingKeysSet.delete(k)); this.emit(true); } async resolveData(signal) { let aborted = false; if (!this.done) { const onAbort = ()=>this.cancel(); signal.addEventListener('abort', onAbort); aborted = await new Promise((resolve)=>{ this.subscribe((aborted)=>{ signal.removeEventListener('abort', onAbort); if (aborted || this.done) resolve(aborted); }); }); } return aborted; } get done() { return 0 === this.pendingKeysSet.size; } get unwrappedData() { invariant(null !== this.data && this.done, 'Can only unwrap data on initialized and settled deferreds'); return Object.entries(this.data).reduce((acc, [key, value])=>Object.assign(acc, { [key]: unwrapTrackedPromise(value) }), {}); } get pendingKeys() { return Array.from(this.pendingKeysSet); } constructor(data, responseInit){ this.pendingKeysSet = new Set(); this.subscribers = new Set(); this.__modern_deferred = true; this.deferredKeys = []; invariant(data && 'object' == typeof data && !Array.isArray(data), 'defer() only accepts plain objects'); let reject; this.abortPromise = new Promise((_, r)=>reject = r); this.controller = new AbortController(); const onAbort = ()=>reject(new AbortedDeferredError('Deferred data aborted')); this.unlistenAbortSignal = ()=>this.controller.signal.removeEventListener('abort', onAbort); this.controller.signal.addEventListener('abort', onAbort); this.data = Object.entries(data).reduce((acc, [key, value])=>Object.assign(acc, { [key]: this.trackPromise(key, value) }), {}); if (this.done) this.unlistenAbortSignal(); this.init = responseInit; } } const activeDeferreds = new Map(); exports.AbortedDeferredError = __webpack_exports__.AbortedDeferredError; exports.DeferredData = __webpack_exports__.DeferredData; exports.activeDeferreds = __webpack_exports__.activeDeferreds; exports.invariant = __webpack_exports__.invariant; for(var __rspack_i in __webpack_exports__)if (-1 === [ "AbortedDeferredError", "DeferredData", "activeDeferreds", "invariant" ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i]; Object.defineProperty(exports, '__esModule', { value: true });