mirror of
https://github.com/swc-project/swc.git
synced 2024-11-28 02:29:04 +03:00
fix(es/minifer): Fix handling of callable expressions (#2379)
swc_ecma_minifier: - `sequences`: Don't inline into arrow expression or function expressions. - Inject variables to arrow expressions correctly.
This commit is contained in:
parent
be3dca295b
commit
ab687a0f98
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -3446,7 +3446,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_minifier"
|
||||
version = "0.37.0"
|
||||
version = "0.37.1"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"anyhow",
|
||||
|
@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs", "src/lists/*.json"]
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecma_minifier"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.37.0"
|
||||
version = "0.37.1"
|
||||
|
||||
[features]
|
||||
debug = ["backtrace"]
|
||||
|
@ -7,7 +7,7 @@ use self::{
|
||||
use crate::{
|
||||
analyzer::{analyze, ProgramData, UsageAnalyzer},
|
||||
compress::hoist_decls::decl_hoister,
|
||||
debug::{dump, invoke},
|
||||
debug::dump,
|
||||
marks::Marks,
|
||||
mode::Mode,
|
||||
option::CompressOptions,
|
||||
@ -217,6 +217,8 @@ where
|
||||
}
|
||||
|
||||
loop {
|
||||
n.invoke();
|
||||
|
||||
self.changed = false;
|
||||
self.optimize_unit(n);
|
||||
self.pass += 1;
|
||||
@ -439,8 +441,6 @@ where
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
self.optimize_unit_repeatedly(n);
|
||||
|
||||
invoke(&*n);
|
||||
}
|
||||
|
||||
fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
|
||||
|
@ -19,8 +19,8 @@ use swc_common::{
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{
|
||||
ident::IdentLike, undefined, ExprExt, ExprFactory, Id, IsEmpty, ModuleItemLike, StmtLike, Type,
|
||||
Value,
|
||||
ident::IdentLike, prepend_stmts, undefined, ExprExt, ExprFactory, Id, IsEmpty, ModuleItemLike,
|
||||
StmtLike, Type, Value,
|
||||
};
|
||||
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
|
||||
use tracing::{span, Level};
|
||||
@ -1482,12 +1482,39 @@ where
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_arrow_expr(&mut self, n: &mut ArrowExpr) {
|
||||
let prepend = self.prepend_stmts.take();
|
||||
|
||||
let ctx = Ctx {
|
||||
can_inline_arguments: true,
|
||||
..self.ctx
|
||||
};
|
||||
|
||||
n.visit_mut_children_with(&mut *self.with_ctx(ctx));
|
||||
|
||||
if !self.prepend_stmts.is_empty() {
|
||||
let mut stmts = self.prepend_stmts.take();
|
||||
match &mut n.body {
|
||||
BlockStmtOrExpr::BlockStmt(v) => {
|
||||
prepend_stmts(&mut v.stmts, stmts.into_iter());
|
||||
}
|
||||
BlockStmtOrExpr::Expr(v) => {
|
||||
self.changed = true;
|
||||
if cfg!(feature = "debug") {
|
||||
tracing::debug!("Convertng a body of an arrow expression to BlockStmt");
|
||||
}
|
||||
stmts.push(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(v.take()),
|
||||
}));
|
||||
n.body = BlockStmtOrExpr::BlockStmt(BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
stmts,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.prepend_stmts = prepend;
|
||||
}
|
||||
|
||||
fn visit_mut_assign_expr(&mut self, e: &mut AssignExpr) {
|
||||
@ -1564,6 +1591,18 @@ where
|
||||
n.visit_mut_children_with(&mut *self.with_ctx(ctx));
|
||||
}
|
||||
|
||||
fn visit_mut_block_stmt_or_expr(&mut self, n: &mut BlockStmtOrExpr) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
match n {
|
||||
BlockStmtOrExpr::BlockStmt(n) => {
|
||||
self.merge_if_returns(&mut n.stmts, false, true);
|
||||
self.drop_else_token(&mut n.stmts);
|
||||
}
|
||||
BlockStmtOrExpr::Expr(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_call_expr(&mut self, e: &mut CallExpr) {
|
||||
let inline_prevented = self.ctx.inline_prevented || self.has_noinline(e.span);
|
||||
|
||||
|
@ -950,7 +950,7 @@ where
|
||||
}
|
||||
|
||||
match b {
|
||||
Expr::Update(..) => return false,
|
||||
Expr::Update(..) | Expr::Arrow(..) | Expr::Fn(..) => return false,
|
||||
|
||||
Expr::Cond(b) => {
|
||||
tracing::trace!("seq: Try test of cond");
|
||||
|
@ -90,6 +90,16 @@ where
|
||||
});
|
||||
}
|
||||
|
||||
fn optimize_fn_stmts(&mut self, stmts: &mut Vec<Stmt>) {
|
||||
self.remove_useless_return(stmts);
|
||||
|
||||
self.negate_if_terminate(stmts, true, false);
|
||||
|
||||
if let Some(last) = stmts.last_mut() {
|
||||
self.drop_unused_stmt_at_end_of_fn(last);
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit `nodes`, maybe in parallel.
|
||||
fn visit_par<N>(&mut self, nodes: &mut Vec<N>)
|
||||
where
|
||||
@ -170,6 +180,11 @@ where
|
||||
fn visit_mut_block_stmt_or_expr(&mut self, body: &mut BlockStmtOrExpr) {
|
||||
body.visit_mut_children_with(self);
|
||||
|
||||
match body {
|
||||
BlockStmtOrExpr::BlockStmt(b) => self.optimize_fn_stmts(&mut b.stmts),
|
||||
BlockStmtOrExpr::Expr(_) => {}
|
||||
}
|
||||
|
||||
self.optimize_arrow_body(body);
|
||||
}
|
||||
|
||||
@ -328,13 +343,7 @@ where
|
||||
}
|
||||
|
||||
if let Some(body) = &mut f.body {
|
||||
self.remove_useless_return(&mut body.stmts);
|
||||
|
||||
self.negate_if_terminate(&mut body.stmts, true, false);
|
||||
|
||||
if let Some(last) = body.stmts.last_mut() {
|
||||
self.drop_unused_stmt_at_end_of_fn(last);
|
||||
}
|
||||
self.optimize_fn_stmts(&mut body.stmts)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,5 +102,9 @@ pub(crate) fn invoke(module: &Module) {
|
||||
);
|
||||
}
|
||||
|
||||
tracing::info!("[SWC_RUN]\n{}", String::from_utf8_lossy(&output.stdout))
|
||||
tracing::info!(
|
||||
"[SWC_RUN]\n{}\n{}",
|
||||
code,
|
||||
String::from_utf8_lossy(&output.stdout)
|
||||
)
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ pub(crate) trait CompileUnit:
|
||||
V: VisitMut;
|
||||
|
||||
fn remove_mark(&mut self) -> Mark;
|
||||
|
||||
fn invoke(&self);
|
||||
}
|
||||
|
||||
impl CompileUnit for Module {
|
||||
@ -39,6 +41,10 @@ impl CompileUnit for Module {
|
||||
fn remove_mark(&mut self) -> Mark {
|
||||
Mark::root()
|
||||
}
|
||||
|
||||
fn invoke(&self) {
|
||||
crate::debug::invoke(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl CompileUnit for FnExpr {
|
||||
@ -60,4 +66,6 @@ impl CompileUnit for FnExpr {
|
||||
fn remove_mark(&mut self) -> Mark {
|
||||
self.function.span.remove_mark()
|
||||
}
|
||||
|
||||
fn invoke(&self) {}
|
||||
}
|
||||
|
@ -2897,15 +2897,15 @@
|
||||
}, {
|
||||
unsafe: !0
|
||||
});
|
||||
} else $DataView = function(buffer, byteOffset, byteLength) {
|
||||
anInstance(this, $DataView, "DataView"), anInstance(buffer, $ArrayBuffer = function(length) {
|
||||
anInstance(this, $ArrayBuffer, "ArrayBuffer");
|
||||
var byteLength = toIndex(length);
|
||||
setInternalState(this, {
|
||||
bytes: arrayFill.call(new Array(byteLength), 0),
|
||||
byteLength: byteLength
|
||||
}), DESCRIPTORS || (this.byteLength = byteLength);
|
||||
}, "DataView");
|
||||
} else $ArrayBuffer = function(length) {
|
||||
anInstance(this, $ArrayBuffer, "ArrayBuffer");
|
||||
var byteLength = toIndex(length);
|
||||
setInternalState(this, {
|
||||
bytes: arrayFill.call(new Array(byteLength), 0),
|
||||
byteLength: byteLength
|
||||
}), DESCRIPTORS || (this.byteLength = byteLength);
|
||||
}, $DataView = function(buffer, byteOffset, byteLength) {
|
||||
anInstance(this, $DataView, "DataView"), anInstance(buffer, $ArrayBuffer, "DataView");
|
||||
var bufferLength = getInternalState(buffer).byteLength, offset = toInteger(byteOffset);
|
||||
if (offset < 0 || offset > bufferLength) throw RangeError("Wrong offset");
|
||||
if (offset + (byteLength = void 0 === byteLength ? bufferLength - offset : toLength(byteLength)) > bufferLength) throw RangeError("Wrong length");
|
||||
@ -7678,23 +7678,23 @@
|
||||
var fixRegExpWellKnownSymbolLogic = __webpack_require__(29045), isRegExp = __webpack_require__(78202), anObject = __webpack_require__(83941), requireObjectCoercible = __webpack_require__(79602), speciesConstructor = __webpack_require__(94850), advanceStringIndex = __webpack_require__(88770), toLength = __webpack_require__(31998), toString = __webpack_require__(72729), getMethod = __webpack_require__(84316), callRegExpExec = __webpack_require__(21135), regexpExec = __webpack_require__(72384), stickyHelpers = __webpack_require__(44725), fails = __webpack_require__(60232), UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y, arrayPush = [].push, min = Math.min;
|
||||
fixRegExpWellKnownSymbolLogic("split", function(SPLIT, nativeSplit, maybeCallNative) {
|
||||
var internalSplit;
|
||||
return [function(separator, limit) {
|
||||
return internalSplit = "c" == "abbc".split(/(b)*/)[1] || 4 != "test".split(/(?:)/, -1).length || 2 != "ab".split(/(?:ab)*/).length || 4 != ".".split(/(.?)(.?)/).length || ".".split(/()()/).length > 1 || "".split(/.?/).length ? function(separator, limit) {
|
||||
var match, lastIndex, lastLength, string = toString(requireObjectCoercible(this)), lim = void 0 === limit ? 4294967295 : limit >>> 0;
|
||||
if (0 === lim) return [];
|
||||
if (void 0 === separator) return [
|
||||
string
|
||||
];
|
||||
if (!isRegExp(separator)) return nativeSplit.call(string, separator, lim);
|
||||
for(var output = [], flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.unicode ? "u" : "") + (separator.sticky ? "y" : ""), lastLastIndex = 0, separatorCopy = new RegExp(separator.source, flags + "g"); match = regexpExec.call(separatorCopy, string);){
|
||||
if ((lastIndex = separatorCopy.lastIndex) > lastLastIndex && (output.push(string.slice(lastLastIndex, match.index)), match.length > 1 && match.index < string.length && arrayPush.apply(output, match.slice(1)), lastLength = match[0].length, lastLastIndex = lastIndex, output.length >= lim)) break;
|
||||
separatorCopy.lastIndex === match.index && separatorCopy.lastIndex++;
|
||||
}
|
||||
return lastLastIndex === string.length ? (lastLength || !separatorCopy.test("")) && output.push("") : output.push(string.slice(lastLastIndex)), output.length > lim ? output.slice(0, lim) : output;
|
||||
} : "0".split(void 0, 0).length ? function(separator, limit) {
|
||||
return void 0 === separator && 0 === limit ? [] : nativeSplit.call(this, separator, limit);
|
||||
} : nativeSplit, [function(separator, limit) {
|
||||
var O = requireObjectCoercible(this), splitter = void 0 == separator ? void 0 : getMethod(separator, SPLIT);
|
||||
return splitter ? splitter.call(separator, O, limit) : (internalSplit = "c" == "abbc".split(/(b)*/)[1] || 4 != "test".split(/(?:)/, -1).length || 2 != "ab".split(/(?:ab)*/).length || 4 != ".".split(/(.?)(.?)/).length || ".".split(/()()/).length > 1 || "".split(/.?/).length ? function(separator, limit) {
|
||||
var match, lastIndex, lastLength, string = toString(requireObjectCoercible(this)), lim = void 0 === limit ? 4294967295 : limit >>> 0;
|
||||
if (0 === lim) return [];
|
||||
if (void 0 === separator) return [
|
||||
string
|
||||
];
|
||||
if (!isRegExp(separator)) return nativeSplit.call(string, separator, lim);
|
||||
for(var output = [], flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.unicode ? "u" : "") + (separator.sticky ? "y" : ""), lastLastIndex = 0, separatorCopy = new RegExp(separator.source, flags + "g"); match = regexpExec.call(separatorCopy, string);){
|
||||
if ((lastIndex = separatorCopy.lastIndex) > lastLastIndex && (output.push(string.slice(lastLastIndex, match.index)), match.length > 1 && match.index < string.length && arrayPush.apply(output, match.slice(1)), lastLength = match[0].length, lastLastIndex = lastIndex, output.length >= lim)) break;
|
||||
separatorCopy.lastIndex === match.index && separatorCopy.lastIndex++;
|
||||
}
|
||||
return lastLastIndex === string.length ? (lastLength || !separatorCopy.test("")) && output.push("") : output.push(string.slice(lastLastIndex)), output.length > lim ? output.slice(0, lim) : output;
|
||||
} : "0".split(void 0, 0).length ? function(separator, limit) {
|
||||
return void 0 === separator && 0 === limit ? [] : nativeSplit.call(this, separator, limit);
|
||||
} : nativeSplit).call(toString(O), separator, limit);
|
||||
return splitter ? splitter.call(separator, O, limit) : internalSplit.call(toString(O), separator, limit);
|
||||
}, function(string, limit) {
|
||||
var rx = anObject(this), S = toString(string), res = maybeCallNative(internalSplit, rx, S, limit, internalSplit !== nativeSplit);
|
||||
if (res.done) return res.value;
|
||||
@ -9315,21 +9315,21 @@
|
||||
Object.assign(current, value);
|
||||
}
|
||||
});
|
||||
var extendStatics, lib_router = router, __extends = function(d, b) {
|
||||
var extendStatics, lib_router = router, __extends = (extendStatics = function(d, b) {
|
||||
return (extendStatics = Object.setPrototypeOf || ({
|
||||
__proto__: []
|
||||
}) instanceof Array && function(d, b) {
|
||||
d.__proto__ = b;
|
||||
} || function(d, b) {
|
||||
for(var p in b)Object.prototype.hasOwnProperty.call(b, p) && (d[p] = b[p]);
|
||||
})(d, b);
|
||||
}, function(d, b) {
|
||||
if ("function" != typeof b && null !== b) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
function __() {
|
||||
this.constructor = d;
|
||||
}
|
||||
(extendStatics = function(d, b) {
|
||||
return (extendStatics = Object.setPrototypeOf || ({
|
||||
__proto__: []
|
||||
}) instanceof Array && function(d, b) {
|
||||
d.__proto__ = b;
|
||||
} || function(d, b) {
|
||||
for(var p in b)Object.prototype.hasOwnProperty.call(b, p) && (d[p] = b[p]);
|
||||
})(d, b);
|
||||
})(d, b), d.prototype = null === b ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
}, visibleListeners = {
|
||||
extendStatics(d, b), d.prototype = null === b ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
}), visibleListeners = {
|
||||
};
|
||||
function addPageLifeCycle(cycle, callback) {
|
||||
var _a, pathname = lib_router.current.pathname;
|
||||
@ -9411,16 +9411,16 @@
|
||||
}) : "browser" === type ? (0, esm_history.createBrowserHistory)({
|
||||
basename: basename
|
||||
}) : (0, esm_history.createMemoryHistory)();
|
||||
}, initHistory = function(appConfig, initialContext) {
|
||||
}, initHistory = (createHistory = createHistory1, function(appConfig, initialContext) {
|
||||
void 0 === initialContext && (initialContext = null), appConfig.router || (appConfig.router = DEFAULT_APP_CONFIG.router);
|
||||
var router = appConfig.router, _a = router.type, type = void 0 === _a ? DEFAULT_APP_CONFIG.router.type : _a, basename = router.basename, customHistory = router.history, newHistory = (createHistory = createHistory1)({
|
||||
var router = appConfig.router, _a = router.type, type = void 0 === _a ? DEFAULT_APP_CONFIG.router.type : _a, basename = router.basename, customHistory = router.history, newHistory = createHistory({
|
||||
type: type,
|
||||
basename: basename,
|
||||
location: initialContext ? initialContext.location : null,
|
||||
customHistory: customHistory
|
||||
});
|
||||
appConfig.router.history = newHistory, setHistory(newHistory);
|
||||
}, web_history = createHistory1, web_initAppLifeCycles = function() {
|
||||
}), web_history = createHistory1, web_initAppLifeCycles = function() {
|
||||
"undefined" != typeof document && "undefined" != typeof window && (document.addEventListener("visibilitychange", function() {
|
||||
var history = getHistory();
|
||||
(history ? history.location.pathname : lib_router.current.pathname) === lib_router.current.pathname && (lib_router.current.visibilityState = !lib_router.current.visibilityState, lib_router.current.visibilityState ? (emit("show"), pageLifeCycles_emit("show", lib_router.current.pathname)) : (pageLifeCycles_emit("hide", lib_router.current.pathname), emit("hide")));
|
||||
@ -10616,8 +10616,7 @@
|
||||
case "index":
|
||||
return (key)=>(result, value)=>{
|
||||
const index = result.length;
|
||||
if (void 0 === value || options.skipNull && null === value || options.skipEmptyString && "" === value) return result;
|
||||
if (null === value) return [
|
||||
return void 0 === value || options.skipNull && null === value || options.skipEmptyString && "" === value ? result : null === value ? [
|
||||
...result,
|
||||
[
|
||||
encode(key, options),
|
||||
@ -10625,8 +10624,7 @@
|
||||
index,
|
||||
"]"
|
||||
].join("")
|
||||
];
|
||||
return [
|
||||
] : [
|
||||
...result,
|
||||
[
|
||||
encode(key, options),
|
||||
@ -10639,60 +10637,48 @@
|
||||
}
|
||||
;
|
||||
case "bracket":
|
||||
return (key)=>(result, value)=>{
|
||||
if (void 0 === value || options.skipNull && null === value || options.skipEmptyString && "" === value) return result;
|
||||
if (null === value) return [
|
||||
return (key)=>(result, value)=>void 0 === value || options.skipNull && null === value || options.skipEmptyString && "" === value ? result : null === value ? [
|
||||
...result,
|
||||
[
|
||||
encode(key, options),
|
||||
"[]"
|
||||
].join("")
|
||||
];
|
||||
return [
|
||||
] : [
|
||||
...result,
|
||||
[
|
||||
encode(key, options),
|
||||
"[]=",
|
||||
encode(value, options)
|
||||
].join("")
|
||||
];
|
||||
}
|
||||
]
|
||||
;
|
||||
case "comma":
|
||||
case "separator":
|
||||
return (key)=>(result, value)=>{
|
||||
if (null == value || 0 === value.length) return result;
|
||||
if (0 === result.length) return [
|
||||
return (key)=>(result, value)=>null == value || 0 === value.length ? result : 0 === result.length ? [
|
||||
[
|
||||
encode(key, options),
|
||||
"=",
|
||||
encode(value, options)
|
||||
].join("")
|
||||
];
|
||||
return [
|
||||
] : [
|
||||
[
|
||||
result,
|
||||
encode(value, options)
|
||||
].join(options.arrayFormatSeparator)
|
||||
];
|
||||
}
|
||||
]
|
||||
;
|
||||
default:
|
||||
return (key)=>(result, value)=>{
|
||||
if (void 0 === value || options.skipNull && null === value || options.skipEmptyString && "" === value) return result;
|
||||
if (null === value) return [
|
||||
return (key)=>(result, value)=>void 0 === value || options.skipNull && null === value || options.skipEmptyString && "" === value ? result : null === value ? [
|
||||
...result,
|
||||
encode(key, options)
|
||||
];
|
||||
return [
|
||||
] : [
|
||||
...result,
|
||||
[
|
||||
encode(key, options),
|
||||
"=",
|
||||
encode(value, options)
|
||||
].join("")
|
||||
];
|
||||
}
|
||||
]
|
||||
;
|
||||
}
|
||||
}(options), objectCopy = {
|
||||
@ -10701,10 +10687,7 @@
|
||||
const keys = Object.keys(objectCopy);
|
||||
return !1 !== options.sort && keys.sort(options.sort), keys.map((key)=>{
|
||||
const value = object[key];
|
||||
if (void 0 === value) return "";
|
||||
if (null === value) return encode(key, options);
|
||||
if (Array.isArray(value)) return value.reduce(formatter(key), []).join("&");
|
||||
return encode(key, options) + "=" + encode(value, options);
|
||||
return void 0 === value ? "" : null === value ? encode(key, options) : Array.isArray(value) ? value.reduce(formatter(key), []).join("&") : encode(key, options) + "=" + encode(value, options);
|
||||
}).filter((x)=>x.length > 0
|
||||
).join("&");
|
||||
}, exports.parseUrl = (url, options)=>{
|
||||
@ -16425,9 +16408,9 @@
|
||||
var _Provider$childContex, _Consumer$contextType, contextProp = "__create-react-context-" + (commonjsGlobal["__global_unique_id__"] = (commonjsGlobal["__global_unique_id__"] || 0) + 1) + "__", Provider = function(_Component) {
|
||||
function Provider() {
|
||||
var _this, value, handlers;
|
||||
return _this = _Component.apply(this, arguments) || this, _this.emitter = {
|
||||
return _this = _Component.apply(this, arguments) || this, value = _this.props.value, handlers = [], _this.emitter = {
|
||||
on: function(handler) {
|
||||
(handlers = []).push(handler);
|
||||
handlers.push(handler);
|
||||
},
|
||||
off: function(handler) {
|
||||
handlers = handlers.filter(function(h) {
|
||||
@ -16435,7 +16418,7 @@
|
||||
});
|
||||
},
|
||||
get: function() {
|
||||
return value = _this.props.value;
|
||||
return value;
|
||||
},
|
||||
set: function(newValue, changedBits) {
|
||||
value = newValue, handlers.forEach(function(handler) {
|
||||
@ -17637,10 +17620,9 @@
|
||||
string
|
||||
];
|
||||
const separatorIndex = string.indexOf(separator);
|
||||
if (-1 === separatorIndex) return [
|
||||
return -1 === separatorIndex ? [
|
||||
string
|
||||
];
|
||||
return [
|
||||
] : [
|
||||
string.slice(0, separatorIndex),
|
||||
string.slice(separatorIndex + separator.length)
|
||||
];
|
||||
|
@ -17,9 +17,7 @@ const isMultiIndexContext = (widget)=>hasMultipleIndices({
|
||||
, isIndexWidgetEqualIndex = (widget, indexId)=>widget.props.indexId === indexId
|
||||
, sortIndexWidgetsFirst = (firstWidget, secondWidget)=>{
|
||||
const isFirstWidgetIndex = isIndexWidget(firstWidget), isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
if (isFirstWidgetIndex && !isSecondWidgetIndex) return -1;
|
||||
if (!isFirstWidgetIndex && isSecondWidgetIndex) return 1;
|
||||
return 0;
|
||||
return isFirstWidgetIndex && !isSecondWidgetIndex ? -1 : !isFirstWidgetIndex && isSecondWidgetIndex ? 1 : 0;
|
||||
};
|
||||
function serializeQueryParameters(parameters) {
|
||||
const isObjectOrArray = (value)=>"[object Object]" === Object.prototype.toString.call(value) || "[object Array]" === Object.prototype.toString.call(value)
|
||||
|
@ -37,9 +37,7 @@ const isMultiIndexContext = (widget)=>hasMultipleIndices({
|
||||
, isIndexWidgetEqualIndex = (widget, indexId)=>widget.props.indexId === indexId
|
||||
, sortIndexWidgetsFirst = (firstWidget, secondWidget)=>{
|
||||
const isFirstWidgetIndex = isIndexWidget(firstWidget), isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
if (isFirstWidgetIndex && !isSecondWidgetIndex) return -1;
|
||||
if (!isFirstWidgetIndex && isSecondWidgetIndex) return 1;
|
||||
return 0;
|
||||
return isFirstWidgetIndex && !isSecondWidgetIndex ? -1 : !isFirstWidgetIndex && isSecondWidgetIndex ? 1 : 0;
|
||||
};
|
||||
function serializeQueryParameters(parameters) {
|
||||
const isObjectOrArray = (value)=>"[object Object]" === Object.prototype.toString.call(value) || "[object Array]" === Object.prototype.toString.call(value)
|
||||
|
548
ecmascript/minifier/tests/compress/fixture/issues/react-instancesearch/004/input.js
vendored
Normal file
548
ecmascript/minifier/tests/compress/fixture/issues/react-instancesearch/004/input.js
vendored
Normal file
@ -0,0 +1,548 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
import algoliasearchHelper from 'algoliasearch-helper';
|
||||
import createWidgetsManager from './createWidgetsManager';
|
||||
import { HIGHLIGHT_TAGS } from './highlight';
|
||||
import { hasMultipleIndices } from './indexUtils';
|
||||
import { version as ReactVersion } from 'react';
|
||||
import version from './version';
|
||||
function addAlgoliaAgents(searchClient) {
|
||||
if (typeof searchClient.addAlgoliaAgent === 'function') {
|
||||
searchClient.addAlgoliaAgent("react (".concat(ReactVersion, ")"));
|
||||
searchClient.addAlgoliaAgent("react-instantsearch (".concat(version, ")"));
|
||||
}
|
||||
}
|
||||
var isMultiIndexContext = function (widget) {
|
||||
return hasMultipleIndices({
|
||||
ais: widget.props.contextValue,
|
||||
multiIndexContext: widget.props.indexContextValue
|
||||
});
|
||||
};
|
||||
var isTargetedIndexEqualIndex = function (widget, indexId) {
|
||||
return widget.props.indexContextValue.targetedIndex === indexId;
|
||||
};
|
||||
// Relying on the `indexId` is a bit brittle to detect the `Index` widget.
|
||||
// Since it's a class we could rely on `instanceof` or similar. We never
|
||||
// had an issue though. Works for now.
|
||||
var isIndexWidget = function (widget) {
|
||||
return Boolean(widget.props.indexId);
|
||||
};
|
||||
var isIndexWidgetEqualIndex = function (widget, indexId) {
|
||||
return widget.props.indexId === indexId;
|
||||
};
|
||||
var sortIndexWidgetsFirst = function (firstWidget, secondWidget) {
|
||||
var isFirstWidgetIndex = isIndexWidget(firstWidget);
|
||||
var isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
if (isFirstWidgetIndex && !isSecondWidgetIndex) {
|
||||
return -1;
|
||||
}
|
||||
if (!isFirstWidgetIndex && isSecondWidgetIndex) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
// This function is copied from the algoliasearch v4 API Client. If modified,
|
||||
// consider updating it also in `serializeQueryParameters` from `@algolia/transporter`.
|
||||
function serializeQueryParameters(parameters) {
|
||||
var isObjectOrArray = function (value) {
|
||||
return Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]';
|
||||
};
|
||||
var encode = function (format) {
|
||||
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
args[_key - 1] = arguments[_key];
|
||||
}
|
||||
var i = 0;
|
||||
return format.replace(/%s/g, function () {
|
||||
return encodeURIComponent(args[i++]);
|
||||
});
|
||||
};
|
||||
return Object.keys(parameters).map(function (key) {
|
||||
return encode('%s=%s', key, isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]);
|
||||
}).join('&');
|
||||
}
|
||||
var _obj;
|
||||
/**
|
||||
* Creates a new instance of the InstantSearchManager which controls the widgets and
|
||||
* trigger the search when the widgets are updated.
|
||||
* @param {string} indexName - the main index name
|
||||
* @param {object} initialState - initial widget state
|
||||
* @param {object} SearchParameters - optional additional parameters to send to the algolia API
|
||||
* @param {number} stalledSearchDelay - time (in ms) after the search is stalled
|
||||
* @return {InstantSearchManager} a new instance of InstantSearchManager
|
||||
*/ export default function createInstantSearchManager(param) {
|
||||
var indexName = param.indexName, _initialState = param.initialState, initialState = _initialState === void 0 ? {
|
||||
} : _initialState, searchClient = param.searchClient, resultsState = param.resultsState, stalledSearchDelay = param.stalledSearchDelay;
|
||||
var createStore = function createStore(initialState) {
|
||||
var state = initialState;
|
||||
var listeners = [];
|
||||
return {
|
||||
getState: function () {
|
||||
return state;
|
||||
},
|
||||
setState: function (nextState) {
|
||||
state = nextState;
|
||||
listeners.forEach(function (listener) {
|
||||
return listener();
|
||||
});
|
||||
},
|
||||
subscribe: function (listener) {
|
||||
listeners.push(listener);
|
||||
return function unsubscribe() {
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
var skipSearch = function skipSearch() {
|
||||
skip = true;
|
||||
};
|
||||
var updateClient = function updateClient(client) {
|
||||
addAlgoliaAgents(client);
|
||||
helper.setClient(client);
|
||||
search();
|
||||
};
|
||||
var clearCache = function clearCache() {
|
||||
helper.clearCache();
|
||||
search();
|
||||
};
|
||||
var getMetadata = function getMetadata(state) {
|
||||
return widgetsManager.getWidgets().filter(function (widget) {
|
||||
return Boolean(widget.getMetadata);
|
||||
}).map(function (widget) {
|
||||
return widget.getMetadata(state);
|
||||
});
|
||||
};
|
||||
var getSearchParameters = function getSearchParameters() {
|
||||
var sharedParameters = widgetsManager.getWidgets().filter(function (widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function (widget) {
|
||||
return !isMultiIndexContext(widget) && !isIndexWidget(widget);
|
||||
}).reduce(function (res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, initialSearchParameters);
|
||||
var mainParameters = widgetsManager.getWidgets().filter(function (widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function (widget) {
|
||||
var targetedIndexEqualMainIndex = isMultiIndexContext(widget) && isTargetedIndexEqualIndex(widget, indexName);
|
||||
var subIndexEqualMainIndex = isIndexWidget(widget) && isIndexWidgetEqualIndex(widget, indexName);
|
||||
return targetedIndexEqualMainIndex || subIndexEqualMainIndex;
|
||||
})// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst).reduce(function (res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, sharedParameters);
|
||||
var derivedIndices = widgetsManager.getWidgets().filter(function (widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function (widget) {
|
||||
var targetedIndexNotEqualMainIndex = isMultiIndexContext(widget) && !isTargetedIndexEqualIndex(widget, indexName);
|
||||
var subIndexNotEqualMainIndex = isIndexWidget(widget) && !isIndexWidgetEqualIndex(widget, indexName);
|
||||
return targetedIndexNotEqualMainIndex || subIndexNotEqualMainIndex;
|
||||
})// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst).reduce(function (indices, widget) {
|
||||
var indexId = isMultiIndexContext(widget) ? widget.props.indexContextValue.targetedIndex : widget.props.indexId;
|
||||
var widgets = indices[indexId] || [];
|
||||
return swcHelpers.objectSpread({
|
||||
}, indices, swcHelpers.defineProperty({
|
||||
}, indexId, widgets.concat(widget)));
|
||||
}, {
|
||||
});
|
||||
var derivedParameters = Object.keys(derivedIndices).map(function (indexId) {
|
||||
return {
|
||||
parameters: derivedIndices[indexId].reduce(function (res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, sharedParameters),
|
||||
indexId: indexId
|
||||
};
|
||||
});
|
||||
return {
|
||||
mainParameters: mainParameters,
|
||||
derivedParameters: derivedParameters
|
||||
};
|
||||
};
|
||||
var search = function search() {
|
||||
if (!skip) {
|
||||
var ref = getSearchParameters(helper.state), mainParameters = ref.mainParameters, derivedParameters = ref.derivedParameters;
|
||||
// We have to call `slice` because the method `detach` on the derived
|
||||
// helpers mutates the value `derivedHelpers`. The `forEach` loop does
|
||||
// not iterate on each value and we're not able to correctly clear the
|
||||
// previous derived helpers (memory leak + useless requests).
|
||||
helper.derivedHelpers.slice().forEach(function (derivedHelper) {
|
||||
// Since we detach the derived helpers on **every** new search they
|
||||
// won't receive intermediate results in case of a stalled search.
|
||||
// Only the last result is dispatched by the derived helper because
|
||||
// they are not detached yet:
|
||||
//
|
||||
// - a -> main helper receives results
|
||||
// - ap -> main helper receives results
|
||||
// - app -> main helper + derived helpers receive results
|
||||
//
|
||||
// The quick fix is to avoid to detach them on search but only once they
|
||||
// received the results. But it means that in case of a stalled search
|
||||
// all the derived helpers not detached yet register a new search inside
|
||||
// the helper. The number grows fast in case of a bad network and it's
|
||||
// not deterministic.
|
||||
derivedHelper.detach();
|
||||
});
|
||||
derivedParameters.forEach(function (param) {
|
||||
var indexId = param.indexId, parameters = param.parameters;
|
||||
var derivedHelper = helper.derive(function () {
|
||||
return parameters;
|
||||
});
|
||||
derivedHelper.on('result', handleSearchSuccess({
|
||||
indexId: indexId
|
||||
})).on('error', handleSearchError);
|
||||
});
|
||||
helper.setState(mainParameters);
|
||||
helper.search();
|
||||
}
|
||||
};
|
||||
var handleSearchSuccess = function handleSearchSuccess(param) {
|
||||
var indexId = param.indexId;
|
||||
return function (event) {
|
||||
var state = store.getState();
|
||||
var isDerivedHelpersEmpty = !helper.derivedHelpers.length;
|
||||
var results = state.results ? state.results : {
|
||||
};
|
||||
// Switching from mono index to multi index and vice versa must reset the
|
||||
// results to an empty object, otherwise we keep reference of stalled and
|
||||
// unused results.
|
||||
results = !isDerivedHelpersEmpty && results.getFacetByName ? {
|
||||
} : results;
|
||||
if (!isDerivedHelpersEmpty) {
|
||||
results = swcHelpers.objectSpread({
|
||||
}, results, swcHelpers.defineProperty({
|
||||
}, indexId, event.results));
|
||||
} else {
|
||||
results = event.results;
|
||||
}
|
||||
var currentState = store.getState();
|
||||
var nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
stalledSearchTimer = null;
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
var resultsFacetValues = currentState.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(currentState, ["resultsFacetValues"]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
results: results,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
searching: false,
|
||||
error: null
|
||||
}));
|
||||
};
|
||||
};
|
||||
var handleSearchError = function handleSearchError(param) {
|
||||
var error = param.error;
|
||||
var currentState = store.getState();
|
||||
var nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
var resultsFacetValues = currentState.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(currentState, ["resultsFacetValues"]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
error: error,
|
||||
searching: false
|
||||
}));
|
||||
};
|
||||
var handleNewSearch = function handleNewSearch() {
|
||||
if (!stalledSearchTimer) {
|
||||
stalledSearchTimer = setTimeout(function () {
|
||||
var _ref = store.getState(), resultsFacetValues = _ref.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(_ref, ["resultsFacetValues"]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
isSearchStalled: true
|
||||
}));
|
||||
}, stalledSearchDelay);
|
||||
}
|
||||
};
|
||||
var hydrateSearchClient = function hydrateSearchClient(client, results) {
|
||||
if (!results) {
|
||||
return;
|
||||
}
|
||||
// Disable cache hydration on:
|
||||
// - Algoliasearch API Client < v4 with cache disabled
|
||||
// - Third party clients (detected by the `addAlgoliaAgent` function missing)
|
||||
if ((!client.transporter || client._cacheHydrated) && (!client._useCache || typeof client.addAlgoliaAgent !== 'function')) {
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client >= v4
|
||||
// To hydrate the client we need to populate the cache with the data from
|
||||
// the server (done in `hydrateSearchClientWithMultiIndexRequest` or
|
||||
// `hydrateSearchClientWithSingleIndexRequest`). But since there is no way
|
||||
// for us to compute the key the same way as `algoliasearch-client` we need
|
||||
// to populate it on a custom key and override the `search` method to
|
||||
// search on it first.
|
||||
if (client.transporter && !client._cacheHydrated) {
|
||||
client._cacheHydrated = true;
|
||||
var baseMethod = client.search;
|
||||
client.search = function (requests) {
|
||||
for (var _len = arguments.length, methodArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
methodArgs[_key - 1] = arguments[_key];
|
||||
}
|
||||
var requestsWithSerializedParams = requests.map(function (request) {
|
||||
return swcHelpers.objectSpread({
|
||||
}, request, {
|
||||
params: serializeQueryParameters(request.params)
|
||||
});
|
||||
});
|
||||
return client.transporter.responsesCache.get({
|
||||
method: 'search',
|
||||
args: [
|
||||
requestsWithSerializedParams
|
||||
].concat(swcHelpers.toConsumableArray(methodArgs))
|
||||
}, function () {
|
||||
return baseMethod.apply(void 0, [
|
||||
requests
|
||||
].concat(swcHelpers.toConsumableArray(methodArgs)));
|
||||
});
|
||||
};
|
||||
}
|
||||
if (Array.isArray(results.results)) {
|
||||
hydrateSearchClientWithMultiIndexRequest(client, results.results);
|
||||
return;
|
||||
}
|
||||
hydrateSearchClientWithSingleIndexRequest(client, results);
|
||||
};
|
||||
var hydrateSearchClientWithMultiIndexRequest = function hydrateSearchClientWithMultiIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set({
|
||||
method: 'search',
|
||||
args: [
|
||||
results.reduce(function (acc, result) {
|
||||
return acc.concat(result.rawResults.map(function (request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}));
|
||||
}, []),
|
||||
]
|
||||
}, {
|
||||
results: results.reduce(function (acc, result) {
|
||||
return acc.concat(result.rawResults);
|
||||
}, [])
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
var key = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: results.reduce(function (acc, result) {
|
||||
return acc.concat(result.rawResults.map(function (request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}));
|
||||
}, [])
|
||||
}));
|
||||
client.cache = swcHelpers.objectSpread({
|
||||
}, client.cache, swcHelpers.defineProperty({
|
||||
}, key, JSON.stringify({
|
||||
results: results.reduce(function (acc, result) {
|
||||
return acc.concat(result.rawResults);
|
||||
}, [])
|
||||
})));
|
||||
};
|
||||
var hydrateSearchClientWithSingleIndexRequest = function hydrateSearchClientWithSingleIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set({
|
||||
method: 'search',
|
||||
args: [
|
||||
results.rawResults.map(function (request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}),
|
||||
]
|
||||
}, {
|
||||
results: results.rawResults
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
var key = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: results.rawResults.map(function (request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
})
|
||||
}));
|
||||
client.cache = swcHelpers.objectSpread({
|
||||
}, client.cache, swcHelpers.defineProperty({
|
||||
}, key, JSON.stringify({
|
||||
results: results.rawResults
|
||||
})));
|
||||
};
|
||||
var hydrateResultsState = function hydrateResultsState(results) {
|
||||
if (!results) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(results.results)) {
|
||||
return results.results.reduce(function (acc, result) {
|
||||
return swcHelpers.objectSpread({
|
||||
}, acc, swcHelpers.defineProperty({
|
||||
}, result._internalIndexId, new algoliasearchHelper.SearchResults(new algoliasearchHelper.SearchParameters(result.state), result.rawResults)));
|
||||
}, {
|
||||
});
|
||||
}
|
||||
return new algoliasearchHelper.SearchResults(new algoliasearchHelper.SearchParameters(results.state), results.rawResults);
|
||||
};
|
||||
var onWidgetsUpdate = // Called whenever a widget has been rendered with new props.
|
||||
function onWidgetsUpdate() {
|
||||
var metadata = getMetadata(store.getState().widgets);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
metadata: metadata,
|
||||
searching: true
|
||||
}));
|
||||
// Since the `getSearchParameters` method of widgets also depends on props,
|
||||
// the result search parameters might have changed.
|
||||
search();
|
||||
};
|
||||
var transitionState = function transitionState(nextSearchState) {
|
||||
var searchState = store.getState().widgets;
|
||||
return widgetsManager.getWidgets().filter(function (widget) {
|
||||
return Boolean(widget.transitionState);
|
||||
}).reduce(function (res, widget) {
|
||||
return widget.transitionState(searchState, res);
|
||||
}, nextSearchState);
|
||||
};
|
||||
var onExternalStateUpdate = function onExternalStateUpdate(nextSearchState) {
|
||||
var metadata = getMetadata(nextSearchState);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
widgets: nextSearchState,
|
||||
metadata: metadata,
|
||||
searching: true
|
||||
}));
|
||||
search();
|
||||
};
|
||||
var onSearchForFacetValues = function onSearchForFacetValues(param) {
|
||||
var facetName = param.facetName, query = param.query, _maxFacetHits = param.maxFacetHits, maxFacetHits = _maxFacetHits === void 0 ? 10 : _maxFacetHits;
|
||||
// The values 1, 100 are the min / max values that the engine accepts.
|
||||
// see: https://www.algolia.com/doc/api-reference/api-parameters/maxFacetHits
|
||||
var maxFacetHitsWithinRange = Math.max(1, Math.min(maxFacetHits, 100));
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
searchingForFacetValues: true
|
||||
}));
|
||||
helper.searchForFacetValues(facetName, query, maxFacetHitsWithinRange).then(function (content) {
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
error: null,
|
||||
searchingForFacetValues: false,
|
||||
resultsFacetValues: swcHelpers.objectSpread({
|
||||
}, store.getState().resultsFacetValues, (_obj = {
|
||||
}, swcHelpers.defineProperty(_obj, facetName, content.facetHits), swcHelpers.defineProperty(_obj, "query", query), _obj))
|
||||
}));
|
||||
}, function (error) {
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
searchingForFacetValues: false,
|
||||
error: error
|
||||
}));
|
||||
}).catch(function (error) {
|
||||
// Since setState is synchronous, any error that occurs in the render of a
|
||||
// component will be swallowed by this promise.
|
||||
// This is a trick to make the error show up correctly in the console.
|
||||
// See http://stackoverflow.com/a/30741722/969302
|
||||
setTimeout(function () {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
};
|
||||
var updateIndex = function updateIndex(newIndex) {
|
||||
initialSearchParameters = initialSearchParameters.setIndex(newIndex);
|
||||
// No need to trigger a new search here as the widgets will also update and trigger it if needed.
|
||||
};
|
||||
var getWidgetsIds = function getWidgetsIds() {
|
||||
return store.getState().metadata.reduce(function (res, meta) {
|
||||
return typeof meta.id !== 'undefined' ? res.concat(meta.id) : res;
|
||||
}, []);
|
||||
};
|
||||
var helper = algoliasearchHelper(searchClient, indexName, swcHelpers.objectSpread({
|
||||
}, HIGHLIGHT_TAGS));
|
||||
addAlgoliaAgents(searchClient);
|
||||
helper.on('search', handleNewSearch).on('result', handleSearchSuccess({
|
||||
indexId: indexName
|
||||
})).on('error', handleSearchError);
|
||||
var skip = false;
|
||||
var stalledSearchTimer = null;
|
||||
var initialSearchParameters = helper.state;
|
||||
var widgetsManager = createWidgetsManager(onWidgetsUpdate);
|
||||
hydrateSearchClient(searchClient, resultsState);
|
||||
var store = createStore({
|
||||
widgets: initialState,
|
||||
metadata: hydrateMetadata(resultsState),
|
||||
results: hydrateResultsState(resultsState),
|
||||
error: null,
|
||||
searching: false,
|
||||
isSearchStalled: true,
|
||||
searchingForFacetValues: false
|
||||
});
|
||||
return {
|
||||
store: store,
|
||||
widgetsManager: widgetsManager,
|
||||
getWidgetsIds: getWidgetsIds,
|
||||
getSearchParameters: getSearchParameters,
|
||||
onSearchForFacetValues: onSearchForFacetValues,
|
||||
onExternalStateUpdate: onExternalStateUpdate,
|
||||
transitionState: transitionState,
|
||||
updateClient: updateClient,
|
||||
updateIndex: updateIndex,
|
||||
clearCache: clearCache,
|
||||
skipSearch: skipSearch
|
||||
};
|
||||
};
|
||||
function hydrateMetadata(resultsState) {
|
||||
if (!resultsState) {
|
||||
return [];
|
||||
}
|
||||
// add a value noop, which gets replaced once the widgets are mounted
|
||||
return resultsState.metadata.map(function (datum) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function () {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, datum, {
|
||||
items: datum.items && datum.items.map(function (item) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function () {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, item, {
|
||||
items: item.items && item.items.map(function (nestedItem) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function () {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, nestedItem);
|
||||
})
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
376
ecmascript/minifier/tests/compress/fixture/issues/react-instancesearch/004/output.js
vendored
Normal file
376
ecmascript/minifier/tests/compress/fixture/issues/react-instancesearch/004/output.js
vendored
Normal file
@ -0,0 +1,376 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
import algoliasearchHelper from "algoliasearch-helper";
|
||||
import createWidgetsManager from "./createWidgetsManager";
|
||||
import { HIGHLIGHT_TAGS } from "./highlight";
|
||||
import { hasMultipleIndices } from "./indexUtils";
|
||||
import { version as ReactVersion } from "react";
|
||||
import version from "./version";
|
||||
function addAlgoliaAgents(searchClient) {
|
||||
"function" == typeof searchClient.addAlgoliaAgent && (searchClient.addAlgoliaAgent("react (".concat(ReactVersion, ")")), searchClient.addAlgoliaAgent("react-instantsearch (".concat(version, ")")));
|
||||
}
|
||||
var _obj, isMultiIndexContext = function(widget) {
|
||||
return hasMultipleIndices({
|
||||
ais: widget.props.contextValue,
|
||||
multiIndexContext: widget.props.indexContextValue
|
||||
});
|
||||
}, isTargetedIndexEqualIndex = function(widget, indexId) {
|
||||
return widget.props.indexContextValue.targetedIndex === indexId;
|
||||
}, isIndexWidget = function(widget) {
|
||||
return Boolean(widget.props.indexId);
|
||||
}, isIndexWidgetEqualIndex = function(widget, indexId) {
|
||||
return widget.props.indexId === indexId;
|
||||
}, sortIndexWidgetsFirst = function(firstWidget, secondWidget) {
|
||||
var isFirstWidgetIndex = isIndexWidget(firstWidget), isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
return isFirstWidgetIndex && !isSecondWidgetIndex ? -1 : !isFirstWidgetIndex && isSecondWidgetIndex ? 1 : 0;
|
||||
};
|
||||
function serializeQueryParameters(parameters) {
|
||||
var encode = function(format) {
|
||||
for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)args[_key - 1] = arguments[_key];
|
||||
var i = 0;
|
||||
return format.replace(/%s/g, function() {
|
||||
return encodeURIComponent(args[i++]);
|
||||
});
|
||||
};
|
||||
return Object.keys(parameters).map(function(key) {
|
||||
var value;
|
||||
return encode("%s=%s", key, (value = parameters[key], "[object Object]" === Object.prototype.toString.call(value) || "[object Array]" === Object.prototype.toString.call(value)) ? JSON.stringify(parameters[key]) : parameters[key]);
|
||||
}).join("&");
|
||||
}
|
||||
export default function createInstantSearchManager(param) {
|
||||
var indexName = param.indexName, _initialState = param.initialState, searchClient = param.searchClient, resultsState = param.resultsState, stalledSearchDelay = param.stalledSearchDelay, getMetadata = function(state) {
|
||||
return widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getMetadata);
|
||||
}).map(function(widget) {
|
||||
return widget.getMetadata(state);
|
||||
});
|
||||
}, getSearchParameters = function() {
|
||||
var sharedParameters = widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function(widget) {
|
||||
return !isMultiIndexContext(widget) && !isIndexWidget(widget);
|
||||
}).reduce(function(res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, initialSearchParameters), mainParameters = widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function(widget) {
|
||||
var targetedIndexEqualMainIndex = isMultiIndexContext(widget) && isTargetedIndexEqualIndex(widget, indexName), subIndexEqualMainIndex = isIndexWidget(widget) && isIndexWidgetEqualIndex(widget, indexName);
|
||||
return targetedIndexEqualMainIndex || subIndexEqualMainIndex;
|
||||
}).sort(sortIndexWidgetsFirst).reduce(function(res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, sharedParameters), derivedIndices = widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function(widget) {
|
||||
var targetedIndexNotEqualMainIndex = isMultiIndexContext(widget) && !isTargetedIndexEqualIndex(widget, indexName), subIndexNotEqualMainIndex = isIndexWidget(widget) && !isIndexWidgetEqualIndex(widget, indexName);
|
||||
return targetedIndexNotEqualMainIndex || subIndexNotEqualMainIndex;
|
||||
}).sort(sortIndexWidgetsFirst).reduce(function(indices, widget) {
|
||||
var indexId = isMultiIndexContext(widget) ? widget.props.indexContextValue.targetedIndex : widget.props.indexId, widgets = indices[indexId] || [];
|
||||
return swcHelpers.objectSpread({
|
||||
}, indices, swcHelpers.defineProperty({
|
||||
}, indexId, widgets.concat(widget)));
|
||||
}, {
|
||||
});
|
||||
return {
|
||||
mainParameters: mainParameters,
|
||||
derivedParameters: Object.keys(derivedIndices).map(function(indexId) {
|
||||
return {
|
||||
parameters: derivedIndices[indexId].reduce(function(res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, sharedParameters),
|
||||
indexId: indexId
|
||||
};
|
||||
})
|
||||
};
|
||||
}, search = function() {
|
||||
if (!skip) {
|
||||
var ref = getSearchParameters(helper.state), mainParameters = ref.mainParameters, derivedParameters = ref.derivedParameters;
|
||||
helper.derivedHelpers.slice().forEach(function(derivedHelper) {
|
||||
derivedHelper.detach();
|
||||
}), derivedParameters.forEach(function(param) {
|
||||
var indexId = param.indexId, parameters = param.parameters;
|
||||
helper.derive(function() {
|
||||
return parameters;
|
||||
}).on("result", handleSearchSuccess({
|
||||
indexId: indexId
|
||||
})).on("error", handleSearchError);
|
||||
}), helper.setState(mainParameters), helper.search();
|
||||
}
|
||||
}, handleSearchSuccess = function(param) {
|
||||
var indexId = param.indexId;
|
||||
return function(event) {
|
||||
var state = store.getState(), isDerivedHelpersEmpty = !helper.derivedHelpers.length, results = state.results ? state.results : {
|
||||
};
|
||||
results = !isDerivedHelpersEmpty && results.getFacetByName ? {
|
||||
} : results, results = isDerivedHelpersEmpty ? event.results : swcHelpers.objectSpread({
|
||||
}, results, swcHelpers.defineProperty({
|
||||
}, indexId, event.results));
|
||||
var currentState = store.getState(), nextIsSearchStalled = currentState.isSearchStalled;
|
||||
helper.hasPendingRequests() || (clearTimeout(stalledSearchTimer), stalledSearchTimer = null, nextIsSearchStalled = !1), currentState.resultsFacetValues;
|
||||
var partialState = swcHelpers.objectWithoutProperties(currentState, [
|
||||
"resultsFacetValues"
|
||||
]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
results: results,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
searching: !1,
|
||||
error: null
|
||||
}));
|
||||
};
|
||||
}, handleSearchError = function(param) {
|
||||
var error = param.error, currentState = store.getState(), nextIsSearchStalled = currentState.isSearchStalled;
|
||||
helper.hasPendingRequests() || (clearTimeout(stalledSearchTimer), nextIsSearchStalled = !1), currentState.resultsFacetValues;
|
||||
var partialState = swcHelpers.objectWithoutProperties(currentState, [
|
||||
"resultsFacetValues"
|
||||
]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
error: error,
|
||||
searching: !1
|
||||
}));
|
||||
}, hydrateSearchClientWithMultiIndexRequest = function(client, results) {
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set({
|
||||
method: "search",
|
||||
args: [
|
||||
results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}));
|
||||
}, []),
|
||||
]
|
||||
}, {
|
||||
results: results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults);
|
||||
}, [])
|
||||
});
|
||||
return;
|
||||
}
|
||||
var key = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}));
|
||||
}, [])
|
||||
}));
|
||||
client.cache = swcHelpers.objectSpread({
|
||||
}, client.cache, swcHelpers.defineProperty({
|
||||
}, key, JSON.stringify({
|
||||
results: results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults);
|
||||
}, [])
|
||||
})));
|
||||
}, hydrateSearchClientWithSingleIndexRequest = function(client, results) {
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set({
|
||||
method: "search",
|
||||
args: [
|
||||
results.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}),
|
||||
]
|
||||
}, {
|
||||
results: results.rawResults
|
||||
});
|
||||
return;
|
||||
}
|
||||
var key = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: results.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
})
|
||||
}));
|
||||
client.cache = swcHelpers.objectSpread({
|
||||
}, client.cache, swcHelpers.defineProperty({
|
||||
}, key, JSON.stringify({
|
||||
results: results.rawResults
|
||||
})));
|
||||
}, helper = algoliasearchHelper(searchClient, indexName, swcHelpers.objectSpread({
|
||||
}, HIGHLIGHT_TAGS));
|
||||
addAlgoliaAgents(searchClient), helper.on("search", function() {
|
||||
stalledSearchTimer || (stalledSearchTimer = setTimeout(function() {
|
||||
var _ref = store.getState(), resultsFacetValues = _ref.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(_ref, [
|
||||
"resultsFacetValues"
|
||||
]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
isSearchStalled: !0
|
||||
}));
|
||||
}, stalledSearchDelay));
|
||||
}).on("result", handleSearchSuccess({
|
||||
indexId: indexName
|
||||
})).on("error", handleSearchError);
|
||||
var skip = !1, stalledSearchTimer = null, initialSearchParameters = helper.state, widgetsManager = createWidgetsManager(function() {
|
||||
var metadata = getMetadata(store.getState().widgets);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
metadata: metadata,
|
||||
searching: !0
|
||||
})), search();
|
||||
});
|
||||
!function(client, results) {
|
||||
if (results && (client.transporter && !client._cacheHydrated || client._useCache && "function" == typeof client.addAlgoliaAgent)) {
|
||||
if (client.transporter && !client._cacheHydrated) {
|
||||
client._cacheHydrated = !0;
|
||||
var baseMethod = client.search;
|
||||
client.search = function(requests) {
|
||||
for(var _len = arguments.length, methodArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)methodArgs[_key - 1] = arguments[_key];
|
||||
var requestsWithSerializedParams = requests.map(function(request) {
|
||||
return swcHelpers.objectSpread({
|
||||
}, request, {
|
||||
params: serializeQueryParameters(request.params)
|
||||
});
|
||||
});
|
||||
return client.transporter.responsesCache.get({
|
||||
method: "search",
|
||||
args: [
|
||||
requestsWithSerializedParams
|
||||
].concat(swcHelpers.toConsumableArray(methodArgs))
|
||||
}, function() {
|
||||
return baseMethod.apply(void 0, [
|
||||
requests
|
||||
].concat(swcHelpers.toConsumableArray(methodArgs)));
|
||||
});
|
||||
};
|
||||
}
|
||||
if (Array.isArray(results.results)) {
|
||||
hydrateSearchClientWithMultiIndexRequest(client, results.results);
|
||||
return;
|
||||
}
|
||||
hydrateSearchClientWithSingleIndexRequest(client, results);
|
||||
}
|
||||
}(searchClient, resultsState);
|
||||
var results, state, listeners, store = (state = {
|
||||
widgets: void 0 === _initialState ? {
|
||||
} : _initialState,
|
||||
metadata: hydrateMetadata(resultsState),
|
||||
results: (results = resultsState) ? Array.isArray(results.results) ? results.results.reduce(function(acc, result) {
|
||||
return swcHelpers.objectSpread({
|
||||
}, acc, swcHelpers.defineProperty({
|
||||
}, result._internalIndexId, new algoliasearchHelper.SearchResults(new algoliasearchHelper.SearchParameters(result.state), result.rawResults)));
|
||||
}, {
|
||||
}) : new algoliasearchHelper.SearchResults(new algoliasearchHelper.SearchParameters(results.state), results.rawResults) : null,
|
||||
error: null,
|
||||
searching: !1,
|
||||
isSearchStalled: !0,
|
||||
searchingForFacetValues: !1
|
||||
}, listeners = [], {
|
||||
getState: function() {
|
||||
return state;
|
||||
},
|
||||
setState: function(nextState) {
|
||||
state = nextState, listeners.forEach(function(listener) {
|
||||
return listener();
|
||||
});
|
||||
},
|
||||
subscribe: function(listener) {
|
||||
return listeners.push(listener), function() {
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
};
|
||||
}
|
||||
});
|
||||
return {
|
||||
store: store,
|
||||
widgetsManager: widgetsManager,
|
||||
getWidgetsIds: function() {
|
||||
return store.getState().metadata.reduce(function(res, meta) {
|
||||
return void 0 !== meta.id ? res.concat(meta.id) : res;
|
||||
}, []);
|
||||
},
|
||||
getSearchParameters: getSearchParameters,
|
||||
onSearchForFacetValues: function(param) {
|
||||
var facetName = param.facetName, query = param.query, _maxFacetHits = param.maxFacetHits;
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
searchingForFacetValues: !0
|
||||
})), helper.searchForFacetValues(facetName, query, Math.max(1, Math.min(void 0 === _maxFacetHits ? 10 : _maxFacetHits, 100))).then(function(content) {
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
error: null,
|
||||
searchingForFacetValues: !1,
|
||||
resultsFacetValues: swcHelpers.objectSpread({
|
||||
}, store.getState().resultsFacetValues, (_obj = {
|
||||
}, swcHelpers.defineProperty(_obj, facetName, content.facetHits), swcHelpers.defineProperty(_obj, "query", query), _obj))
|
||||
}));
|
||||
}, function(error) {
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
searchingForFacetValues: !1,
|
||||
error: error
|
||||
}));
|
||||
}).catch(function(error) {
|
||||
setTimeout(function() {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
},
|
||||
onExternalStateUpdate: function(nextSearchState) {
|
||||
var metadata = getMetadata(nextSearchState);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
widgets: nextSearchState,
|
||||
metadata: metadata,
|
||||
searching: !0
|
||||
})), search();
|
||||
},
|
||||
transitionState: function(nextSearchState) {
|
||||
var searchState = store.getState().widgets;
|
||||
return widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.transitionState);
|
||||
}).reduce(function(res, widget) {
|
||||
return widget.transitionState(searchState, res);
|
||||
}, nextSearchState);
|
||||
},
|
||||
updateClient: function(client) {
|
||||
addAlgoliaAgents(client), helper.setClient(client), search();
|
||||
},
|
||||
updateIndex: function(newIndex) {
|
||||
initialSearchParameters = initialSearchParameters.setIndex(newIndex);
|
||||
},
|
||||
clearCache: function() {
|
||||
helper.clearCache(), search();
|
||||
},
|
||||
skipSearch: function() {
|
||||
skip = !0;
|
||||
}
|
||||
};
|
||||
};
|
||||
function hydrateMetadata(resultsState) {
|
||||
return resultsState ? resultsState.metadata.map(function(datum) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, datum, {
|
||||
items: datum.items && datum.items.map(function(item) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, item, {
|
||||
items: item.items && item.items.map(function(nestedItem) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, nestedItem);
|
||||
})
|
||||
});
|
||||
})
|
||||
});
|
||||
}) : [];
|
||||
}
|
@ -585,6 +585,7 @@ inline/inline_annotation_2/input.js
|
||||
inline/inline_func_with_name_existing_in_block_scope/input.js
|
||||
inline/inline_into_scope_conflict_enclosed/input.js
|
||||
inline/inline_into_scope_conflict_enclosed_2/input.js
|
||||
inline/issue_308/input.js
|
||||
inline/noinline_annotation/input.js
|
||||
inline/noinline_annotation_2/input.js
|
||||
inline/noinline_annotation_3/input.js
|
||||
|
@ -193,7 +193,6 @@ inline/dont_inline_funcs_into_default_param_2/input.js
|
||||
inline/inline_annotation/input.js
|
||||
inline/inline_into_scope_conflict/input.js
|
||||
inline/inline_within_extends_1/input.js
|
||||
inline/issue_308/input.js
|
||||
issue_1034/non_hoisted_function_after_return/input.js
|
||||
issue_1034/non_hoisted_function_after_return_2a/input.js
|
||||
issue_1034/non_hoisted_function_after_return_2b/input.js
|
||||
|
@ -584,7 +584,7 @@
|
||||
if (isDefined(unsupported)) throw jqLiteMinErr("onargs", "jqLite#on() does not support the `selector` or `eventData` parameters");
|
||||
var element1, events, eventHandler, events1 = jqLiteExpandoStore(element, "events"), handle = jqLiteExpandoStore(element, "handle");
|
||||
events1 || jqLiteExpandoStore(element, "events", events1 = {
|
||||
}), handle || jqLiteExpandoStore(element, "handle", handle = ((eventHandler = function(event, type) {
|
||||
}), handle || jqLiteExpandoStore(element, "handle", handle = (element1 = element, events = events1, (eventHandler = function(event, type) {
|
||||
if (event.preventDefault || (event.preventDefault = function() {
|
||||
event.returnValue = !1;
|
||||
}), event.stopPropagation || (event.stopPropagation = function() {
|
||||
@ -597,8 +597,8 @@
|
||||
}
|
||||
event.isDefaultPrevented = function() {
|
||||
return event.defaultPrevented || !1 === event.returnValue;
|
||||
}, forEach((events = events1)[type || event.type], function(fn) {
|
||||
fn.call(element1 = element, event);
|
||||
}, forEach(events[type || event.type], function(fn) {
|
||||
fn.call(element1, event);
|
||||
}), msie <= 8 ? (event.preventDefault = null, event.stopPropagation = null, event.isDefaultPrevented = null) : (delete event.preventDefault, delete event.stopPropagation, delete event.isDefaultPrevented);
|
||||
}).elem = element1, eventHandler)), forEach(type.split(" "), function(type) {
|
||||
var eventFns = events1[type];
|
||||
@ -876,13 +876,13 @@
|
||||
this.enter(element, parent, after, done);
|
||||
},
|
||||
addClass: function(element, className, done) {
|
||||
forEach(element, function(element) {
|
||||
jqLiteAddClass(element, className = isString(className) ? className : isArray(className) ? className.join(" ") : "");
|
||||
className = isString(className) ? className : isArray(className) ? className.join(" ") : "", forEach(element, function(element) {
|
||||
jqLiteAddClass(element, className);
|
||||
}), done && $timeout(done, 0, !1);
|
||||
},
|
||||
removeClass: function(element, className, done) {
|
||||
forEach(element, function(element) {
|
||||
jqLiteRemoveClass(element, className = isString(className) ? className : isArray(className) ? className.join(" ") : "");
|
||||
className = isString(className) ? className : isArray(className) ? className.join(" ") : "", forEach(element, function(element) {
|
||||
jqLiteRemoveClass(element, className);
|
||||
}), done && $timeout(done, 0, !1);
|
||||
},
|
||||
enabled: noop
|
||||
@ -915,11 +915,11 @@
|
||||
var pollTimeout, pollFns = [];
|
||||
self.addPollFn = function(fn) {
|
||||
var setTimeout1;
|
||||
return isUndefined(pollTimeout) && (function check() {
|
||||
return isUndefined(pollTimeout) && (setTimeout1 = setTimeout, (function check() {
|
||||
forEach(pollFns, function(pollFn) {
|
||||
pollFn();
|
||||
}), pollTimeout = (setTimeout1 = setTimeout)(check, 100);
|
||||
})(), pollFns.push(fn), fn;
|
||||
}), pollTimeout = setTimeout1(check, 100);
|
||||
})()), pollFns.push(fn), fn;
|
||||
};
|
||||
var lastBrowserUrl = location.href, baseElement = document.find("base"), newLocation = null;
|
||||
self.url = function(url, replace) {
|
||||
@ -1229,9 +1229,9 @@
|
||||
if (value = null, elementControllers && "data" === retrievalMethod && (value = elementControllers[require]), !(value = value || $element[retrievalMethod]("$" + require + "Controller")) && !optional) throw $compileMinErr("ctreq", "Controller '{0}', required by directive '{1}', can't be found!", require, directiveName);
|
||||
return value;
|
||||
}
|
||||
return isArray(require) && forEach(require, function(require) {
|
||||
(value = []).push(getControllers(require, $element, elementControllers));
|
||||
}), value;
|
||||
return isArray(require) && (value = [], forEach(require, function(require) {
|
||||
value.push(getControllers(require, $element, elementControllers));
|
||||
})), value;
|
||||
}
|
||||
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
|
||||
var attrs, $element, i, ii, linkFn, controller, isolateScope, transcludeFn, elementControllers = {
|
||||
@ -2378,8 +2378,8 @@
|
||||
},
|
||||
assignment: function() {
|
||||
var right, token, left = this.ternary();
|
||||
return (token = this.expect("=")) ? (left.assign || this.throwError("implies assignment but [" + this.text.substring(0, token.index) + "] can not be assigned to", token), function(scope, locals) {
|
||||
return left.assign(scope, (right = this.ternary())(scope, locals), locals);
|
||||
return (token = this.expect("=")) ? (left.assign || this.throwError("implies assignment but [" + this.text.substring(0, token.index) + "] can not be assigned to", token), right = this.ternary(), function(scope, locals) {
|
||||
return left.assign(scope, right(scope, locals), locals);
|
||||
}) : left;
|
||||
},
|
||||
ternary: function() {
|
||||
@ -3644,9 +3644,9 @@
|
||||
if (ctrl.$isEmpty(value) || regexp.test(value)) return ctrl.$setValidity("pattern", !0), value;
|
||||
ctrl.$setValidity("pattern", !1);
|
||||
};
|
||||
if (pattern && (patternValidator = (match = pattern.match(/^\/(.*)\/([gim]*)$/)) ? function(value) {
|
||||
return validate(pattern = new RegExp(match[1], match[2]), value);
|
||||
} : function(value) {
|
||||
if (pattern && ((match = pattern.match(/^\/(.*)\/([gim]*)$/)) ? (pattern = new RegExp(match[1], match[2]), patternValidator = function(value) {
|
||||
return validate(pattern, value);
|
||||
}) : patternValidator = function(value) {
|
||||
var patternObj = scope.$eval(pattern);
|
||||
if (!patternObj || !patternObj.test) throw minErr("ngPattern")("noregexp", "Expected {0} to be a RegExp but was {1}. Element: {2}", pattern, patternObj, startingTag(element));
|
||||
return validate(patternObj, value);
|
||||
@ -3983,9 +3983,9 @@
|
||||
$id: hashKey
|
||||
};
|
||||
if (!match) throw ngRepeatMinErr("iexp", "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", expression);
|
||||
if (lhs = match[1], rhs = match[2], (trackByExp = match[4]) ? trackByIdExpFn = function(key, value, index) {
|
||||
return keyIdentifier && (hashFnLocals[keyIdentifier] = key), hashFnLocals[valueIdentifier] = value, hashFnLocals.$index = index, (trackByExpGetter = $parse(trackByExp))($scope, hashFnLocals);
|
||||
} : (trackByIdArrayFn = function(key, value) {
|
||||
if (lhs = match[1], rhs = match[2], (trackByExp = match[4]) ? (trackByExpGetter = $parse(trackByExp), trackByIdExpFn = function(key, value, index) {
|
||||
return keyIdentifier && (hashFnLocals[keyIdentifier] = key), hashFnLocals[valueIdentifier] = value, hashFnLocals.$index = index, trackByExpGetter($scope, hashFnLocals);
|
||||
}) : (trackByIdArrayFn = function(key, value) {
|
||||
return hashKey(value);
|
||||
}, trackByIdObjFn = function(key) {
|
||||
return key;
|
||||
|
@ -236,9 +236,9 @@
|
||||
access: function(elems, fn, key, value, chainable, emptyGet, raw) {
|
||||
var i = 0, length = elems.length, bulk = null == key;
|
||||
if ("object" === jQuery.type(key)) for(i in chainable = !0, key)jQuery.access(elems, fn, i, key[i], !0, emptyGet, raw);
|
||||
else if (value !== undefined && (chainable = !0, jQuery.isFunction(value) || (raw = !0), bulk && (raw ? (fn.call(elems, value), fn = null) : fn = function(elem, key, value) {
|
||||
return (bulk = fn).call(jQuery(elem), value);
|
||||
}), fn)) for(; i < length; i++)fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
|
||||
else if (value !== undefined && (chainable = !0, jQuery.isFunction(value) || (raw = !0), bulk && (raw ? (fn.call(elems, value), fn = null) : (bulk = fn, fn = function(elem, key, value) {
|
||||
return bulk.call(jQuery(elem), value);
|
||||
})), fn)) for(; i < length; i++)fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
|
||||
return chainable ? elems : bulk ? fn.call(elems) : length ? fn(elems[0], key) : emptyGet;
|
||||
},
|
||||
now: function() {
|
||||
@ -1093,8 +1093,8 @@
|
||||
}
|
||||
if (null == data && null == fn ? (fn = selector, data = selector = undefined) : null == fn && ("string" == typeof selector ? (fn = data, data = undefined) : (fn = data, data = selector, selector = undefined)), !1 === fn) fn = returnFalse;
|
||||
else if (!fn) return this;
|
||||
return 1 === one && ((fn = function(event) {
|
||||
return jQuery().off(event), (origFn = fn).apply(this, arguments);
|
||||
return 1 === one && (origFn = fn, (fn = function(event) {
|
||||
return jQuery().off(event), origFn.apply(this, arguments);
|
||||
}).guid = origFn.guid || (origFn.guid = jQuery.guid++)), this.each(function() {
|
||||
jQuery.event.add(this, types, fn, data, selector);
|
||||
});
|
||||
@ -1231,8 +1231,8 @@
|
||||
}
|
||||
function createPositionalPseudo(fn) {
|
||||
return markFunction(function(argument) {
|
||||
return markFunction(function(seed, matches) {
|
||||
for(var j, matchIndexes = fn([], seed.length, argument = +argument), i = matchIndexes.length; i--;)seed[j = matchIndexes[i]] && (seed[j] = !(matches[j] = seed[j]));
|
||||
return argument = +argument, markFunction(function(seed, matches) {
|
||||
for(var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length; i--;)seed[j = matchIndexes[i]] && (seed[j] = !(matches[j] = seed[j]));
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -1409,15 +1409,15 @@
|
||||
TAG: function(nodeName) {
|
||||
return "*" === nodeName ? function() {
|
||||
return !0;
|
||||
} : function(elem) {
|
||||
return elem.nodeName && elem.nodeName.toLowerCase() === (nodeName = nodeName.replace(runescape, funescape).toLowerCase());
|
||||
};
|
||||
} : (nodeName = nodeName.replace(runescape, funescape).toLowerCase(), function(elem) {
|
||||
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
|
||||
});
|
||||
},
|
||||
CLASS: function(className) {
|
||||
var pattern = classCache[className + " "];
|
||||
return pattern || classCache(className, function(elem) {
|
||||
return (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")).test(elem.className || void 0 !== elem.getAttribute && elem.getAttribute("class") || "");
|
||||
});
|
||||
return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)"), classCache(className, function(elem) {
|
||||
return pattern.test(elem.className || void 0 !== elem.getAttribute && elem.getAttribute("class") || "");
|
||||
}));
|
||||
},
|
||||
ATTR: function(name, operator, check) {
|
||||
return function(elem) {
|
||||
@ -2257,15 +2257,15 @@
|
||||
for(name in ret = callback.apply(elem, args || []), options)elem.style[name] = old[name];
|
||||
return ret;
|
||||
}
|
||||
}), window.getComputedStyle ? curCSS = function(elem, name, _computed) {
|
||||
var width, minWidth, maxWidth, computed = _computed || (getStyles = function(elem) {
|
||||
return window.getComputedStyle(elem, null);
|
||||
})(elem), ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined, style = elem.style;
|
||||
}), window.getComputedStyle ? (getStyles = function(elem) {
|
||||
return window.getComputedStyle(elem, null);
|
||||
}, curCSS = function(elem, name, _computed) {
|
||||
var width, minWidth, maxWidth, computed = _computed || getStyles(elem), ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined, style = elem.style;
|
||||
return computed && ("" !== ret || jQuery.contains(elem.ownerDocument, elem) || (ret = jQuery.style(elem, name)), rnumnonpx.test(ret) && rmargin.test(name) && (width = style.width, minWidth = style.minWidth, maxWidth = style.maxWidth, style.minWidth = style.maxWidth = style.width = ret, ret = computed.width, style.width = width, style.minWidth = minWidth, style.maxWidth = maxWidth)), ret;
|
||||
} : document.documentElement.currentStyle && (curCSS = function(elem, name, _computed) {
|
||||
var left, rs, rsLeft, computed = _computed || (getStyles = function(elem) {
|
||||
return elem.currentStyle;
|
||||
})(elem), ret = computed ? computed[name] : undefined, style = elem.style;
|
||||
}) : document.documentElement.currentStyle && (getStyles = function(elem) {
|
||||
return elem.currentStyle;
|
||||
}, curCSS = function(elem, name, _computed) {
|
||||
var left, rs, rsLeft, computed = _computed || getStyles(elem), ret = computed ? computed[name] : undefined, style = elem.style;
|
||||
return null == ret && style && style[name] && (ret = style[name]), rnumnonpx.test(ret) && !rposition.test(name) && (left = style.left, (rsLeft = (rs = elem.runtimeStyle) && rs.left) && (rs.left = elem.currentStyle.left), style.left = "fontSize" === name ? "1em" : ret, ret = style.pixelLeft + "px", style.left = left, rsLeft && (rs.left = rsLeft)), "" === ret ? "auto" : ret;
|
||||
}), jQuery.each([
|
||||
"height",
|
||||
|
@ -4496,8 +4496,8 @@
|
||||
_setWidget: function(widget) {
|
||||
if (!this._widget && widget) {
|
||||
var self, orig;
|
||||
this._widget = widget, self = this, this._widget._setOptions = function(options) {
|
||||
(orig = this._widget._setOptions).call(this, options), self._syncTextInputOptions(options);
|
||||
this._widget = widget, self = this, orig = this._widget._setOptions, this._widget._setOptions = function(options) {
|
||||
orig.call(this, options), self._syncTextInputOptions(options);
|
||||
};
|
||||
}
|
||||
return this._widget && (this._syncTextInputOptions(this._widget.options), "listview" === this._widget.widgetName && (this._widget.options.hideDividers = !0, this._widget.element.listview("refresh"))), !!this._widget;
|
||||
|
@ -1748,8 +1748,8 @@ var Element = function(tag, props) {
|
||||
}
|
||||
return document.newElement(tag, props);
|
||||
};
|
||||
Browser.Element && (Element.prototype = Browser.Element.prototype, Element.prototype._fireEvent = function(type, event) {
|
||||
return (fireEvent = Element.prototype.fireEvent).call(this, type, event);
|
||||
Browser.Element && (Element.prototype = Browser.Element.prototype, fireEvent = Element.prototype.fireEvent, Element.prototype._fireEvent = function(type, event) {
|
||||
return fireEvent.call(this, type, event);
|
||||
}), new Type("Element", Element).mirror(function(name) {
|
||||
if (!Array.prototype[name]) {
|
||||
var obj = {
|
||||
@ -1784,9 +1784,9 @@ var IFrame = new Type("IFrame", function() {
|
||||
props.id,
|
||||
props.name,
|
||||
iframe ? iframe.id || iframe.name : "IFrame_" + String.uniqueID()
|
||||
].pick();
|
||||
].pick(), iframe = new Element(iframe || "iframe", props);
|
||||
var onLoad = function() {
|
||||
onload.call((iframe = new Element(iframe || "iframe", props)).contentWindow);
|
||||
onload.call(iframe.contentWindow);
|
||||
};
|
||||
return window.frames[props.id] ? onLoad() : iframe.addListener("load", onLoad), iframe;
|
||||
}), Elements = this.Elements = function(nodes) {
|
||||
@ -3345,8 +3345,9 @@ Elements.prototype = {
|
||||
return trans;
|
||||
}
|
||||
}), Fx.Transition = function(transition, params) {
|
||||
params = Array.from(params);
|
||||
var easeIn = function(pos) {
|
||||
return transition(pos, params = Array.from(params));
|
||||
return transition(pos, params);
|
||||
};
|
||||
return Object.append(easeIn, {
|
||||
easeIn: easeIn,
|
||||
|
@ -242,13 +242,13 @@
|
||||
}
|
||||
if (key || ref) {
|
||||
var props, displayName, warnAboutAccessingKey, props1, displayName1, warnAboutAccessingRef, displayName2 = "function" == typeof type ? type.displayName || type.name || "Unknown" : type;
|
||||
key && (props = props3, (warnAboutAccessingKey = function() {
|
||||
specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", displayName = displayName2));
|
||||
key && (props = props3, displayName = displayName2, (warnAboutAccessingKey = function() {
|
||||
specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", displayName));
|
||||
}).isReactWarning = !0, Object.defineProperty(props, "key", {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: !0
|
||||
})), ref && (props1 = props3, (warnAboutAccessingRef = function() {
|
||||
specialPropRefWarningShown || (specialPropRefWarningShown = !0, error("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", displayName1 = displayName2));
|
||||
})), ref && (props1 = props3, displayName1 = displayName2, (warnAboutAccessingRef = function() {
|
||||
specialPropRefWarningShown || (specialPropRefWarningShown = !0, error("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", displayName1));
|
||||
}).isReactWarning = !0, Object.defineProperty(props1, "ref", {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: !0
|
||||
|
@ -1871,31 +1871,33 @@
|
||||
}
|
||||
var didWarnValueNull = !1, validateProperty$1 = function() {
|
||||
}, warnedProperties$1 = {
|
||||
}, _hasOwnProperty = Object.prototype.hasOwnProperty, EVENT_NAME_REGEX = /^on./, INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/, rARIA$1 = /^(aria)-[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/, rARIACamel$1 = /^(aria)[A-Z][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/, warnUnknownProperties = function(type, props, eventRegistry) {
|
||||
}, _hasOwnProperty = Object.prototype.hasOwnProperty, EVENT_NAME_REGEX = /^on./, INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/, rARIA$1 = /^(aria)-[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/, rARIACamel$1 = /^(aria)[A-Z][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/;
|
||||
validateProperty$1 = function(tagName, name, value, eventRegistry) {
|
||||
if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) return !0;
|
||||
var lowerCasedName = name.toLowerCase();
|
||||
if ("onfocusin" === lowerCasedName || "onfocusout" === lowerCasedName) return error("React uses onFocus and onBlur instead of onFocusIn and onFocusOut. All React events are normalized to bubble, so onFocusIn and onFocusOut are not needed/supported by React."), warnedProperties$1[name] = !0, !0;
|
||||
if (null != eventRegistry) {
|
||||
var registrationNameDependencies = eventRegistry.registrationNameDependencies, possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
|
||||
if (registrationNameDependencies.hasOwnProperty(name)) return !0;
|
||||
var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
|
||||
if (null != registrationName) return error("Invalid event handler property `%s`. Did you mean `%s`?", name, registrationName), warnedProperties$1[name] = !0, !0;
|
||||
if (EVENT_NAME_REGEX.test(name)) return error("Unknown event handler property `%s`. It will be ignored.", name), warnedProperties$1[name] = !0, !0;
|
||||
} else if (EVENT_NAME_REGEX.test(name)) return INVALID_EVENT_NAME_REGEX.test(name) && error("Invalid event handler property `%s`. React events use the camelCase naming convention, for example `onClick`.", name), warnedProperties$1[name] = !0, !0;
|
||||
if (rARIA$1.test(name) || rARIACamel$1.test(name)) return !0;
|
||||
if ("innerhtml" === lowerCasedName) return error("Directly setting property `innerHTML` is not permitted. For more information, lookup documentation on `dangerouslySetInnerHTML`."), warnedProperties$1[name] = !0, !0;
|
||||
if ("aria" === lowerCasedName) return error("The `aria` attribute is reserved for future use in React. Pass individual `aria-` attributes instead."), warnedProperties$1[name] = !0, !0;
|
||||
if ("is" === lowerCasedName && null != value && "string" != typeof value) return error("Received a `%s` for a string attribute `is`. If this is expected, cast the value to a string.", typeof value), warnedProperties$1[name] = !0, !0;
|
||||
if ("number" == typeof value && isNaN(value)) return error("Received NaN for the `%s` attribute. If this is expected, cast the value to a string.", name), warnedProperties$1[name] = !0, !0;
|
||||
var propertyInfo = getPropertyInfo(name), isReserved = null !== propertyInfo && 0 === propertyInfo.type;
|
||||
if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
|
||||
var standardName = possibleStandardNames[lowerCasedName];
|
||||
if (standardName !== name) return error("Invalid DOM property `%s`. Did you mean `%s`?", name, standardName), warnedProperties$1[name] = !0, !0;
|
||||
} else if (!isReserved && name !== lowerCasedName) return error("React does not recognize the `%s` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `%s` instead. If you accidentally passed it from a parent component, remove it from the DOM element.", name, lowerCasedName), warnedProperties$1[name] = !0, !0;
|
||||
return "boolean" == typeof value && shouldRemoveAttributeWithWarning(name, value, propertyInfo, !1) ? (value ? error("Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s=\"%s\" or %s={value.toString()}.", value, name, name, value, name) : error("Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s=\"%s\" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.", value, name, name, value, name, name, name), warnedProperties$1[name] = !0, !0) : !!isReserved || (shouldRemoveAttributeWithWarning(name, value, propertyInfo, !1) ? (warnedProperties$1[name] = !0, !1) : "false" !== value && "true" !== value || null === propertyInfo || 3 !== propertyInfo.type || (error("Received the string `%s` for the boolean attribute `%s`. %s Did you mean %s={%s}?", value, name, "false" === value ? "The browser will interpret it as a truthy value." : "Although this works, it will not work as expected if you pass the string \"false\".", name, value), warnedProperties$1[name] = !0, !0));
|
||||
};
|
||||
var warnUnknownProperties = function(type, props, eventRegistry) {
|
||||
var unknownProps = [];
|
||||
for(var key in props)(validateProperty$1 = function(tagName, name, value, eventRegistry) {
|
||||
if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) return !0;
|
||||
var lowerCasedName = name.toLowerCase();
|
||||
if ("onfocusin" === lowerCasedName || "onfocusout" === lowerCasedName) return error("React uses onFocus and onBlur instead of onFocusIn and onFocusOut. All React events are normalized to bubble, so onFocusIn and onFocusOut are not needed/supported by React."), warnedProperties$1[name] = !0, !0;
|
||||
if (null != eventRegistry) {
|
||||
var registrationNameDependencies = eventRegistry.registrationNameDependencies, possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
|
||||
if (registrationNameDependencies.hasOwnProperty(name)) return !0;
|
||||
var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
|
||||
if (null != registrationName) return error("Invalid event handler property `%s`. Did you mean `%s`?", name, registrationName), warnedProperties$1[name] = !0, !0;
|
||||
if (EVENT_NAME_REGEX.test(name)) return error("Unknown event handler property `%s`. It will be ignored.", name), warnedProperties$1[name] = !0, !0;
|
||||
} else if (EVENT_NAME_REGEX.test(name)) return INVALID_EVENT_NAME_REGEX.test(name) && error("Invalid event handler property `%s`. React events use the camelCase naming convention, for example `onClick`.", name), warnedProperties$1[name] = !0, !0;
|
||||
if (rARIA$1.test(name) || rARIACamel$1.test(name)) return !0;
|
||||
if ("innerhtml" === lowerCasedName) return error("Directly setting property `innerHTML` is not permitted. For more information, lookup documentation on `dangerouslySetInnerHTML`."), warnedProperties$1[name] = !0, !0;
|
||||
if ("aria" === lowerCasedName) return error("The `aria` attribute is reserved for future use in React. Pass individual `aria-` attributes instead."), warnedProperties$1[name] = !0, !0;
|
||||
if ("is" === lowerCasedName && null != value && "string" != typeof value) return error("Received a `%s` for a string attribute `is`. If this is expected, cast the value to a string.", typeof value), warnedProperties$1[name] = !0, !0;
|
||||
if ("number" == typeof value && isNaN(value)) return error("Received NaN for the `%s` attribute. If this is expected, cast the value to a string.", name), warnedProperties$1[name] = !0, !0;
|
||||
var propertyInfo = getPropertyInfo(name), isReserved = null !== propertyInfo && 0 === propertyInfo.type;
|
||||
if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
|
||||
var standardName = possibleStandardNames[lowerCasedName];
|
||||
if (standardName !== name) return error("Invalid DOM property `%s`. Did you mean `%s`?", name, standardName), warnedProperties$1[name] = !0, !0;
|
||||
} else if (!isReserved && name !== lowerCasedName) return error("React does not recognize the `%s` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `%s` instead. If you accidentally passed it from a parent component, remove it from the DOM element.", name, lowerCasedName), warnedProperties$1[name] = !0, !0;
|
||||
return "boolean" == typeof value && shouldRemoveAttributeWithWarning(name, value, propertyInfo, !1) ? (value ? error("Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s=\"%s\" or %s={value.toString()}.", value, name, name, value, name) : error("Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s=\"%s\" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.", value, name, name, value, name, name, name), warnedProperties$1[name] = !0, !0) : !!isReserved || (shouldRemoveAttributeWithWarning(name, value, propertyInfo, !1) ? (warnedProperties$1[name] = !0, !1) : "false" !== value && "true" !== value || null === propertyInfo || 3 !== propertyInfo.type || (error("Received the string `%s` for the boolean attribute `%s`. %s Did you mean %s={%s}?", value, name, "false" === value ? "The browser will interpret it as a truthy value." : "Although this works, it will not work as expected if you pass the string \"false\".", name, value), warnedProperties$1[name] = !0, !0));
|
||||
})(type, key, props[key], eventRegistry) || unknownProps.push(key);
|
||||
for(var key in props)validateProperty$1(type, key, props[key], eventRegistry) || unknownProps.push(key);
|
||||
var unknownPropString = unknownProps.map(function(prop) {
|
||||
return "`" + prop + "`";
|
||||
}).join(", ");
|
||||
@ -6221,6 +6223,74 @@
|
||||
return currentHookNameInDev = "useOpaqueIdentifier", warnInvalidHookAccess(), mountHookTypesDev(), mountOpaqueIdentifier();
|
||||
},
|
||||
unstable_isNewReconciler: enableNewReconciler
|
||||
}, InvalidNestedHooksDispatcherOnUpdateInDEV = {
|
||||
readContext: function(context, observedBits) {
|
||||
return warnInvalidContextAccess(), readContext(context, observedBits);
|
||||
},
|
||||
useCallback: function(callback, deps) {
|
||||
return currentHookNameInDev = "useCallback", warnInvalidHookAccess(), updateHookTypesDev(), updateCallback(callback, deps);
|
||||
},
|
||||
useContext: function(context, observedBits) {
|
||||
return currentHookNameInDev = "useContext", warnInvalidHookAccess(), updateHookTypesDev(), readContext(context, observedBits);
|
||||
},
|
||||
useEffect: function(create, deps) {
|
||||
return currentHookNameInDev = "useEffect", warnInvalidHookAccess(), updateHookTypesDev(), updateEffect(create, deps);
|
||||
},
|
||||
useImperativeHandle: function(ref, create, deps) {
|
||||
return currentHookNameInDev = "useImperativeHandle", warnInvalidHookAccess(), updateHookTypesDev(), updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
return currentHookNameInDev = "useLayoutEffect", warnInvalidHookAccess(), updateHookTypesDev(), updateLayoutEffect(create, deps);
|
||||
},
|
||||
useMemo: function(create, deps) {
|
||||
currentHookNameInDev = "useMemo", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateMemo(create, deps);
|
||||
} finally{
|
||||
ReactCurrentDispatcher$1.current = prevDispatcher;
|
||||
}
|
||||
},
|
||||
useReducer: function(reducer, initialArg, init) {
|
||||
currentHookNameInDev = "useReducer", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateReducer(reducer, initialArg, init);
|
||||
} finally{
|
||||
ReactCurrentDispatcher$1.current = prevDispatcher;
|
||||
}
|
||||
},
|
||||
useRef: function(initialValue) {
|
||||
return currentHookNameInDev = "useRef", warnInvalidHookAccess(), updateHookTypesDev(), updateRef();
|
||||
},
|
||||
useState: function(initialState) {
|
||||
currentHookNameInDev = "useState", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateState(initialState);
|
||||
} finally{
|
||||
ReactCurrentDispatcher$1.current = prevDispatcher;
|
||||
}
|
||||
},
|
||||
useDebugValue: function(value, formatterFn) {
|
||||
return currentHookNameInDev = "useDebugValue", warnInvalidHookAccess(), updateHookTypesDev(), updateDebugValue();
|
||||
},
|
||||
useDeferredValue: function(value) {
|
||||
return currentHookNameInDev = "useDeferredValue", warnInvalidHookAccess(), updateHookTypesDev(), updateDeferredValue(value);
|
||||
},
|
||||
useTransition: function() {
|
||||
return currentHookNameInDev = "useTransition", warnInvalidHookAccess(), updateHookTypesDev(), updateTransition();
|
||||
},
|
||||
useMutableSource: function(source, getSnapshot, subscribe) {
|
||||
return currentHookNameInDev = "useMutableSource", warnInvalidHookAccess(), updateHookTypesDev(), updateMutableSource(source, getSnapshot, subscribe);
|
||||
},
|
||||
useOpaqueIdentifier: function() {
|
||||
return currentHookNameInDev = "useOpaqueIdentifier", warnInvalidHookAccess(), updateHookTypesDev(), updateOpaqueIdentifier();
|
||||
},
|
||||
unstable_isNewReconciler: enableNewReconciler
|
||||
}, InvalidNestedHooksDispatcherOnRerenderInDEV = {
|
||||
readContext: function(context, observedBits) {
|
||||
return warnInvalidContextAccess(), readContext(context, observedBits);
|
||||
@ -6243,75 +6313,7 @@
|
||||
useMemo: function(create, deps) {
|
||||
currentHookNameInDev = "useMemo", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV = {
|
||||
readContext: function(context, observedBits) {
|
||||
return warnInvalidContextAccess(), readContext(context, observedBits);
|
||||
},
|
||||
useCallback: function(callback, deps) {
|
||||
return currentHookNameInDev = "useCallback", warnInvalidHookAccess(), updateHookTypesDev(), updateCallback(callback, deps);
|
||||
},
|
||||
useContext: function(context, observedBits) {
|
||||
return currentHookNameInDev = "useContext", warnInvalidHookAccess(), updateHookTypesDev(), readContext(context, observedBits);
|
||||
},
|
||||
useEffect: function(create, deps) {
|
||||
return currentHookNameInDev = "useEffect", warnInvalidHookAccess(), updateHookTypesDev(), updateEffect(create, deps);
|
||||
},
|
||||
useImperativeHandle: function(ref, create, deps) {
|
||||
return currentHookNameInDev = "useImperativeHandle", warnInvalidHookAccess(), updateHookTypesDev(), updateImperativeHandle(ref, create, deps);
|
||||
},
|
||||
useLayoutEffect: function(create, deps) {
|
||||
return currentHookNameInDev = "useLayoutEffect", warnInvalidHookAccess(), updateHookTypesDev(), updateLayoutEffect(create, deps);
|
||||
},
|
||||
useMemo: function(create, deps) {
|
||||
currentHookNameInDev = "useMemo", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateMemo(create, deps);
|
||||
} finally{
|
||||
ReactCurrentDispatcher$1.current = prevDispatcher;
|
||||
}
|
||||
},
|
||||
useReducer: function(reducer, initialArg, init) {
|
||||
currentHookNameInDev = "useReducer", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateReducer(reducer, initialArg, init);
|
||||
} finally{
|
||||
ReactCurrentDispatcher$1.current = prevDispatcher;
|
||||
}
|
||||
},
|
||||
useRef: function(initialValue) {
|
||||
return currentHookNameInDev = "useRef", warnInvalidHookAccess(), updateHookTypesDev(), updateRef();
|
||||
},
|
||||
useState: function(initialState) {
|
||||
currentHookNameInDev = "useState", warnInvalidHookAccess(), updateHookTypesDev();
|
||||
var prevDispatcher = ReactCurrentDispatcher$1.current;
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateState(initialState);
|
||||
} finally{
|
||||
ReactCurrentDispatcher$1.current = prevDispatcher;
|
||||
}
|
||||
},
|
||||
useDebugValue: function(value, formatterFn) {
|
||||
return currentHookNameInDev = "useDebugValue", warnInvalidHookAccess(), updateHookTypesDev(), updateDebugValue();
|
||||
},
|
||||
useDeferredValue: function(value) {
|
||||
return currentHookNameInDev = "useDeferredValue", warnInvalidHookAccess(), updateHookTypesDev(), updateDeferredValue(value);
|
||||
},
|
||||
useTransition: function() {
|
||||
return currentHookNameInDev = "useTransition", warnInvalidHookAccess(), updateHookTypesDev(), updateTransition();
|
||||
},
|
||||
useMutableSource: function(source, getSnapshot, subscribe) {
|
||||
return currentHookNameInDev = "useMutableSource", warnInvalidHookAccess(), updateHookTypesDev(), updateMutableSource(source, getSnapshot, subscribe);
|
||||
},
|
||||
useOpaqueIdentifier: function() {
|
||||
return currentHookNameInDev = "useOpaqueIdentifier", warnInvalidHookAccess(), updateHookTypesDev(), updateOpaqueIdentifier();
|
||||
},
|
||||
unstable_isNewReconciler: enableNewReconciler
|
||||
};
|
||||
ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
|
||||
try {
|
||||
return updateMemo(create, deps);
|
||||
} finally{
|
||||
|
@ -1 +1,3 @@
|
||||
console.log(1, 2, void 0, void 0);
|
||||
const undef = (a)=>{
|
||||
};
|
||||
console.log(1, 2, undef(3), undef(4));
|
||||
|
@ -21,5 +21,6 @@
|
||||
"lazy": false,
|
||||
"noInterop": false
|
||||
},
|
||||
"sourceMaps": true
|
||||
"sourceMaps": true,
|
||||
"inlineSourcesContent": true
|
||||
}
|
@ -7,5 +7,8 @@
|
||||
"sources": [
|
||||
"../../input/index.ts"
|
||||
],
|
||||
"sourcesContent": [
|
||||
"\n\nexport const foo = {\n arr: []\n};"
|
||||
],
|
||||
"version": 3
|
||||
}
|
||||
|
19
tests/fixture/sourcemap/002/input/.swcrc
Normal file
19
tests/fixture/sourcemap/002/input/.swcrc
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"dynamicImport": false,
|
||||
"decorators": false
|
||||
},
|
||||
"transform": {
|
||||
"legacyDecorator": true,
|
||||
"decoratorMetadata": true
|
||||
},
|
||||
"target": "es5",
|
||||
"loose": false,
|
||||
"externalHelpers": true
|
||||
},
|
||||
"sourceMaps": true,
|
||||
"inlineSourcesContent": true
|
||||
}
|
13
tests/fixture/sourcemap/002/input/index.js
Normal file
13
tests/fixture/sourcemap/002/input/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
export default function StaticPage({ data }) {
|
||||
return <div>{data.foo}</div>
|
||||
}
|
||||
|
||||
export async function getStaticProps() {
|
||||
return {
|
||||
props: {
|
||||
data: {
|
||||
foo: 'bar',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
29
tests/fixture/sourcemap/002/output/index.js
Normal file
29
tests/fixture/sourcemap/002/output/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
import regeneratorRuntime from "regenerator-runtime";
|
||||
export default function StaticPage(param) {
|
||||
var data = param.data;
|
||||
return(/*#__PURE__*/ React.createElement("div", null, data.foo));
|
||||
};
|
||||
function _getStaticProps() {
|
||||
_getStaticProps = swcHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee() {
|
||||
return regeneratorRuntime.wrap(function _callee$(_ctx) {
|
||||
while(1)switch(_ctx.prev = _ctx.next){
|
||||
case 0:
|
||||
return _ctx.abrupt("return", {
|
||||
props: {
|
||||
data: {
|
||||
foo: 'bar'
|
||||
}
|
||||
}
|
||||
});
|
||||
case 1:
|
||||
case "end":
|
||||
return _ctx.stop();
|
||||
}
|
||||
}, _callee);
|
||||
}));
|
||||
return _getStaticProps.apply(this, arguments);
|
||||
}
|
||||
export function getStaticProps() {
|
||||
return _getStaticProps.apply(this, arguments);
|
||||
}
|
18
tests/fixture/sourcemap/002/output/index.map
Normal file
18
tests/fixture/sourcemap/002/output/index.map
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"mappings": ";;eAAe,QAAQ,CAAC,UAAU,CAAC,KAAQ,EAAE,CAAC;QAAT,IAAI,GAAN,KAAQ,CAAN,IAAI;IACrC,MAAM,mCAAE,CAAG,YAAE,IAAI,CAAC,GAAG;AACzB,CAAC;SAEqB,eAAc;IAAd,eAAc,uDAA7B,QAAQ,WAAwB,CAAC;;;;iDAC7B,CAAC;wBACJ,KAAK,EAAE,CAAC;4BACJ,IAAI,EAAE,CAAC;gCACH,GAAG,EAAE,CAAK;4BACd,CAAC;wBACL,CAAC;oBACL,CAAC;;;;;;IACL,CAAC;WARqB,eAAc;;gBAAd,cAAc;WAAd,eAAc",
|
||||
"names": [
|
||||
"StaticPage",
|
||||
"data",
|
||||
"div",
|
||||
"foo",
|
||||
"getStaticProps",
|
||||
"props"
|
||||
],
|
||||
"sources": [
|
||||
"../../input/index.js"
|
||||
],
|
||||
"sourcesContent": [
|
||||
"export default function StaticPage({ data }) {\n return <div>{data.foo}</div>\n}\n\nexport async function getStaticProps() {\n return {\n props: {\n data: {\n foo: 'bar',\n },\n },\n }\n}"
|
||||
],
|
||||
"version": 3
|
||||
}
|
24
tests/fixture/sourcemap/003/input/.swcrc
Normal file
24
tests/fixture/sourcemap/003/input/.swcrc
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"dynamicImport": false,
|
||||
"decorators": false
|
||||
},
|
||||
"transform": {
|
||||
"legacyDecorator": true,
|
||||
"decoratorMetadata": true
|
||||
},
|
||||
"target": "es5",
|
||||
"loose": false,
|
||||
"externalHelpers": true,
|
||||
"minify": {
|
||||
"compress": true,
|
||||
"mangle": true
|
||||
}
|
||||
},
|
||||
"minify": true,
|
||||
"sourceMaps": true,
|
||||
"inlineSourcesContent": true
|
||||
}
|
13
tests/fixture/sourcemap/003/input/index.js
Normal file
13
tests/fixture/sourcemap/003/input/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
export default function StaticPage({ data }) {
|
||||
return <div>{data.foo}</div>
|
||||
}
|
||||
|
||||
export async function getStaticProps() {
|
||||
return {
|
||||
props: {
|
||||
data: {
|
||||
foo: 'bar',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
1
tests/fixture/sourcemap/003/output/index.js
Normal file
1
tests/fixture/sourcemap/003/output/index.js
Normal file
@ -0,0 +1 @@
|
||||
import*as a from"@swc/helpers";import b from"regenerator-runtime";export default function StaticPage(c){var d=c.data;return React.createElement("div",null,d.foo)};function _getStaticProps(){return(_getStaticProps=a.asyncToGenerator(b.mark(function _callee(){return b.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",{props:{data:{foo:"bar"}}});case 1:case"end":return e.stop()}},_callee)}))).apply(this,arguments)}export function getStaticProps(){return _getStaticProps.apply(this,arguments)}
|
18
tests/fixture/sourcemap/003/output/index.map
Normal file
18
tests/fixture/sourcemap/003/output/index.map
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"mappings": "iFAAe,QAAQ,CAAC,UAAU,CAAC,CAAQ,CAAE,CAAC,IAAT,CAAI,CAAN,CAAQ,CAAN,IAAI,CACrC,MAAM,qBAAE,CAAG,UAAE,CAAI,CAAC,GAAG,CACzB,CAAC,UAEqB,eAAc,UAAd,eAAc,2BAA7B,QAAQ,UAAwB,CAAC,uFAC7B,CAAC,AACJ,KAAK,CAAE,CAAC,AACJ,IAAI,CAAE,CAAC,AACH,GAAG,CAAE,CAAK,IACd,CAAC,AACL,CAAC,AACL,CAAC,6CACL,CAAC,0CARqB,cAAc,UAAd,eAAc",
|
||||
"names": [
|
||||
"StaticPage",
|
||||
"data",
|
||||
"div",
|
||||
"foo",
|
||||
"getStaticProps",
|
||||
"props"
|
||||
],
|
||||
"sources": [
|
||||
"../../input/index.js"
|
||||
],
|
||||
"sourcesContent": [
|
||||
"export default function StaticPage({ data }) {\n return <div>{data.foo}</div>\n}\n\nexport async function getStaticProps() {\n return {\n props: {\n data: {\n foo: 'bar',\n },\n },\n }\n}"
|
||||
],
|
||||
"version": 3
|
||||
}
|
@ -790,6 +790,7 @@ fn should_visit() {
|
||||
}
|
||||
|
||||
#[testing::fixture("tests/fixture/**/input/")]
|
||||
#[testing::fixture("tests/vercel/**/input/")]
|
||||
fn tests(input_dir: PathBuf) {
|
||||
let output = input_dir.parent().unwrap().join("output");
|
||||
|
||||
|
24
tests/vercel/full/.swcrc
Normal file
24
tests/vercel/full/.swcrc
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"jsc": {
|
||||
"target": "es5",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true
|
||||
},
|
||||
"transform": {
|
||||
"react": {
|
||||
"runtime": "automatic",
|
||||
"pragma": "React.createElement",
|
||||
"pragmaFrag": "React.Fragment",
|
||||
"throwIfNamespace": true,
|
||||
"useBuiltins": true
|
||||
}
|
||||
},
|
||||
"minify": {
|
||||
"compress": true,
|
||||
"mangle": true,
|
||||
"toplevel": true
|
||||
},
|
||||
"externalHelpers": true
|
||||
}
|
||||
}
|
19
tests/vercel/full/react-instantsearch/1/input/index.js
vendored
Normal file
19
tests/vercel/full/react-instantsearch/1/input/index.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
export default function createStore(initialState) {
|
||||
let state = initialState;
|
||||
const listeners = [];
|
||||
return {
|
||||
getState() {
|
||||
return state;
|
||||
},
|
||||
setState(nextState) {
|
||||
state = nextState;
|
||||
listeners.forEach(listener => listener());
|
||||
},
|
||||
subscribe(listener) {
|
||||
listeners.push(listener);
|
||||
return function unsubscribe() {
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
18
tests/vercel/full/react-instantsearch/1/output/index.js
vendored
Normal file
18
tests/vercel/full/react-instantsearch/1/output/index.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
export default function createStore(a) {
|
||||
var b = a, c = [];
|
||||
return {
|
||||
getState: function() {
|
||||
return b;
|
||||
},
|
||||
setState: function(d) {
|
||||
b = d, c.forEach(function(e) {
|
||||
return e();
|
||||
});
|
||||
},
|
||||
subscribe: function(f) {
|
||||
return c.push(f), function() {
|
||||
c.splice(c.indexOf(f), 1);
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
658
tests/vercel/full/react-instantsearch/2/input/index.js
vendored
Normal file
658
tests/vercel/full/react-instantsearch/2/input/index.js
vendored
Normal file
@ -0,0 +1,658 @@
|
||||
import algoliasearchHelper from 'algoliasearch-helper';
|
||||
import createWidgetsManager from './createWidgetsManager';
|
||||
import { HIGHLIGHT_TAGS } from './highlight';
|
||||
import { hasMultipleIndices } from './indexUtils';
|
||||
import { version as ReactVersion } from 'react';
|
||||
import version from './version';
|
||||
|
||||
|
||||
function addAlgoliaAgents(searchClient) {
|
||||
if (typeof searchClient.addAlgoliaAgent === 'function') {
|
||||
searchClient.addAlgoliaAgent(`react (${ReactVersion})`);
|
||||
searchClient.addAlgoliaAgent(`react-instantsearch (${version})`);
|
||||
}
|
||||
}
|
||||
|
||||
const isMultiIndexContext = widget =>
|
||||
hasMultipleIndices({
|
||||
ais: widget.props.contextValue,
|
||||
multiIndexContext: widget.props.indexContextValue,
|
||||
});
|
||||
const isTargetedIndexEqualIndex = (widget, indexId) =>
|
||||
widget.props.indexContextValue.targetedIndex === indexId;
|
||||
|
||||
// Relying on the `indexId` is a bit brittle to detect the `Index` widget.
|
||||
// Since it's a class we could rely on `instanceof` or similar. We never
|
||||
// had an issue though. Works for now.
|
||||
const isIndexWidget = widget => Boolean(widget.props.indexId);
|
||||
const isIndexWidgetEqualIndex = (widget, indexId) =>
|
||||
widget.props.indexId === indexId;
|
||||
|
||||
const sortIndexWidgetsFirst = (firstWidget, secondWidget) => {
|
||||
const isFirstWidgetIndex = isIndexWidget(firstWidget);
|
||||
const isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
|
||||
if (isFirstWidgetIndex && !isSecondWidgetIndex) {
|
||||
return -1;
|
||||
}
|
||||
if (!isFirstWidgetIndex && isSecondWidgetIndex) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// This function is copied from the algoliasearch v4 API Client. If modified,
|
||||
// consider updating it also in `serializeQueryParameters` from `@algolia/transporter`.
|
||||
function serializeQueryParameters(parameters) {
|
||||
const isObjectOrArray = value =>
|
||||
Object.prototype.toString.call(value) === '[object Object]' ||
|
||||
Object.prototype.toString.call(value) === '[object Array]';
|
||||
|
||||
const encode = (format, ...args) => {
|
||||
let i = 0;
|
||||
return format.replace(/%s/g, () => encodeURIComponent(args[i++]));
|
||||
};
|
||||
|
||||
return Object.keys(parameters)
|
||||
.map(key =>
|
||||
encode(
|
||||
'%s=%s',
|
||||
key,
|
||||
isObjectOrArray(parameters[key])
|
||||
? JSON.stringify(parameters[key])
|
||||
: parameters[key]
|
||||
)
|
||||
)
|
||||
.join('&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the InstantSearchManager which controls the widgets and
|
||||
* trigger the search when the widgets are updated.
|
||||
* @param {string} indexName - the main index name
|
||||
* @param {object} initialState - initial widget state
|
||||
* @param {object} SearchParameters - optional additional parameters to send to the algolia API
|
||||
* @param {number} stalledSearchDelay - time (in ms) after the search is stalled
|
||||
* @return {InstantSearchManager} a new instance of InstantSearchManager
|
||||
*/
|
||||
export default function createInstantSearchManager({
|
||||
indexName,
|
||||
initialState = {},
|
||||
searchClient,
|
||||
resultsState,
|
||||
stalledSearchDelay,
|
||||
}) {
|
||||
|
||||
function createStore(initialState) {
|
||||
let state = initialState;
|
||||
const listeners = [];
|
||||
return {
|
||||
getState() {
|
||||
return state;
|
||||
},
|
||||
setState(nextState) {
|
||||
state = nextState;
|
||||
listeners.forEach(listener => listener());
|
||||
},
|
||||
subscribe(listener) {
|
||||
listeners.push(listener);
|
||||
return function unsubscribe() {
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const helper = algoliasearchHelper(searchClient, indexName, {
|
||||
...HIGHLIGHT_TAGS,
|
||||
});
|
||||
|
||||
addAlgoliaAgents(searchClient);
|
||||
|
||||
helper
|
||||
.on('search', handleNewSearch)
|
||||
.on('result', handleSearchSuccess({ indexId: indexName }))
|
||||
.on('error', handleSearchError);
|
||||
|
||||
let skip = false;
|
||||
let stalledSearchTimer = null;
|
||||
let initialSearchParameters = helper.state;
|
||||
|
||||
const widgetsManager = createWidgetsManager(onWidgetsUpdate);
|
||||
|
||||
hydrateSearchClient(searchClient, resultsState);
|
||||
|
||||
const store = createStore({
|
||||
widgets: initialState,
|
||||
metadata: hydrateMetadata(resultsState),
|
||||
results: hydrateResultsState(resultsState),
|
||||
error: null,
|
||||
searching: false,
|
||||
isSearchStalled: true,
|
||||
searchingForFacetValues: false,
|
||||
});
|
||||
|
||||
function skipSearch() {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
function updateClient(client) {
|
||||
addAlgoliaAgents(client);
|
||||
helper.setClient(client);
|
||||
search();
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
helper.clearCache();
|
||||
search();
|
||||
}
|
||||
|
||||
function getMetadata(state) {
|
||||
return widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getMetadata))
|
||||
.map(widget => widget.getMetadata(state));
|
||||
}
|
||||
|
||||
function getSearchParameters() {
|
||||
const sharedParameters = widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getSearchParameters))
|
||||
.filter(widget => !isMultiIndexContext(widget) && !isIndexWidget(widget))
|
||||
.reduce(
|
||||
(res, widget) => widget.getSearchParameters(res),
|
||||
initialSearchParameters
|
||||
);
|
||||
|
||||
const mainParameters = widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getSearchParameters))
|
||||
.filter(widget => {
|
||||
const targetedIndexEqualMainIndex =
|
||||
isMultiIndexContext(widget) &&
|
||||
isTargetedIndexEqualIndex(widget, indexName);
|
||||
|
||||
const subIndexEqualMainIndex =
|
||||
isIndexWidget(widget) && isIndexWidgetEqualIndex(widget, indexName);
|
||||
|
||||
return targetedIndexEqualMainIndex || subIndexEqualMainIndex;
|
||||
})
|
||||
// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst)
|
||||
.reduce(
|
||||
(res, widget) => widget.getSearchParameters(res),
|
||||
sharedParameters
|
||||
);
|
||||
|
||||
const derivedIndices = widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getSearchParameters))
|
||||
.filter(widget => {
|
||||
const targetedIndexNotEqualMainIndex =
|
||||
isMultiIndexContext(widget) &&
|
||||
!isTargetedIndexEqualIndex(widget, indexName);
|
||||
|
||||
const subIndexNotEqualMainIndex =
|
||||
isIndexWidget(widget) && !isIndexWidgetEqualIndex(widget, indexName);
|
||||
|
||||
return targetedIndexNotEqualMainIndex || subIndexNotEqualMainIndex;
|
||||
})
|
||||
// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst)
|
||||
.reduce((indices, widget) => {
|
||||
const indexId = isMultiIndexContext(widget)
|
||||
? widget.props.indexContextValue.targetedIndex
|
||||
: widget.props.indexId;
|
||||
|
||||
const widgets = indices[indexId] || [];
|
||||
|
||||
return {
|
||||
...indices,
|
||||
[indexId]: widgets.concat(widget),
|
||||
};
|
||||
}, {});
|
||||
|
||||
const derivedParameters = Object.keys(derivedIndices).map(indexId => ({
|
||||
parameters: derivedIndices[indexId].reduce(
|
||||
(res, widget) => widget.getSearchParameters(res),
|
||||
sharedParameters
|
||||
),
|
||||
indexId,
|
||||
}));
|
||||
|
||||
return {
|
||||
mainParameters,
|
||||
derivedParameters,
|
||||
};
|
||||
}
|
||||
|
||||
function search() {
|
||||
if (!skip) {
|
||||
const { mainParameters, derivedParameters } = getSearchParameters(
|
||||
helper.state
|
||||
);
|
||||
|
||||
// We have to call `slice` because the method `detach` on the derived
|
||||
// helpers mutates the value `derivedHelpers`. The `forEach` loop does
|
||||
// not iterate on each value and we're not able to correctly clear the
|
||||
// previous derived helpers (memory leak + useless requests).
|
||||
helper.derivedHelpers.slice().forEach(derivedHelper => {
|
||||
// Since we detach the derived helpers on **every** new search they
|
||||
// won't receive intermediate results in case of a stalled search.
|
||||
// Only the last result is dispatched by the derived helper because
|
||||
// they are not detached yet:
|
||||
//
|
||||
// - a -> main helper receives results
|
||||
// - ap -> main helper receives results
|
||||
// - app -> main helper + derived helpers receive results
|
||||
//
|
||||
// The quick fix is to avoid to detach them on search but only once they
|
||||
// received the results. But it means that in case of a stalled search
|
||||
// all the derived helpers not detached yet register a new search inside
|
||||
// the helper. The number grows fast in case of a bad network and it's
|
||||
// not deterministic.
|
||||
derivedHelper.detach();
|
||||
});
|
||||
|
||||
derivedParameters.forEach(({ indexId, parameters }) => {
|
||||
const derivedHelper = helper.derive(() => parameters);
|
||||
|
||||
derivedHelper
|
||||
.on('result', handleSearchSuccess({ indexId }))
|
||||
.on('error', handleSearchError);
|
||||
});
|
||||
|
||||
helper.setState(mainParameters);
|
||||
|
||||
helper.search();
|
||||
}
|
||||
}
|
||||
|
||||
function handleSearchSuccess({ indexId }) {
|
||||
return event => {
|
||||
const state = store.getState();
|
||||
const isDerivedHelpersEmpty = !helper.derivedHelpers.length;
|
||||
|
||||
let results = state.results ? state.results : {};
|
||||
|
||||
// Switching from mono index to multi index and vice versa must reset the
|
||||
// results to an empty object, otherwise we keep reference of stalled and
|
||||
// unused results.
|
||||
results = !isDerivedHelpersEmpty && results.getFacetByName ? {} : results;
|
||||
|
||||
if (!isDerivedHelpersEmpty) {
|
||||
results = { ...results, [indexId]: event.results };
|
||||
} else {
|
||||
results = event.results;
|
||||
}
|
||||
|
||||
const currentState = store.getState();
|
||||
let nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
stalledSearchTimer = null;
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
|
||||
const { resultsFacetValues, ...partialState } = currentState;
|
||||
|
||||
store.setState({
|
||||
...partialState,
|
||||
results,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
searching: false,
|
||||
error: null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function handleSearchError({ error }) {
|
||||
const currentState = store.getState();
|
||||
|
||||
let nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
|
||||
const { resultsFacetValues, ...partialState } = currentState;
|
||||
|
||||
store.setState({
|
||||
...partialState,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
error,
|
||||
searching: false,
|
||||
});
|
||||
}
|
||||
|
||||
function handleNewSearch() {
|
||||
if (!stalledSearchTimer) {
|
||||
stalledSearchTimer = setTimeout(() => {
|
||||
const { resultsFacetValues, ...partialState } = store.getState();
|
||||
|
||||
store.setState({
|
||||
...partialState,
|
||||
isSearchStalled: true,
|
||||
});
|
||||
}, stalledSearchDelay);
|
||||
}
|
||||
}
|
||||
|
||||
function hydrateSearchClient(client, results) {
|
||||
if (!results) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable cache hydration on:
|
||||
// - Algoliasearch API Client < v4 with cache disabled
|
||||
// - Third party clients (detected by the `addAlgoliaAgent` function missing)
|
||||
|
||||
if (
|
||||
(!client.transporter || client._cacheHydrated) &&
|
||||
(!client._useCache || typeof client.addAlgoliaAgent !== 'function')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Algoliasearch API Client >= v4
|
||||
// To hydrate the client we need to populate the cache with the data from
|
||||
// the server (done in `hydrateSearchClientWithMultiIndexRequest` or
|
||||
// `hydrateSearchClientWithSingleIndexRequest`). But since there is no way
|
||||
// for us to compute the key the same way as `algoliasearch-client` we need
|
||||
// to populate it on a custom key and override the `search` method to
|
||||
// search on it first.
|
||||
if (client.transporter && !client._cacheHydrated) {
|
||||
client._cacheHydrated = true;
|
||||
|
||||
const baseMethod = client.search;
|
||||
client.search = (requests, ...methodArgs) => {
|
||||
const requestsWithSerializedParams = requests.map(request => ({
|
||||
...request,
|
||||
params: serializeQueryParameters(request.params),
|
||||
}));
|
||||
|
||||
return client.transporter.responsesCache.get(
|
||||
{
|
||||
method: 'search',
|
||||
args: [requestsWithSerializedParams, ...methodArgs],
|
||||
},
|
||||
() => {
|
||||
return baseMethod(requests, ...methodArgs);
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
if (Array.isArray(results.results)) {
|
||||
hydrateSearchClientWithMultiIndexRequest(client, results.results);
|
||||
return;
|
||||
}
|
||||
|
||||
hydrateSearchClientWithSingleIndexRequest(client, results);
|
||||
}
|
||||
|
||||
function hydrateSearchClientWithMultiIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set(
|
||||
{
|
||||
method: 'search',
|
||||
args: [
|
||||
results.reduce(
|
||||
(acc, result) =>
|
||||
acc.concat(
|
||||
result.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
}))
|
||||
),
|
||||
[]
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
results: results.reduce(
|
||||
(acc, result) => acc.concat(result.rawResults),
|
||||
[]
|
||||
),
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
const key = `/1/indexes/*/queries_body_${JSON.stringify({
|
||||
requests: results.reduce(
|
||||
(acc, result) =>
|
||||
acc.concat(
|
||||
result.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
}))
|
||||
),
|
||||
[]
|
||||
),
|
||||
})}`;
|
||||
|
||||
client.cache = {
|
||||
...client.cache,
|
||||
[key]: JSON.stringify({
|
||||
results: results.reduce(
|
||||
(acc, result) => acc.concat(result.rawResults),
|
||||
[]
|
||||
),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateSearchClientWithSingleIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set(
|
||||
{
|
||||
method: 'search',
|
||||
args: [
|
||||
results.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
})),
|
||||
],
|
||||
},
|
||||
{
|
||||
results: results.rawResults,
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
const key = `/1/indexes/*/queries_body_${JSON.stringify({
|
||||
requests: results.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
})),
|
||||
})}`;
|
||||
|
||||
client.cache = {
|
||||
...client.cache,
|
||||
[key]: JSON.stringify({
|
||||
results: results.rawResults,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateResultsState(results) {
|
||||
if (!results) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Array.isArray(results.results)) {
|
||||
return results.results.reduce(
|
||||
(acc, result) => ({
|
||||
...acc,
|
||||
[result._internalIndexId]: new algoliasearchHelper.SearchResults(
|
||||
new algoliasearchHelper.SearchParameters(result.state),
|
||||
result.rawResults
|
||||
),
|
||||
}),
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
return new algoliasearchHelper.SearchResults(
|
||||
new algoliasearchHelper.SearchParameters(results.state),
|
||||
results.rawResults
|
||||
);
|
||||
}
|
||||
|
||||
// Called whenever a widget has been rendered with new props.
|
||||
function onWidgetsUpdate() {
|
||||
const metadata = getMetadata(store.getState().widgets);
|
||||
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
metadata,
|
||||
searching: true,
|
||||
});
|
||||
|
||||
// Since the `getSearchParameters` method of widgets also depends on props,
|
||||
// the result search parameters might have changed.
|
||||
search();
|
||||
}
|
||||
|
||||
function transitionState(nextSearchState) {
|
||||
const searchState = store.getState().widgets;
|
||||
|
||||
return widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.transitionState))
|
||||
.reduce(
|
||||
(res, widget) => widget.transitionState(searchState, res),
|
||||
nextSearchState
|
||||
);
|
||||
}
|
||||
|
||||
function onExternalStateUpdate(nextSearchState) {
|
||||
const metadata = getMetadata(nextSearchState);
|
||||
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
widgets: nextSearchState,
|
||||
metadata,
|
||||
searching: true,
|
||||
});
|
||||
|
||||
search();
|
||||
}
|
||||
|
||||
function onSearchForFacetValues({ facetName, query, maxFacetHits = 10 }) {
|
||||
// The values 1, 100 are the min / max values that the engine accepts.
|
||||
// see: https://www.algolia.com/doc/api-reference/api-parameters/maxFacetHits
|
||||
const maxFacetHitsWithinRange = Math.max(1, Math.min(maxFacetHits, 100));
|
||||
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
searchingForFacetValues: true,
|
||||
});
|
||||
|
||||
helper
|
||||
.searchForFacetValues(facetName, query, maxFacetHitsWithinRange)
|
||||
.then(
|
||||
content => {
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
error: null,
|
||||
searchingForFacetValues: false,
|
||||
resultsFacetValues: {
|
||||
...store.getState().resultsFacetValues,
|
||||
[facetName]: content.facetHits,
|
||||
query,
|
||||
},
|
||||
});
|
||||
},
|
||||
error => {
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
searchingForFacetValues: false,
|
||||
error,
|
||||
});
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
// Since setState is synchronous, any error that occurs in the render of a
|
||||
// component will be swallowed by this promise.
|
||||
// This is a trick to make the error show up correctly in the console.
|
||||
// See http://stackoverflow.com/a/30741722/969302
|
||||
setTimeout(() => {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateIndex(newIndex) {
|
||||
initialSearchParameters = initialSearchParameters.setIndex(newIndex);
|
||||
// No need to trigger a new search here as the widgets will also update and trigger it if needed.
|
||||
}
|
||||
|
||||
function getWidgetsIds() {
|
||||
return store
|
||||
.getState()
|
||||
.metadata.reduce(
|
||||
(res, meta) =>
|
||||
typeof meta.id !== 'undefined' ? res.concat(meta.id) : res,
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
store,
|
||||
widgetsManager,
|
||||
getWidgetsIds,
|
||||
getSearchParameters,
|
||||
onSearchForFacetValues,
|
||||
onExternalStateUpdate,
|
||||
transitionState,
|
||||
updateClient,
|
||||
updateIndex,
|
||||
clearCache,
|
||||
skipSearch,
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateMetadata(resultsState) {
|
||||
if (!resultsState) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// add a value noop, which gets replaced once the widgets are mounted
|
||||
return resultsState.metadata.map(datum => ({
|
||||
value: () => ({}),
|
||||
...datum,
|
||||
items:
|
||||
datum.items &&
|
||||
datum.items.map(item => ({
|
||||
value: () => ({}),
|
||||
...item,
|
||||
items:
|
||||
item.items &&
|
||||
item.items.map(nestedItem => ({
|
||||
value: () => ({}),
|
||||
...nestedItem,
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
}
|
370
tests/vercel/full/react-instantsearch/2/output/index.js
vendored
Normal file
370
tests/vercel/full/react-instantsearch/2/output/index.js
vendored
Normal file
@ -0,0 +1,370 @@
|
||||
import * as a from "@swc/helpers";
|
||||
import b from "algoliasearch-helper";
|
||||
import c from "./createWidgetsManager";
|
||||
import { HIGHLIGHT_TAGS as d } from "./highlight";
|
||||
import { hasMultipleIndices as e } from "./indexUtils";
|
||||
import { version as f } from "react";
|
||||
import g from "./version";
|
||||
function addAlgoliaAgents(h) {
|
||||
"function" == typeof h.addAlgoliaAgent && (h.addAlgoliaAgent("react (".concat(f, ")")), h.addAlgoliaAgent("react-instantsearch (".concat(g, ")")));
|
||||
}
|
||||
var _obj, isMultiIndexContext = function(i) {
|
||||
return e({
|
||||
ais: i.props.contextValue,
|
||||
multiIndexContext: i.props.indexContextValue
|
||||
});
|
||||
}, isTargetedIndexEqualIndex = function(j, k) {
|
||||
return j.props.indexContextValue.targetedIndex === k;
|
||||
}, isIndexWidget = function(l) {
|
||||
return Boolean(l.props.indexId);
|
||||
}, isIndexWidgetEqualIndex = function(m, n) {
|
||||
return m.props.indexId === n;
|
||||
}, sortIndexWidgetsFirst = function(o, p) {
|
||||
var q = isIndexWidget(o), r = isIndexWidget(p);
|
||||
return q && !r ? -1 : !q && r ? 1 : 0;
|
||||
};
|
||||
function serializeQueryParameters(s) {
|
||||
var t = function(u) {
|
||||
for(var v = arguments.length, w = new Array(v > 1 ? v - 1 : 0), x = 1; x < v; x++)w[x - 1] = arguments[x];
|
||||
var y = 0;
|
||||
return u.replace(/%s/g, function() {
|
||||
return encodeURIComponent(w[y++]);
|
||||
});
|
||||
};
|
||||
return Object.keys(s).map(function(z) {
|
||||
var A;
|
||||
return t("%s=%s", z, (A = s[z], "[object Object]" === Object.prototype.toString.call(A) || "[object Array]" === Object.prototype.toString.call(A)) ? JSON.stringify(s[z]) : s[z]);
|
||||
}).join("&");
|
||||
}
|
||||
export default function createInstantSearchManager(B) {
|
||||
var C = B.indexName, D = B.initialState, E = B.searchClient, F = B.resultsState, G = B.stalledSearchDelay, H = function(I) {
|
||||
return J.getWidgets().filter(function(K) {
|
||||
return Boolean(K.getMetadata);
|
||||
}).map(function(L) {
|
||||
return L.getMetadata(I);
|
||||
});
|
||||
}, M = function() {
|
||||
var N = J.getWidgets().filter(function(O) {
|
||||
return Boolean(O.getSearchParameters);
|
||||
}).filter(function(P) {
|
||||
return !isMultiIndexContext(P) && !isIndexWidget(P);
|
||||
}).reduce(function(Q, R) {
|
||||
return R.getSearchParameters(Q);
|
||||
}, S), T = J.getWidgets().filter(function(U) {
|
||||
return Boolean(U.getSearchParameters);
|
||||
}).filter(function(V) {
|
||||
var W = isMultiIndexContext(V) && isTargetedIndexEqualIndex(V, C), X = isIndexWidget(V) && isIndexWidgetEqualIndex(V, C);
|
||||
return W || X;
|
||||
}).sort(sortIndexWidgetsFirst).reduce(function(Y, Z) {
|
||||
return Z.getSearchParameters(Y);
|
||||
}, N), $ = J.getWidgets().filter(function(_) {
|
||||
return Boolean(_.getSearchParameters);
|
||||
}).filter(function(aa) {
|
||||
var ba = isMultiIndexContext(aa) && !isTargetedIndexEqualIndex(aa, C), ca = isIndexWidget(aa) && !isIndexWidgetEqualIndex(aa, C);
|
||||
return ba || ca;
|
||||
}).sort(sortIndexWidgetsFirst).reduce(function(da, ea) {
|
||||
var fa = isMultiIndexContext(ea) ? ea.props.indexContextValue.targetedIndex : ea.props.indexId, ga = da[fa] || [];
|
||||
return a.objectSpread({
|
||||
}, da, a.defineProperty({
|
||||
}, fa, ga.concat(ea)));
|
||||
}, {
|
||||
});
|
||||
return {
|
||||
mainParameters: T,
|
||||
derivedParameters: Object.keys($).map(function(ha) {
|
||||
return {
|
||||
parameters: $[ha].reduce(function(ia, ja) {
|
||||
return ja.getSearchParameters(ia);
|
||||
}, N),
|
||||
indexId: ha
|
||||
};
|
||||
})
|
||||
};
|
||||
}, ka = function() {
|
||||
if (!la) {
|
||||
var ma = M(na.state), oa = ma.mainParameters, pa = ma.derivedParameters;
|
||||
na.derivedHelpers.slice().forEach(function(qa) {
|
||||
qa.detach();
|
||||
}), pa.forEach(function(ra) {
|
||||
var sa = ra.indexId, ta = ra.parameters;
|
||||
na.derive(function() {
|
||||
return ta;
|
||||
}).on("result", ua({
|
||||
indexId: sa
|
||||
})).on("error", va);
|
||||
}), na.setState(oa), na.search();
|
||||
}
|
||||
}, ua = function(wa) {
|
||||
var xa = wa.indexId;
|
||||
return function(ya) {
|
||||
var za = Aa.getState(), Ba = !na.derivedHelpers.length, Ca = za.results ? za.results : {
|
||||
};
|
||||
Ca = !Ba && Ca.getFacetByName ? {
|
||||
} : Ca, Ca = Ba ? ya.results : a.objectSpread({
|
||||
}, Ca, a.defineProperty({
|
||||
}, xa, ya.results));
|
||||
var Da = Aa.getState(), Ea = Da.isSearchStalled;
|
||||
na.hasPendingRequests() || (clearTimeout(Fa), Fa = null, Ea = !1), Da.resultsFacetValues;
|
||||
var Ga = a.objectWithoutProperties(Da, ["resultsFacetValues"]);
|
||||
Aa.setState(a.objectSpread({
|
||||
}, Ga, {
|
||||
results: Ca,
|
||||
isSearchStalled: Ea,
|
||||
searching: !1,
|
||||
error: null
|
||||
}));
|
||||
};
|
||||
}, va = function(Ha) {
|
||||
var Ia = Ha.error, Ja = Aa.getState(), Ka = Ja.isSearchStalled;
|
||||
na.hasPendingRequests() || (clearTimeout(Fa), Ka = !1), Ja.resultsFacetValues;
|
||||
var La = a.objectWithoutProperties(Ja, ["resultsFacetValues"]);
|
||||
Aa.setState(a.objectSpread({
|
||||
}, La, {
|
||||
isSearchStalled: Ka,
|
||||
error: Ia,
|
||||
searching: !1
|
||||
}));
|
||||
}, Ma = function(Na, Oa) {
|
||||
if (Na.transporter) {
|
||||
Na.transporter.responsesCache.set({
|
||||
method: "search",
|
||||
args: [
|
||||
Oa.reduce(function(Pa, Qa) {
|
||||
return Pa.concat(Qa.rawResults.map(function(Ra) {
|
||||
return {
|
||||
indexName: Ra.index,
|
||||
params: Ra.params
|
||||
};
|
||||
}));
|
||||
}, []),
|
||||
]
|
||||
}, {
|
||||
results: Oa.reduce(function(Sa, Ta) {
|
||||
return Sa.concat(Ta.rawResults);
|
||||
}, [])
|
||||
});
|
||||
return;
|
||||
}
|
||||
var Ua = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: Oa.reduce(function(Va, Wa) {
|
||||
return Va.concat(Wa.rawResults.map(function(Xa) {
|
||||
return {
|
||||
indexName: Xa.index,
|
||||
params: Xa.params
|
||||
};
|
||||
}));
|
||||
}, [])
|
||||
}));
|
||||
Na.cache = a.objectSpread({
|
||||
}, Na.cache, a.defineProperty({
|
||||
}, Ua, JSON.stringify({
|
||||
results: Oa.reduce(function(Ya, Za) {
|
||||
return Ya.concat(Za.rawResults);
|
||||
}, [])
|
||||
})));
|
||||
}, $a = function(_a, ab) {
|
||||
if (_a.transporter) {
|
||||
_a.transporter.responsesCache.set({
|
||||
method: "search",
|
||||
args: [
|
||||
ab.rawResults.map(function(bb) {
|
||||
return {
|
||||
indexName: bb.index,
|
||||
params: bb.params
|
||||
};
|
||||
}),
|
||||
]
|
||||
}, {
|
||||
results: ab.rawResults
|
||||
});
|
||||
return;
|
||||
}
|
||||
var cb = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: ab.rawResults.map(function(db) {
|
||||
return {
|
||||
indexName: db.index,
|
||||
params: db.params
|
||||
};
|
||||
})
|
||||
}));
|
||||
_a.cache = a.objectSpread({
|
||||
}, _a.cache, a.defineProperty({
|
||||
}, cb, JSON.stringify({
|
||||
results: ab.rawResults
|
||||
})));
|
||||
}, na = b(E, C, a.objectSpread({
|
||||
}, d));
|
||||
addAlgoliaAgents(E), na.on("search", function() {
|
||||
Fa || (Fa = setTimeout(function() {
|
||||
var eb = Aa.getState(), fb = eb.resultsFacetValues, gb = a.objectWithoutProperties(eb, ["resultsFacetValues"]);
|
||||
Aa.setState(a.objectSpread({
|
||||
}, gb, {
|
||||
isSearchStalled: !0
|
||||
}));
|
||||
}, G));
|
||||
}).on("result", ua({
|
||||
indexId: C
|
||||
})).on("error", va);
|
||||
var la = !1, Fa = null, S = na.state, J = c(function() {
|
||||
var hb = H(Aa.getState().widgets);
|
||||
Aa.setState(a.objectSpread({
|
||||
}, Aa.getState(), {
|
||||
metadata: hb,
|
||||
searching: !0
|
||||
})), ka();
|
||||
});
|
||||
!function(ib, jb) {
|
||||
if (jb && (ib.transporter && !ib._cacheHydrated || ib._useCache && "function" == typeof ib.addAlgoliaAgent)) {
|
||||
if (ib.transporter && !ib._cacheHydrated) {
|
||||
ib._cacheHydrated = !0;
|
||||
var kb = ib.search;
|
||||
ib.search = function(lb) {
|
||||
for(var mb = arguments.length, nb = new Array(mb > 1 ? mb - 1 : 0), ob = 1; ob < mb; ob++)nb[ob - 1] = arguments[ob];
|
||||
var pb = lb.map(function(qb) {
|
||||
return a.objectSpread({
|
||||
}, qb, {
|
||||
params: serializeQueryParameters(qb.params)
|
||||
});
|
||||
});
|
||||
return ib.transporter.responsesCache.get({
|
||||
method: "search",
|
||||
args: [
|
||||
pb
|
||||
].concat(a.toConsumableArray(nb))
|
||||
}, function() {
|
||||
return kb.apply(void 0, [
|
||||
lb
|
||||
].concat(a.toConsumableArray(nb)));
|
||||
});
|
||||
};
|
||||
}
|
||||
if (Array.isArray(jb.results)) {
|
||||
Ma(ib, jb.results);
|
||||
return;
|
||||
}
|
||||
$a(ib, jb);
|
||||
}
|
||||
}(E, F);
|
||||
var rb, sb, tb, Aa = (sb = {
|
||||
widgets: void 0 === D ? {
|
||||
} : D,
|
||||
metadata: hydrateMetadata(F),
|
||||
results: (rb = F) ? Array.isArray(rb.results) ? rb.results.reduce(function(ub, vb) {
|
||||
return a.objectSpread({
|
||||
}, ub, a.defineProperty({
|
||||
}, vb._internalIndexId, new b.SearchResults(new b.SearchParameters(vb.state), vb.rawResults)));
|
||||
}, {
|
||||
}) : new b.SearchResults(new b.SearchParameters(rb.state), rb.rawResults) : null,
|
||||
error: null,
|
||||
searching: !1,
|
||||
isSearchStalled: !0,
|
||||
searchingForFacetValues: !1
|
||||
}, tb = [], {
|
||||
getState: function() {
|
||||
return sb;
|
||||
},
|
||||
setState: function(wb) {
|
||||
sb = wb, tb.forEach(function(xb) {
|
||||
return xb();
|
||||
});
|
||||
},
|
||||
subscribe: function(yb) {
|
||||
return tb.push(yb), function() {
|
||||
tb.splice(tb.indexOf(yb), 1);
|
||||
};
|
||||
}
|
||||
});
|
||||
return {
|
||||
store: Aa,
|
||||
widgetsManager: J,
|
||||
getWidgetsIds: function() {
|
||||
return Aa.getState().metadata.reduce(function(zb, Ab) {
|
||||
return void 0 !== Ab.id ? zb.concat(Ab.id) : zb;
|
||||
}, []);
|
||||
},
|
||||
getSearchParameters: M,
|
||||
onSearchForFacetValues: function(Bb) {
|
||||
var Cb = Bb.facetName, Db = Bb.query, Eb = Bb.maxFacetHits;
|
||||
Aa.setState(a.objectSpread({
|
||||
}, Aa.getState(), {
|
||||
searchingForFacetValues: !0
|
||||
})), na.searchForFacetValues(Cb, Db, Math.max(1, Math.min(void 0 === Eb ? 10 : Eb, 100))).then(function(Fb) {
|
||||
Aa.setState(a.objectSpread({
|
||||
}, Aa.getState(), {
|
||||
error: null,
|
||||
searchingForFacetValues: !1,
|
||||
resultsFacetValues: a.objectSpread({
|
||||
}, Aa.getState().resultsFacetValues, (_obj = {
|
||||
}, a.defineProperty(_obj, Cb, Fb.facetHits), a.defineProperty(_obj, "query", Db), _obj))
|
||||
}));
|
||||
}, function(Gb) {
|
||||
Aa.setState(a.objectSpread({
|
||||
}, Aa.getState(), {
|
||||
searchingForFacetValues: !1,
|
||||
error: Gb
|
||||
}));
|
||||
}).catch(function(Hb) {
|
||||
setTimeout(function() {
|
||||
throw Hb;
|
||||
});
|
||||
});
|
||||
},
|
||||
onExternalStateUpdate: function(Ib) {
|
||||
var Jb = H(Ib);
|
||||
Aa.setState(a.objectSpread({
|
||||
}, Aa.getState(), {
|
||||
widgets: Ib,
|
||||
metadata: Jb,
|
||||
searching: !0
|
||||
})), ka();
|
||||
},
|
||||
transitionState: function(Kb) {
|
||||
var Lb = Aa.getState().widgets;
|
||||
return J.getWidgets().filter(function(Mb) {
|
||||
return Boolean(Mb.transitionState);
|
||||
}).reduce(function(Nb, Ob) {
|
||||
return Ob.transitionState(Lb, Nb);
|
||||
}, Kb);
|
||||
},
|
||||
updateClient: function(Pb) {
|
||||
addAlgoliaAgents(Pb), na.setClient(Pb), ka();
|
||||
},
|
||||
updateIndex: function(Qb) {
|
||||
S = S.setIndex(Qb);
|
||||
},
|
||||
clearCache: function() {
|
||||
na.clearCache(), ka();
|
||||
},
|
||||
skipSearch: function() {
|
||||
la = !0;
|
||||
}
|
||||
};
|
||||
};
|
||||
function hydrateMetadata(Rb) {
|
||||
return Rb ? Rb.metadata.map(function(Sb) {
|
||||
return a.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, Sb, {
|
||||
items: Sb.items && Sb.items.map(function(Tb) {
|
||||
return a.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, Tb, {
|
||||
items: Tb.items && Tb.items.map(function(Ub) {
|
||||
return a.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, Ub);
|
||||
})
|
||||
});
|
||||
})
|
||||
});
|
||||
}) : [];
|
||||
}
|
19
tests/vercel/loader-only/.swcrc
Normal file
19
tests/vercel/loader-only/.swcrc
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"jsc": {
|
||||
"target": "es5",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true
|
||||
},
|
||||
"transform": {
|
||||
"react": {
|
||||
"runtime": "automatic",
|
||||
"pragma": "React.createElement",
|
||||
"pragmaFrag": "React.Fragment",
|
||||
"throwIfNamespace": true,
|
||||
"useBuiltins": true
|
||||
}
|
||||
},
|
||||
"externalHelpers": true
|
||||
}
|
||||
}
|
658
tests/vercel/loader-only/react-instantsearch/1/input/index.js
vendored
Normal file
658
tests/vercel/loader-only/react-instantsearch/1/input/index.js
vendored
Normal file
@ -0,0 +1,658 @@
|
||||
import algoliasearchHelper from 'algoliasearch-helper';
|
||||
import createWidgetsManager from './createWidgetsManager';
|
||||
import { HIGHLIGHT_TAGS } from './highlight';
|
||||
import { hasMultipleIndices } from './indexUtils';
|
||||
import { version as ReactVersion } from 'react';
|
||||
import version from './version';
|
||||
|
||||
|
||||
function addAlgoliaAgents(searchClient) {
|
||||
if (typeof searchClient.addAlgoliaAgent === 'function') {
|
||||
searchClient.addAlgoliaAgent(`react (${ReactVersion})`);
|
||||
searchClient.addAlgoliaAgent(`react-instantsearch (${version})`);
|
||||
}
|
||||
}
|
||||
|
||||
const isMultiIndexContext = widget =>
|
||||
hasMultipleIndices({
|
||||
ais: widget.props.contextValue,
|
||||
multiIndexContext: widget.props.indexContextValue,
|
||||
});
|
||||
const isTargetedIndexEqualIndex = (widget, indexId) =>
|
||||
widget.props.indexContextValue.targetedIndex === indexId;
|
||||
|
||||
// Relying on the `indexId` is a bit brittle to detect the `Index` widget.
|
||||
// Since it's a class we could rely on `instanceof` or similar. We never
|
||||
// had an issue though. Works for now.
|
||||
const isIndexWidget = widget => Boolean(widget.props.indexId);
|
||||
const isIndexWidgetEqualIndex = (widget, indexId) =>
|
||||
widget.props.indexId === indexId;
|
||||
|
||||
const sortIndexWidgetsFirst = (firstWidget, secondWidget) => {
|
||||
const isFirstWidgetIndex = isIndexWidget(firstWidget);
|
||||
const isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
|
||||
if (isFirstWidgetIndex && !isSecondWidgetIndex) {
|
||||
return -1;
|
||||
}
|
||||
if (!isFirstWidgetIndex && isSecondWidgetIndex) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// This function is copied from the algoliasearch v4 API Client. If modified,
|
||||
// consider updating it also in `serializeQueryParameters` from `@algolia/transporter`.
|
||||
function serializeQueryParameters(parameters) {
|
||||
const isObjectOrArray = value =>
|
||||
Object.prototype.toString.call(value) === '[object Object]' ||
|
||||
Object.prototype.toString.call(value) === '[object Array]';
|
||||
|
||||
const encode = (format, ...args) => {
|
||||
let i = 0;
|
||||
return format.replace(/%s/g, () => encodeURIComponent(args[i++]));
|
||||
};
|
||||
|
||||
return Object.keys(parameters)
|
||||
.map(key =>
|
||||
encode(
|
||||
'%s=%s',
|
||||
key,
|
||||
isObjectOrArray(parameters[key])
|
||||
? JSON.stringify(parameters[key])
|
||||
: parameters[key]
|
||||
)
|
||||
)
|
||||
.join('&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the InstantSearchManager which controls the widgets and
|
||||
* trigger the search when the widgets are updated.
|
||||
* @param {string} indexName - the main index name
|
||||
* @param {object} initialState - initial widget state
|
||||
* @param {object} SearchParameters - optional additional parameters to send to the algolia API
|
||||
* @param {number} stalledSearchDelay - time (in ms) after the search is stalled
|
||||
* @return {InstantSearchManager} a new instance of InstantSearchManager
|
||||
*/
|
||||
export default function createInstantSearchManager({
|
||||
indexName,
|
||||
initialState = {},
|
||||
searchClient,
|
||||
resultsState,
|
||||
stalledSearchDelay,
|
||||
}) {
|
||||
|
||||
function createStore(initialState) {
|
||||
let state = initialState;
|
||||
const listeners = [];
|
||||
return {
|
||||
getState() {
|
||||
return state;
|
||||
},
|
||||
setState(nextState) {
|
||||
state = nextState;
|
||||
listeners.forEach(listener => listener());
|
||||
},
|
||||
subscribe(listener) {
|
||||
listeners.push(listener);
|
||||
return function unsubscribe() {
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const helper = algoliasearchHelper(searchClient, indexName, {
|
||||
...HIGHLIGHT_TAGS,
|
||||
});
|
||||
|
||||
addAlgoliaAgents(searchClient);
|
||||
|
||||
helper
|
||||
.on('search', handleNewSearch)
|
||||
.on('result', handleSearchSuccess({ indexId: indexName }))
|
||||
.on('error', handleSearchError);
|
||||
|
||||
let skip = false;
|
||||
let stalledSearchTimer = null;
|
||||
let initialSearchParameters = helper.state;
|
||||
|
||||
const widgetsManager = createWidgetsManager(onWidgetsUpdate);
|
||||
|
||||
hydrateSearchClient(searchClient, resultsState);
|
||||
|
||||
const store = createStore({
|
||||
widgets: initialState,
|
||||
metadata: hydrateMetadata(resultsState),
|
||||
results: hydrateResultsState(resultsState),
|
||||
error: null,
|
||||
searching: false,
|
||||
isSearchStalled: true,
|
||||
searchingForFacetValues: false,
|
||||
});
|
||||
|
||||
function skipSearch() {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
function updateClient(client) {
|
||||
addAlgoliaAgents(client);
|
||||
helper.setClient(client);
|
||||
search();
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
helper.clearCache();
|
||||
search();
|
||||
}
|
||||
|
||||
function getMetadata(state) {
|
||||
return widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getMetadata))
|
||||
.map(widget => widget.getMetadata(state));
|
||||
}
|
||||
|
||||
function getSearchParameters() {
|
||||
const sharedParameters = widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getSearchParameters))
|
||||
.filter(widget => !isMultiIndexContext(widget) && !isIndexWidget(widget))
|
||||
.reduce(
|
||||
(res, widget) => widget.getSearchParameters(res),
|
||||
initialSearchParameters
|
||||
);
|
||||
|
||||
const mainParameters = widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getSearchParameters))
|
||||
.filter(widget => {
|
||||
const targetedIndexEqualMainIndex =
|
||||
isMultiIndexContext(widget) &&
|
||||
isTargetedIndexEqualIndex(widget, indexName);
|
||||
|
||||
const subIndexEqualMainIndex =
|
||||
isIndexWidget(widget) && isIndexWidgetEqualIndex(widget, indexName);
|
||||
|
||||
return targetedIndexEqualMainIndex || subIndexEqualMainIndex;
|
||||
})
|
||||
// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst)
|
||||
.reduce(
|
||||
(res, widget) => widget.getSearchParameters(res),
|
||||
sharedParameters
|
||||
);
|
||||
|
||||
const derivedIndices = widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.getSearchParameters))
|
||||
.filter(widget => {
|
||||
const targetedIndexNotEqualMainIndex =
|
||||
isMultiIndexContext(widget) &&
|
||||
!isTargetedIndexEqualIndex(widget, indexName);
|
||||
|
||||
const subIndexNotEqualMainIndex =
|
||||
isIndexWidget(widget) && !isIndexWidgetEqualIndex(widget, indexName);
|
||||
|
||||
return targetedIndexNotEqualMainIndex || subIndexNotEqualMainIndex;
|
||||
})
|
||||
// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst)
|
||||
.reduce((indices, widget) => {
|
||||
const indexId = isMultiIndexContext(widget)
|
||||
? widget.props.indexContextValue.targetedIndex
|
||||
: widget.props.indexId;
|
||||
|
||||
const widgets = indices[indexId] || [];
|
||||
|
||||
return {
|
||||
...indices,
|
||||
[indexId]: widgets.concat(widget),
|
||||
};
|
||||
}, {});
|
||||
|
||||
const derivedParameters = Object.keys(derivedIndices).map(indexId => ({
|
||||
parameters: derivedIndices[indexId].reduce(
|
||||
(res, widget) => widget.getSearchParameters(res),
|
||||
sharedParameters
|
||||
),
|
||||
indexId,
|
||||
}));
|
||||
|
||||
return {
|
||||
mainParameters,
|
||||
derivedParameters,
|
||||
};
|
||||
}
|
||||
|
||||
function search() {
|
||||
if (!skip) {
|
||||
const { mainParameters, derivedParameters } = getSearchParameters(
|
||||
helper.state
|
||||
);
|
||||
|
||||
// We have to call `slice` because the method `detach` on the derived
|
||||
// helpers mutates the value `derivedHelpers`. The `forEach` loop does
|
||||
// not iterate on each value and we're not able to correctly clear the
|
||||
// previous derived helpers (memory leak + useless requests).
|
||||
helper.derivedHelpers.slice().forEach(derivedHelper => {
|
||||
// Since we detach the derived helpers on **every** new search they
|
||||
// won't receive intermediate results in case of a stalled search.
|
||||
// Only the last result is dispatched by the derived helper because
|
||||
// they are not detached yet:
|
||||
//
|
||||
// - a -> main helper receives results
|
||||
// - ap -> main helper receives results
|
||||
// - app -> main helper + derived helpers receive results
|
||||
//
|
||||
// The quick fix is to avoid to detach them on search but only once they
|
||||
// received the results. But it means that in case of a stalled search
|
||||
// all the derived helpers not detached yet register a new search inside
|
||||
// the helper. The number grows fast in case of a bad network and it's
|
||||
// not deterministic.
|
||||
derivedHelper.detach();
|
||||
});
|
||||
|
||||
derivedParameters.forEach(({ indexId, parameters }) => {
|
||||
const derivedHelper = helper.derive(() => parameters);
|
||||
|
||||
derivedHelper
|
||||
.on('result', handleSearchSuccess({ indexId }))
|
||||
.on('error', handleSearchError);
|
||||
});
|
||||
|
||||
helper.setState(mainParameters);
|
||||
|
||||
helper.search();
|
||||
}
|
||||
}
|
||||
|
||||
function handleSearchSuccess({ indexId }) {
|
||||
return event => {
|
||||
const state = store.getState();
|
||||
const isDerivedHelpersEmpty = !helper.derivedHelpers.length;
|
||||
|
||||
let results = state.results ? state.results : {};
|
||||
|
||||
// Switching from mono index to multi index and vice versa must reset the
|
||||
// results to an empty object, otherwise we keep reference of stalled and
|
||||
// unused results.
|
||||
results = !isDerivedHelpersEmpty && results.getFacetByName ? {} : results;
|
||||
|
||||
if (!isDerivedHelpersEmpty) {
|
||||
results = { ...results, [indexId]: event.results };
|
||||
} else {
|
||||
results = event.results;
|
||||
}
|
||||
|
||||
const currentState = store.getState();
|
||||
let nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
stalledSearchTimer = null;
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
|
||||
const { resultsFacetValues, ...partialState } = currentState;
|
||||
|
||||
store.setState({
|
||||
...partialState,
|
||||
results,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
searching: false,
|
||||
error: null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function handleSearchError({ error }) {
|
||||
const currentState = store.getState();
|
||||
|
||||
let nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
|
||||
const { resultsFacetValues, ...partialState } = currentState;
|
||||
|
||||
store.setState({
|
||||
...partialState,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
error,
|
||||
searching: false,
|
||||
});
|
||||
}
|
||||
|
||||
function handleNewSearch() {
|
||||
if (!stalledSearchTimer) {
|
||||
stalledSearchTimer = setTimeout(() => {
|
||||
const { resultsFacetValues, ...partialState } = store.getState();
|
||||
|
||||
store.setState({
|
||||
...partialState,
|
||||
isSearchStalled: true,
|
||||
});
|
||||
}, stalledSearchDelay);
|
||||
}
|
||||
}
|
||||
|
||||
function hydrateSearchClient(client, results) {
|
||||
if (!results) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable cache hydration on:
|
||||
// - Algoliasearch API Client < v4 with cache disabled
|
||||
// - Third party clients (detected by the `addAlgoliaAgent` function missing)
|
||||
|
||||
if (
|
||||
(!client.transporter || client._cacheHydrated) &&
|
||||
(!client._useCache || typeof client.addAlgoliaAgent !== 'function')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Algoliasearch API Client >= v4
|
||||
// To hydrate the client we need to populate the cache with the data from
|
||||
// the server (done in `hydrateSearchClientWithMultiIndexRequest` or
|
||||
// `hydrateSearchClientWithSingleIndexRequest`). But since there is no way
|
||||
// for us to compute the key the same way as `algoliasearch-client` we need
|
||||
// to populate it on a custom key and override the `search` method to
|
||||
// search on it first.
|
||||
if (client.transporter && !client._cacheHydrated) {
|
||||
client._cacheHydrated = true;
|
||||
|
||||
const baseMethod = client.search;
|
||||
client.search = (requests, ...methodArgs) => {
|
||||
const requestsWithSerializedParams = requests.map(request => ({
|
||||
...request,
|
||||
params: serializeQueryParameters(request.params),
|
||||
}));
|
||||
|
||||
return client.transporter.responsesCache.get(
|
||||
{
|
||||
method: 'search',
|
||||
args: [requestsWithSerializedParams, ...methodArgs],
|
||||
},
|
||||
() => {
|
||||
return baseMethod(requests, ...methodArgs);
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
if (Array.isArray(results.results)) {
|
||||
hydrateSearchClientWithMultiIndexRequest(client, results.results);
|
||||
return;
|
||||
}
|
||||
|
||||
hydrateSearchClientWithSingleIndexRequest(client, results);
|
||||
}
|
||||
|
||||
function hydrateSearchClientWithMultiIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set(
|
||||
{
|
||||
method: 'search',
|
||||
args: [
|
||||
results.reduce(
|
||||
(acc, result) =>
|
||||
acc.concat(
|
||||
result.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
}))
|
||||
),
|
||||
[]
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
results: results.reduce(
|
||||
(acc, result) => acc.concat(result.rawResults),
|
||||
[]
|
||||
),
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
const key = `/1/indexes/*/queries_body_${JSON.stringify({
|
||||
requests: results.reduce(
|
||||
(acc, result) =>
|
||||
acc.concat(
|
||||
result.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
}))
|
||||
),
|
||||
[]
|
||||
),
|
||||
})}`;
|
||||
|
||||
client.cache = {
|
||||
...client.cache,
|
||||
[key]: JSON.stringify({
|
||||
results: results.reduce(
|
||||
(acc, result) => acc.concat(result.rawResults),
|
||||
[]
|
||||
),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateSearchClientWithSingleIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set(
|
||||
{
|
||||
method: 'search',
|
||||
args: [
|
||||
results.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
})),
|
||||
],
|
||||
},
|
||||
{
|
||||
results: results.rawResults,
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
const key = `/1/indexes/*/queries_body_${JSON.stringify({
|
||||
requests: results.rawResults.map(request => ({
|
||||
indexName: request.index,
|
||||
params: request.params,
|
||||
})),
|
||||
})}`;
|
||||
|
||||
client.cache = {
|
||||
...client.cache,
|
||||
[key]: JSON.stringify({
|
||||
results: results.rawResults,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateResultsState(results) {
|
||||
if (!results) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Array.isArray(results.results)) {
|
||||
return results.results.reduce(
|
||||
(acc, result) => ({
|
||||
...acc,
|
||||
[result._internalIndexId]: new algoliasearchHelper.SearchResults(
|
||||
new algoliasearchHelper.SearchParameters(result.state),
|
||||
result.rawResults
|
||||
),
|
||||
}),
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
return new algoliasearchHelper.SearchResults(
|
||||
new algoliasearchHelper.SearchParameters(results.state),
|
||||
results.rawResults
|
||||
);
|
||||
}
|
||||
|
||||
// Called whenever a widget has been rendered with new props.
|
||||
function onWidgetsUpdate() {
|
||||
const metadata = getMetadata(store.getState().widgets);
|
||||
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
metadata,
|
||||
searching: true,
|
||||
});
|
||||
|
||||
// Since the `getSearchParameters` method of widgets also depends on props,
|
||||
// the result search parameters might have changed.
|
||||
search();
|
||||
}
|
||||
|
||||
function transitionState(nextSearchState) {
|
||||
const searchState = store.getState().widgets;
|
||||
|
||||
return widgetsManager
|
||||
.getWidgets()
|
||||
.filter(widget => Boolean(widget.transitionState))
|
||||
.reduce(
|
||||
(res, widget) => widget.transitionState(searchState, res),
|
||||
nextSearchState
|
||||
);
|
||||
}
|
||||
|
||||
function onExternalStateUpdate(nextSearchState) {
|
||||
const metadata = getMetadata(nextSearchState);
|
||||
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
widgets: nextSearchState,
|
||||
metadata,
|
||||
searching: true,
|
||||
});
|
||||
|
||||
search();
|
||||
}
|
||||
|
||||
function onSearchForFacetValues({ facetName, query, maxFacetHits = 10 }) {
|
||||
// The values 1, 100 are the min / max values that the engine accepts.
|
||||
// see: https://www.algolia.com/doc/api-reference/api-parameters/maxFacetHits
|
||||
const maxFacetHitsWithinRange = Math.max(1, Math.min(maxFacetHits, 100));
|
||||
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
searchingForFacetValues: true,
|
||||
});
|
||||
|
||||
helper
|
||||
.searchForFacetValues(facetName, query, maxFacetHitsWithinRange)
|
||||
.then(
|
||||
content => {
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
error: null,
|
||||
searchingForFacetValues: false,
|
||||
resultsFacetValues: {
|
||||
...store.getState().resultsFacetValues,
|
||||
[facetName]: content.facetHits,
|
||||
query,
|
||||
},
|
||||
});
|
||||
},
|
||||
error => {
|
||||
store.setState({
|
||||
...store.getState(),
|
||||
searchingForFacetValues: false,
|
||||
error,
|
||||
});
|
||||
}
|
||||
)
|
||||
.catch(error => {
|
||||
// Since setState is synchronous, any error that occurs in the render of a
|
||||
// component will be swallowed by this promise.
|
||||
// This is a trick to make the error show up correctly in the console.
|
||||
// See http://stackoverflow.com/a/30741722/969302
|
||||
setTimeout(() => {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateIndex(newIndex) {
|
||||
initialSearchParameters = initialSearchParameters.setIndex(newIndex);
|
||||
// No need to trigger a new search here as the widgets will also update and trigger it if needed.
|
||||
}
|
||||
|
||||
function getWidgetsIds() {
|
||||
return store
|
||||
.getState()
|
||||
.metadata.reduce(
|
||||
(res, meta) =>
|
||||
typeof meta.id !== 'undefined' ? res.concat(meta.id) : res,
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
store,
|
||||
widgetsManager,
|
||||
getWidgetsIds,
|
||||
getSearchParameters,
|
||||
onSearchForFacetValues,
|
||||
onExternalStateUpdate,
|
||||
transitionState,
|
||||
updateClient,
|
||||
updateIndex,
|
||||
clearCache,
|
||||
skipSearch,
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateMetadata(resultsState) {
|
||||
if (!resultsState) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// add a value noop, which gets replaced once the widgets are mounted
|
||||
return resultsState.metadata.map(datum => ({
|
||||
value: () => ({}),
|
||||
...datum,
|
||||
items:
|
||||
datum.items &&
|
||||
datum.items.map(item => ({
|
||||
value: () => ({}),
|
||||
...item,
|
||||
items:
|
||||
item.items &&
|
||||
item.items.map(nestedItem => ({
|
||||
value: () => ({}),
|
||||
...nestedItem,
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
}
|
548
tests/vercel/loader-only/react-instantsearch/1/output/index.js
vendored
Normal file
548
tests/vercel/loader-only/react-instantsearch/1/output/index.js
vendored
Normal file
@ -0,0 +1,548 @@
|
||||
import * as swcHelpers from "@swc/helpers";
|
||||
import algoliasearchHelper from 'algoliasearch-helper';
|
||||
import createWidgetsManager from './createWidgetsManager';
|
||||
import { HIGHLIGHT_TAGS } from './highlight';
|
||||
import { hasMultipleIndices } from './indexUtils';
|
||||
import { version as ReactVersion } from 'react';
|
||||
import version from './version';
|
||||
function addAlgoliaAgents(searchClient) {
|
||||
if (typeof searchClient.addAlgoliaAgent === 'function') {
|
||||
searchClient.addAlgoliaAgent("react (".concat(ReactVersion, ")"));
|
||||
searchClient.addAlgoliaAgent("react-instantsearch (".concat(version, ")"));
|
||||
}
|
||||
}
|
||||
var isMultiIndexContext = function(widget) {
|
||||
return hasMultipleIndices({
|
||||
ais: widget.props.contextValue,
|
||||
multiIndexContext: widget.props.indexContextValue
|
||||
});
|
||||
};
|
||||
var isTargetedIndexEqualIndex = function(widget, indexId) {
|
||||
return widget.props.indexContextValue.targetedIndex === indexId;
|
||||
};
|
||||
// Relying on the `indexId` is a bit brittle to detect the `Index` widget.
|
||||
// Since it's a class we could rely on `instanceof` or similar. We never
|
||||
// had an issue though. Works for now.
|
||||
var isIndexWidget = function(widget) {
|
||||
return Boolean(widget.props.indexId);
|
||||
};
|
||||
var isIndexWidgetEqualIndex = function(widget, indexId) {
|
||||
return widget.props.indexId === indexId;
|
||||
};
|
||||
var sortIndexWidgetsFirst = function(firstWidget, secondWidget) {
|
||||
var isFirstWidgetIndex = isIndexWidget(firstWidget);
|
||||
var isSecondWidgetIndex = isIndexWidget(secondWidget);
|
||||
if (isFirstWidgetIndex && !isSecondWidgetIndex) {
|
||||
return -1;
|
||||
}
|
||||
if (!isFirstWidgetIndex && isSecondWidgetIndex) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
// This function is copied from the algoliasearch v4 API Client. If modified,
|
||||
// consider updating it also in `serializeQueryParameters` from `@algolia/transporter`.
|
||||
function serializeQueryParameters(parameters) {
|
||||
var isObjectOrArray = function(value) {
|
||||
return Object.prototype.toString.call(value) === '[object Object]' || Object.prototype.toString.call(value) === '[object Array]';
|
||||
};
|
||||
var encode = function(format) {
|
||||
for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
|
||||
args[_key - 1] = arguments[_key];
|
||||
}
|
||||
var i = 0;
|
||||
return format.replace(/%s/g, function() {
|
||||
return encodeURIComponent(args[i++]);
|
||||
});
|
||||
};
|
||||
return Object.keys(parameters).map(function(key) {
|
||||
return encode('%s=%s', key, isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]);
|
||||
}).join('&');
|
||||
}
|
||||
var _obj;
|
||||
/**
|
||||
* Creates a new instance of the InstantSearchManager which controls the widgets and
|
||||
* trigger the search when the widgets are updated.
|
||||
* @param {string} indexName - the main index name
|
||||
* @param {object} initialState - initial widget state
|
||||
* @param {object} SearchParameters - optional additional parameters to send to the algolia API
|
||||
* @param {number} stalledSearchDelay - time (in ms) after the search is stalled
|
||||
* @return {InstantSearchManager} a new instance of InstantSearchManager
|
||||
*/ export default function createInstantSearchManager(param) {
|
||||
var indexName = param.indexName, _initialState = param.initialState, initialState = _initialState === void 0 ? {
|
||||
} : _initialState, searchClient = param.searchClient, resultsState = param.resultsState, stalledSearchDelay = param.stalledSearchDelay;
|
||||
var createStore = function createStore(initialState) {
|
||||
var state = initialState;
|
||||
var listeners = [];
|
||||
return {
|
||||
getState: function() {
|
||||
return state;
|
||||
},
|
||||
setState: function(nextState) {
|
||||
state = nextState;
|
||||
listeners.forEach(function(listener) {
|
||||
return listener();
|
||||
});
|
||||
},
|
||||
subscribe: function(listener) {
|
||||
listeners.push(listener);
|
||||
return function unsubscribe() {
|
||||
listeners.splice(listeners.indexOf(listener), 1);
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
var skipSearch = function skipSearch() {
|
||||
skip = true;
|
||||
};
|
||||
var updateClient = function updateClient(client) {
|
||||
addAlgoliaAgents(client);
|
||||
helper.setClient(client);
|
||||
search();
|
||||
};
|
||||
var clearCache = function clearCache() {
|
||||
helper.clearCache();
|
||||
search();
|
||||
};
|
||||
var getMetadata = function getMetadata(state) {
|
||||
return widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getMetadata);
|
||||
}).map(function(widget) {
|
||||
return widget.getMetadata(state);
|
||||
});
|
||||
};
|
||||
var getSearchParameters = function getSearchParameters() {
|
||||
var sharedParameters = widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function(widget) {
|
||||
return !isMultiIndexContext(widget) && !isIndexWidget(widget);
|
||||
}).reduce(function(res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, initialSearchParameters);
|
||||
var mainParameters = widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function(widget) {
|
||||
var targetedIndexEqualMainIndex = isMultiIndexContext(widget) && isTargetedIndexEqualIndex(widget, indexName);
|
||||
var subIndexEqualMainIndex = isIndexWidget(widget) && isIndexWidgetEqualIndex(widget, indexName);
|
||||
return targetedIndexEqualMainIndex || subIndexEqualMainIndex;
|
||||
})// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst).reduce(function(res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, sharedParameters);
|
||||
var derivedIndices = widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.getSearchParameters);
|
||||
}).filter(function(widget) {
|
||||
var targetedIndexNotEqualMainIndex = isMultiIndexContext(widget) && !isTargetedIndexEqualIndex(widget, indexName);
|
||||
var subIndexNotEqualMainIndex = isIndexWidget(widget) && !isIndexWidgetEqualIndex(widget, indexName);
|
||||
return targetedIndexNotEqualMainIndex || subIndexNotEqualMainIndex;
|
||||
})// We have to sort the `Index` widgets first so the `index` parameter
|
||||
// is correctly set in the `reduce` function for the following widgets
|
||||
.sort(sortIndexWidgetsFirst).reduce(function(indices, widget) {
|
||||
var indexId = isMultiIndexContext(widget) ? widget.props.indexContextValue.targetedIndex : widget.props.indexId;
|
||||
var widgets = indices[indexId] || [];
|
||||
return swcHelpers.objectSpread({
|
||||
}, indices, swcHelpers.defineProperty({
|
||||
}, indexId, widgets.concat(widget)));
|
||||
}, {
|
||||
});
|
||||
var derivedParameters = Object.keys(derivedIndices).map(function(indexId) {
|
||||
return {
|
||||
parameters: derivedIndices[indexId].reduce(function(res, widget) {
|
||||
return widget.getSearchParameters(res);
|
||||
}, sharedParameters),
|
||||
indexId: indexId
|
||||
};
|
||||
});
|
||||
return {
|
||||
mainParameters: mainParameters,
|
||||
derivedParameters: derivedParameters
|
||||
};
|
||||
};
|
||||
var search = function search() {
|
||||
if (!skip) {
|
||||
var ref = getSearchParameters(helper.state), mainParameters = ref.mainParameters, derivedParameters = ref.derivedParameters;
|
||||
// We have to call `slice` because the method `detach` on the derived
|
||||
// helpers mutates the value `derivedHelpers`. The `forEach` loop does
|
||||
// not iterate on each value and we're not able to correctly clear the
|
||||
// previous derived helpers (memory leak + useless requests).
|
||||
helper.derivedHelpers.slice().forEach(function(derivedHelper) {
|
||||
// Since we detach the derived helpers on **every** new search they
|
||||
// won't receive intermediate results in case of a stalled search.
|
||||
// Only the last result is dispatched by the derived helper because
|
||||
// they are not detached yet:
|
||||
//
|
||||
// - a -> main helper receives results
|
||||
// - ap -> main helper receives results
|
||||
// - app -> main helper + derived helpers receive results
|
||||
//
|
||||
// The quick fix is to avoid to detach them on search but only once they
|
||||
// received the results. But it means that in case of a stalled search
|
||||
// all the derived helpers not detached yet register a new search inside
|
||||
// the helper. The number grows fast in case of a bad network and it's
|
||||
// not deterministic.
|
||||
derivedHelper.detach();
|
||||
});
|
||||
derivedParameters.forEach(function(param) {
|
||||
var indexId = param.indexId, parameters = param.parameters;
|
||||
var derivedHelper = helper.derive(function() {
|
||||
return parameters;
|
||||
});
|
||||
derivedHelper.on('result', handleSearchSuccess({
|
||||
indexId: indexId
|
||||
})).on('error', handleSearchError);
|
||||
});
|
||||
helper.setState(mainParameters);
|
||||
helper.search();
|
||||
}
|
||||
};
|
||||
var handleSearchSuccess = function handleSearchSuccess(param) {
|
||||
var indexId = param.indexId;
|
||||
return function(event) {
|
||||
var state = store.getState();
|
||||
var isDerivedHelpersEmpty = !helper.derivedHelpers.length;
|
||||
var results = state.results ? state.results : {
|
||||
};
|
||||
// Switching from mono index to multi index and vice versa must reset the
|
||||
// results to an empty object, otherwise we keep reference of stalled and
|
||||
// unused results.
|
||||
results = !isDerivedHelpersEmpty && results.getFacetByName ? {
|
||||
} : results;
|
||||
if (!isDerivedHelpersEmpty) {
|
||||
results = swcHelpers.objectSpread({
|
||||
}, results, swcHelpers.defineProperty({
|
||||
}, indexId, event.results));
|
||||
} else {
|
||||
results = event.results;
|
||||
}
|
||||
var currentState = store.getState();
|
||||
var nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
stalledSearchTimer = null;
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
var resultsFacetValues = currentState.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(currentState, ["resultsFacetValues"]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
results: results,
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
searching: false,
|
||||
error: null
|
||||
}));
|
||||
};
|
||||
};
|
||||
var handleSearchError = function handleSearchError(param) {
|
||||
var error = param.error;
|
||||
var currentState = store.getState();
|
||||
var nextIsSearchStalled = currentState.isSearchStalled;
|
||||
if (!helper.hasPendingRequests()) {
|
||||
clearTimeout(stalledSearchTimer);
|
||||
nextIsSearchStalled = false;
|
||||
}
|
||||
var resultsFacetValues = currentState.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(currentState, ["resultsFacetValues"]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
isSearchStalled: nextIsSearchStalled,
|
||||
error: error,
|
||||
searching: false
|
||||
}));
|
||||
};
|
||||
var handleNewSearch = function handleNewSearch() {
|
||||
if (!stalledSearchTimer) {
|
||||
stalledSearchTimer = setTimeout(function() {
|
||||
var _ref = store.getState(), resultsFacetValues = _ref.resultsFacetValues, partialState = swcHelpers.objectWithoutProperties(_ref, ["resultsFacetValues"]);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, partialState, {
|
||||
isSearchStalled: true
|
||||
}));
|
||||
}, stalledSearchDelay);
|
||||
}
|
||||
};
|
||||
var hydrateSearchClient = function hydrateSearchClient(client, results) {
|
||||
if (!results) {
|
||||
return;
|
||||
}
|
||||
// Disable cache hydration on:
|
||||
// - Algoliasearch API Client < v4 with cache disabled
|
||||
// - Third party clients (detected by the `addAlgoliaAgent` function missing)
|
||||
if ((!client.transporter || client._cacheHydrated) && (!client._useCache || typeof client.addAlgoliaAgent !== 'function')) {
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client >= v4
|
||||
// To hydrate the client we need to populate the cache with the data from
|
||||
// the server (done in `hydrateSearchClientWithMultiIndexRequest` or
|
||||
// `hydrateSearchClientWithSingleIndexRequest`). But since there is no way
|
||||
// for us to compute the key the same way as `algoliasearch-client` we need
|
||||
// to populate it on a custom key and override the `search` method to
|
||||
// search on it first.
|
||||
if (client.transporter && !client._cacheHydrated) {
|
||||
client._cacheHydrated = true;
|
||||
var baseMethod = client.search;
|
||||
client.search = function(requests) {
|
||||
for(var _len = arguments.length, methodArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
|
||||
methodArgs[_key - 1] = arguments[_key];
|
||||
}
|
||||
var requestsWithSerializedParams = requests.map(function(request) {
|
||||
return swcHelpers.objectSpread({
|
||||
}, request, {
|
||||
params: serializeQueryParameters(request.params)
|
||||
});
|
||||
});
|
||||
return client.transporter.responsesCache.get({
|
||||
method: 'search',
|
||||
args: [
|
||||
requestsWithSerializedParams
|
||||
].concat(swcHelpers.toConsumableArray(methodArgs))
|
||||
}, function() {
|
||||
return baseMethod.apply(void 0, [
|
||||
requests
|
||||
].concat(swcHelpers.toConsumableArray(methodArgs)));
|
||||
});
|
||||
};
|
||||
}
|
||||
if (Array.isArray(results.results)) {
|
||||
hydrateSearchClientWithMultiIndexRequest(client, results.results);
|
||||
return;
|
||||
}
|
||||
hydrateSearchClientWithSingleIndexRequest(client, results);
|
||||
};
|
||||
var hydrateSearchClientWithMultiIndexRequest = function hydrateSearchClientWithMultiIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set({
|
||||
method: 'search',
|
||||
args: [
|
||||
results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}));
|
||||
}, []),
|
||||
]
|
||||
}, {
|
||||
results: results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults);
|
||||
}, [])
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
var key = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}));
|
||||
}, [])
|
||||
}));
|
||||
client.cache = swcHelpers.objectSpread({
|
||||
}, client.cache, swcHelpers.defineProperty({
|
||||
}, key, JSON.stringify({
|
||||
results: results.reduce(function(acc, result) {
|
||||
return acc.concat(result.rawResults);
|
||||
}, [])
|
||||
})));
|
||||
};
|
||||
var hydrateSearchClientWithSingleIndexRequest = function hydrateSearchClientWithSingleIndexRequest(client, results) {
|
||||
// Algoliasearch API Client >= v4
|
||||
// Populate the cache with the data from the server
|
||||
if (client.transporter) {
|
||||
client.transporter.responsesCache.set({
|
||||
method: 'search',
|
||||
args: [
|
||||
results.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
}),
|
||||
]
|
||||
}, {
|
||||
results: results.rawResults
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Algoliasearch API Client < v4
|
||||
// Prior to client v4 we didn't have a proper API to hydrate the client
|
||||
// cache from the outside. The following code populates the cache with
|
||||
// a single-index result. You can find more information about the
|
||||
// computation of the key inside the client (see link below).
|
||||
// https://github.com/algolia/algoliasearch-client-javascript/blob/c27e89ff92b2a854ae6f40dc524bffe0f0cbc169/src/AlgoliaSearchCore.js#L232-L240
|
||||
var key = "/1/indexes/*/queries_body_".concat(JSON.stringify({
|
||||
requests: results.rawResults.map(function(request) {
|
||||
return {
|
||||
indexName: request.index,
|
||||
params: request.params
|
||||
};
|
||||
})
|
||||
}));
|
||||
client.cache = swcHelpers.objectSpread({
|
||||
}, client.cache, swcHelpers.defineProperty({
|
||||
}, key, JSON.stringify({
|
||||
results: results.rawResults
|
||||
})));
|
||||
};
|
||||
var hydrateResultsState = function hydrateResultsState(results) {
|
||||
if (!results) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(results.results)) {
|
||||
return results.results.reduce(function(acc, result) {
|
||||
return swcHelpers.objectSpread({
|
||||
}, acc, swcHelpers.defineProperty({
|
||||
}, result._internalIndexId, new algoliasearchHelper.SearchResults(new algoliasearchHelper.SearchParameters(result.state), result.rawResults)));
|
||||
}, {
|
||||
});
|
||||
}
|
||||
return new algoliasearchHelper.SearchResults(new algoliasearchHelper.SearchParameters(results.state), results.rawResults);
|
||||
};
|
||||
var onWidgetsUpdate = // Called whenever a widget has been rendered with new props.
|
||||
function onWidgetsUpdate() {
|
||||
var metadata = getMetadata(store.getState().widgets);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
metadata: metadata,
|
||||
searching: true
|
||||
}));
|
||||
// Since the `getSearchParameters` method of widgets also depends on props,
|
||||
// the result search parameters might have changed.
|
||||
search();
|
||||
};
|
||||
var transitionState = function transitionState(nextSearchState) {
|
||||
var searchState = store.getState().widgets;
|
||||
return widgetsManager.getWidgets().filter(function(widget) {
|
||||
return Boolean(widget.transitionState);
|
||||
}).reduce(function(res, widget) {
|
||||
return widget.transitionState(searchState, res);
|
||||
}, nextSearchState);
|
||||
};
|
||||
var onExternalStateUpdate = function onExternalStateUpdate(nextSearchState) {
|
||||
var metadata = getMetadata(nextSearchState);
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
widgets: nextSearchState,
|
||||
metadata: metadata,
|
||||
searching: true
|
||||
}));
|
||||
search();
|
||||
};
|
||||
var onSearchForFacetValues = function onSearchForFacetValues(param) {
|
||||
var facetName = param.facetName, query = param.query, _maxFacetHits = param.maxFacetHits, maxFacetHits = _maxFacetHits === void 0 ? 10 : _maxFacetHits;
|
||||
// The values 1, 100 are the min / max values that the engine accepts.
|
||||
// see: https://www.algolia.com/doc/api-reference/api-parameters/maxFacetHits
|
||||
var maxFacetHitsWithinRange = Math.max(1, Math.min(maxFacetHits, 100));
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
searchingForFacetValues: true
|
||||
}));
|
||||
helper.searchForFacetValues(facetName, query, maxFacetHitsWithinRange).then(function(content) {
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
error: null,
|
||||
searchingForFacetValues: false,
|
||||
resultsFacetValues: swcHelpers.objectSpread({
|
||||
}, store.getState().resultsFacetValues, (_obj = {
|
||||
}, swcHelpers.defineProperty(_obj, facetName, content.facetHits), swcHelpers.defineProperty(_obj, "query", query), _obj))
|
||||
}));
|
||||
}, function(error) {
|
||||
store.setState(swcHelpers.objectSpread({
|
||||
}, store.getState(), {
|
||||
searchingForFacetValues: false,
|
||||
error: error
|
||||
}));
|
||||
}).catch(function(error) {
|
||||
// Since setState is synchronous, any error that occurs in the render of a
|
||||
// component will be swallowed by this promise.
|
||||
// This is a trick to make the error show up correctly in the console.
|
||||
// See http://stackoverflow.com/a/30741722/969302
|
||||
setTimeout(function() {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
};
|
||||
var updateIndex = function updateIndex(newIndex) {
|
||||
initialSearchParameters = initialSearchParameters.setIndex(newIndex);
|
||||
// No need to trigger a new search here as the widgets will also update and trigger it if needed.
|
||||
};
|
||||
var getWidgetsIds = function getWidgetsIds() {
|
||||
return store.getState().metadata.reduce(function(res, meta) {
|
||||
return typeof meta.id !== 'undefined' ? res.concat(meta.id) : res;
|
||||
}, []);
|
||||
};
|
||||
var helper = algoliasearchHelper(searchClient, indexName, swcHelpers.objectSpread({
|
||||
}, HIGHLIGHT_TAGS));
|
||||
addAlgoliaAgents(searchClient);
|
||||
helper.on('search', handleNewSearch).on('result', handleSearchSuccess({
|
||||
indexId: indexName
|
||||
})).on('error', handleSearchError);
|
||||
var skip = false;
|
||||
var stalledSearchTimer = null;
|
||||
var initialSearchParameters = helper.state;
|
||||
var widgetsManager = createWidgetsManager(onWidgetsUpdate);
|
||||
hydrateSearchClient(searchClient, resultsState);
|
||||
var store = createStore({
|
||||
widgets: initialState,
|
||||
metadata: hydrateMetadata(resultsState),
|
||||
results: hydrateResultsState(resultsState),
|
||||
error: null,
|
||||
searching: false,
|
||||
isSearchStalled: true,
|
||||
searchingForFacetValues: false
|
||||
});
|
||||
return {
|
||||
store: store,
|
||||
widgetsManager: widgetsManager,
|
||||
getWidgetsIds: getWidgetsIds,
|
||||
getSearchParameters: getSearchParameters,
|
||||
onSearchForFacetValues: onSearchForFacetValues,
|
||||
onExternalStateUpdate: onExternalStateUpdate,
|
||||
transitionState: transitionState,
|
||||
updateClient: updateClient,
|
||||
updateIndex: updateIndex,
|
||||
clearCache: clearCache,
|
||||
skipSearch: skipSearch
|
||||
};
|
||||
};
|
||||
function hydrateMetadata(resultsState) {
|
||||
if (!resultsState) {
|
||||
return [];
|
||||
}
|
||||
// add a value noop, which gets replaced once the widgets are mounted
|
||||
return resultsState.metadata.map(function(datum) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, datum, {
|
||||
items: datum.items && datum.items.map(function(item) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, item, {
|
||||
items: item.items && item.items.map(function(nestedItem) {
|
||||
return swcHelpers.objectSpread({
|
||||
value: function() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
}, nestedItem);
|
||||
})
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user