commit 9d283dad991eb774a461f4286e8cfa490fa72148 Author: what Date: Wed Apr 15 15:19:04 2026 +0800 初始化发布包 v0.11.1 diff --git a/ff-request.js b/ff-request.js new file mode 100644 index 0000000..3c67015 --- /dev/null +++ b/ff-request.js @@ -0,0 +1,692 @@ +var ue = Object.defineProperty; +var ie = (r) => { + throw TypeError(r); +}; +var de = (r, e, t) => e in r ? ue(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t; +var g = (r, e, t) => de(r, typeof e != "symbol" ? e + "" : e, t), oe = (r, e, t) => e.has(r) || ie("Cannot " + t); +var i = (r, e, t) => (oe(r, e, "read from private field"), t ? t.call(r) : e.get(r)), w = (r, e, t) => e.has(r) ? ie("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(r) : e.set(r, t), C = (r, e, t, n) => (oe(r, e, "write to private field"), n ? n.call(r, t) : e.set(r, t), t); +function ge(r) { + return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r; +} +var he = {}; +(function(r) { + (function(e) { + e([], function() { + var t = -1, n = -2, s = -3, o = -4, h = -5, R = function(l, u) { + u = u || {}; + var f = u.verbose || !1; + f && console.log("Normalize the JSON Object"), l = typeof l == "string" ? this.JSON.parse(l) : l, f && console.log("Creating a empty dictionary"); + var d = { + strings: [], + integers: [], + floats: [] + }; + f && console.log("Creating the AST"); + var p = function S(a) { + f && console.log("Calling recursiveAstBuilder with " + this.JSON.stringify(a)); + var y = typeof a; + if (a === null) + return { + type: "null", + index: s + }; + if (typeof a > "u") + return { + type: "undefined", + index: h + }; + if (a instanceof Array) { + var x = ["@"]; + for (var b in a) + a.hasOwnProperty(b) && x.push(S(a[b])); + return x; + } + if (y === "object") { + var x = ["$"]; + for (var $ in a) + a.hasOwnProperty($) && (x.push(S($)), x.push(S(a[$]))); + return x; + } + if (a === "") + return { + type: "empty", + index: o + }; + if (y === "string") { + var O = H.call(d.strings, a); + return O == -1 && (d.strings.push(T(a)), O = d.strings.length - 1), { + type: "strings", + index: O + }; + } + if (y === "number" && a % 1 === 0) { + var O = H.call(d.integers, a); + return O == -1 && (d.integers.push(_(a)), O = d.integers.length - 1), { + type: "integers", + index: O + }; + } + if (y === "number") { + var O = H.call(d.floats, a); + return O == -1 && (d.floats.push(a), O = d.floats.length - 1), { + type: "floats", + index: O + }; + } + if (y === "boolean") + return { + type: "boolean", + index: a ? t : n + }; + throw new Error("Unexpected argument of type " + typeof a); + }(l), E = d.strings.length, B = d.integers.length; + d.floats.length, f && console.log("Parsing the dictionary"); + var N = d.strings.join("|"); + return N += "^" + d.integers.join("|"), N += "^" + d.floats.join("|"), f && console.log("Parsing the structure"), N += "^" + function S(a) { + if (f && console.log("Calling a recursiveParser with " + this.JSON.stringify(a)), a instanceof Array) { + var y = a.shift(); + for (var x in a) + a.hasOwnProperty(x) && (y += S(a[x]) + "|"); + return (y[y.length - 1] === "|" ? y.slice(0, -1) : y) + "]"; + } + var b = a.type, $ = a.index; + if (b === "strings") + return _($); + if (b === "integers") + return _(E + $); + if (b === "floats") + return _(E + B + $); + if (b === "boolean") + return a.index; + if (b === "null") + return s; + if (b === "undefined") + return h; + if (b === "empty") + return o; + throw new TypeError("The item is alien!"); + }(p), f && console.log("Ending parser"), u.debug ? { + dictionary: d, + ast: p, + packed: N + } : N; + }, c = function(l, u) { + u = u || {}; + var f = l.split("^"); + u.verbose && console.log("Building dictionary"); + var d = [], p = f[0]; + if (p !== "") { + p = p.split("|"), u.verbose && console.log("Parse the strings dictionary"); + for (var E = 0, B = p.length; E < B; E++) + d.push(M(p[E])); + } + if (p = f[1], p !== "") { + p = p.split("|"), u.verbose && console.log("Parse the integers dictionary"); + for (var E = 0, B = p.length; E < B; E++) + d.push(U(p[E])); + } + if (p = f[2], p !== "") { + p = p.split("|"), u.verbose && console.log("Parse the floats dictionary"); + for (var E = 0, B = p.length; E < B; E++) + d.push(parseFloat(p[E])); + } + p = null, u.verbose && console.log("Tokenizing the structure"); + for (var N = "", S = [], a = f[3].length, E = 0; E < a; E++) { + var y = f[3].charAt(E); + y === "|" || y === "$" || y === "@" || y === "]" ? (N && (S.push(U(N)), N = ""), y !== "|" && S.push(y)) : N += y; + } + var x = S.length, b = 0; + return u.verbose && console.log("Starting recursive parser"), function $() { + var O = S[b++]; + if (u.verbose && console.log("Reading collection type " + (O === "$" ? "object" : "Array")), O === "@") { + for (var v = []; b < x; b++) { + var A = S[b]; + if (u.verbose && console.log("Read " + A + " symbol"), A === "]") + return v; + if (A === "@" || A === "$") + v.push($()); + else + switch (A) { + case t: + v.push(!0); + break; + case n: + v.push(!1); + break; + case s: + v.push(null); + break; + case h: + v.push(void 0); + break; + case o: + v.push(""); + break; + default: + v.push(d[A]); + } + } + return u.verbose && console.log("Parsed " + this.JSON.stringify(v)), v; + } + if (O === "$") { + for (var v = {}; b < x; b++) { + var P = S[b]; + if (P === "]") + return v; + P === o ? P = "" : P = d[P]; + var A = S[++b]; + if (A === "@" || A === "$") + v[P] = $(); + else + switch (A) { + case t: + v[P] = !0; + break; + case n: + v[P] = !1; + break; + case s: + v[P] = null; + break; + case h: + v[P] = void 0; + break; + case o: + v[P] = ""; + break; + default: + v[P] = d[A]; + } + } + return u.verbose && console.log("Parsed " + this.JSON.stringify(v)), v; + } + throw new TypeError("Bad token " + O + " isn't a type"); + }(); + }, T = function(l) { + return typeof l != "string" ? l : l.replace(/[\+ \|\^\%]/g, function(u) { + return { + " ": "+", + "+": "%2B", + "|": "%7C", + "^": "%5E", + "%": "%25" + }[u]; + }); + }, M = function(l) { + return typeof l != "string" ? l : l.replace(/\+|%2B|%7C|%5E|%25/g, function(u) { + return { + "+": " ", + "%2B": "+", + "%7C": "|", + "%5E": "^", + "%25": "%" + }[u]; + }); + }, _ = function(l) { + return Number.prototype.toString.call(l, 36).toUpperCase(); + }, U = function(l) { + return parseInt(l, 36); + }, H = Array.prototype.indexOf || function(l, u) { + for (var f = u || 0, d = this.length; f < d; f++) + if (this[f] === l) + return f; + return -1; + }; + return { + JSON, + pack: R, + unpack: c + }; + }); + })(function(e, t) { + var n = t(); + for (var s in n) + r[s] = n[s]; + }); +})(he); +const ae = /* @__PURE__ */ ge(he); +var K, L, j, F, Q, W, q, X, Z; +class ne { + /** + * @param {number} code + * @param {string} message + * @param {unknown} data + * @param {string} url + * @param {string} res + */ + constructor(e, t, n, s, o) { + /** @type {number} */ + g(this, "code", 0); + /** @type {string} */ + g(this, "message", "操作成功"); + /** @type {unknown} */ + g(this, "data", null); + /** @type {string} */ + g(this, "url", ""); + /** @type {string} */ + g(this, "res", ""); + /** @type {HttpResponse} */ + w(this, K); + // 判断返回 Response 对象, 还是 Response 中的 data + /** @type {boolean} */ + w(this, L, !0); + // 判断是否已经给出错误提示 + /** @type {boolean} */ + w(this, j, !0); + w(this, F, { + /** @param {any} __ @param {string} key */ + get: (e, t) => i(this, Q).call(this, t), + /** @returns {string[]} */ + ownKeys: () => Object.keys(i(this, F).getPrototypeOf() || {}), + /** @returns {HttpResponse | unknown} */ + getPrototypeOf: () => i(this, L) ? this : this.data, + /** @returns {PropertyDescriptor} */ + getOwnPropertyDescriptor: () => ({ + configurable: !0, + enumerable: !0, + writable: !0, + value: i(this, F).getPrototypeOf() + }) + }); + /** + * @param {string} key + * @returns {unknown} + */ + w(this, Q, (e) => e === "$echoMsg" ? i(this, q) : e === "msg" ? i(this, W) : e === "then" || e === "resp" ? (C(this, j, !0), C(this, L, e === "resp"), i(this, X)) : e === "catch" ? i(this, Z) : e === "IS_ECHO_MSG" ? i(this, j) : Reflect.get(this, e)); + /** + * @param {(value: unknown) => unknown} [fn] + * @param {boolean} [isResp] + * @returns {Promise} + */ + w(this, W, (e = (n) => n, t = !1) => (i(this, q).call(this), C(this, L, t), Promise.resolve(e == null ? void 0 : e(i(this, F).getPrototypeOf())))); + w(this, q, () => { + i(this, j) && (C(this, j, !1), se.onMsg(this.code, this.message)); + }); + /** + * @param {(value: unknown) => unknown} [fn] + * @returns {Promise} + */ + w(this, X, (e) => [0, 1].includes(this.code) ? Promise.resolve(e == null ? void 0 : e(i(this, F).getPrototypeOf())) : Promise.reject(i(this, K))); + /** + * @param {(reason: HttpResponse) => unknown} fn + * @returns {Promise} + */ + w(this, Z, (e) => Promise.resolve(e(i(this, K)))); + return this.code = e, this.message = t, this.data = n, this.url = s, this.res = o, C(this, K, new Proxy(this, i(this, F))); + } +} +K = new WeakMap(), L = new WeakMap(), j = new WeakMap(), F = new WeakMap(), Q = new WeakMap(), W = new WeakMap(), q = new WeakMap(), X = new WeakMap(), Z = new WeakMap(); +const re = (r, e, t, n = "/", s = "") => new ne(r, e, t, n, s); +var fe = [ + "utf8", + "utf-8", + "unicode-1-1-utf-8" +]; +function pe(r) { + if (fe.indexOf(r) < 0 && typeof r < "u" && r != null) + throw new RangeError("Invalid encoding type. Only utf-8 is supported"); + this.encoding = "utf-8", this.encode = function(e) { + if (typeof e != "string") + throw new TypeError("passed argument must be of tye string"); + var t = unescape(encodeURIComponent(e)), n = new Uint8Array(t.length); + const s = t.split(""); + for (let o = 0; o < s.length; o++) + n[o] = s[o].charCodeAt(0); + return n; + }; +} +function ve(r) { + if (fe.indexOf(r) < 0 && typeof r < "u" && r != null) + throw new RangeError("Invalid encoding type. Only utf-8 is supported"); + this.encoding = "utf-8", this.decode = function(e, t) { + if (typeof e > "u") + return ""; + var n = typeof t < "u" && n in t ? t.stream : !1; + if (typeof n != "boolean") + throw new TypeError("stream option must be boolean"); + if (ArrayBuffer.isView(e)) { + var s = new Uint8Array(e.buffer, e.byteOffset, e.byteLength), o = new Array(s.length); + for (let h = 0; h < s.length; h++) + o[h] = String.fromCharCode(s[h]); + return decodeURIComponent(escape(o.join(""))); + } else + throw new TypeError("passed argument must be an array buffer view"); + }; +} +var le = { + TextEncoder: pe, + TextDecoder: ve +}; +const we = new le.TextEncoder("utf8"), ye = new le.TextDecoder("utf8"); +function be(r) { + let e = 5381; + for (let t = 0; t < r.length; t++) + e = e * 33 ^ r.charCodeAt(t); + return (e >>> 0).toString(16); +} +function Ee(r, e) { + return r.replace(new RegExp(`^${e}+|${e}+$`, "g"), ""); +} +function Oe(r) { + return we.encode(r || ""); +} +function Ce(r) { + return ye.decode(new DataView(r), {}); +} +const Te = 62, Y = 30, ce = 31, Se = 63; +class xe { + /** + * @param {string} alphabet 62 位编码字母表 + */ + constructor(e) { + /** @type {string[]} */ + g(this, "encodeTable", []); + /** @type {Uint8Array} */ + g(this, "decodeMap", new Uint8Array(256).fill(255)); + if (e.length !== Te) + throw new Error("Encoding alphabet must be 62 characters long"); + if (e.includes(` +`) || e.includes("\r")) + throw new Error("Encoding alphabet contains newline character"); + this.encodeTable = e.split(""), this.decodeMap = new Uint8Array(256).fill(255); + for (let t = 0; t < e.length; t++) + this.decodeMap[e.charCodeAt(t)] = t; + } + /** + * 将字符串编码为 Base62 字符串 + * @param {string} src + * @returns {string} + */ + encode(e) { + if (!e || e.length === 0) return ""; + const t = new Pe(this).encodeV2(e); + return String.fromCharCode(...t); + } + /** + * 将 Base62 字符串解码为原始字符串 + * @param {string} src + * @returns {string} + */ + decode(e) { + if (!e || e.length === 0) return ""; + const t = new _e(this).decode(e); + return new TextDecoder().decode(t); + } +} +var z; +class Pe { + /** + * @param {Base62} b62 + */ + constructor(e) { + /** @type {Base62} */ + w(this, z); + /** @type {Uint8Array} */ + g(this, "src", new Uint8Array()); + /** @type {number} */ + g(this, "pos", 0); + C(this, z, e); + } + /** @returns {number} */ + get6bits() { + let e = this.pos & 7, t = this.pos >> 3; + e === 0 && (t -= 1, e = 8); + let n = this.src[t] >> 8 - e; + return e < 6 && t > 0 && (n |= this.src[t - 1] << e), n & Se; + } + /** + * @param {string} src + * @returns {number[]} + */ + encodeV2(e) { + this.src = Oe(e), this.pos = this.src.length * 8; + const t = []; + for (; this.pos > 0; ) { + let n = 6, s = this.get6bits(); + (s & Y) === Y && ((this.pos > 6 || s > ce) && (n = 5), s &= ce), t.push(i(this, z).encodeTable[s].charCodeAt(0)), this.pos -= n; + } + return t; + } +} +z = new WeakMap(); +var k; +class _e { + /** + * @param {Base62} b62 + */ + constructor(e) { + /** @type {Base62} */ + w(this, k); + C(this, k, e); + } + /** + * @param {string} src + * @returns {Uint8Array} + */ + decode(e) { + const t = new Uint8Array(Math.ceil(e.length * 6 / 8) + 1); + let n = t.length, s = 0, o = 0; + for (let h = 0; h < e.length; h++) { + const R = e[h].charCodeAt(0), c = i(this, k).decodeMap[R]; + if (c === 255) + throw new Error(`CorruptInputError at index ${h}`); + h === e.length - 1 ? (o |= c << s, s += Math.ceil(Math.log2(c + 1))) : (c & Y) === Y ? (o |= c << s, s += 5) : (o |= c << s, s += 6), s >= 8 && (n--, t[n] = o & 255, s %= 8, o >>= 8); + } + return s > 0 && (n--, t[n] = o & 255), t.slice(n); + } +} +k = new WeakMap(); +Promise.withResolvers || (Promise.withResolvers = /** @type {typeof Promise.withResolvers} */ +function() { + let r, e; + return { promise: new Promise((n, s) => { + r = n, e = s; + }), resolve: r, reject: e }; +}); +var G, D, ee, m, I, J, te, V; +class se { + /** + * @param {string} [appKey] + * @param {string} [appSecret] + * @param {RequestFn} [reqFn] + */ + constructor(e, t, n) { + /** @type {RequestFn | undefined} */ + w(this, G); + /** @type {Base62 | undefined} */ + w(this, D); + /** @type {string | undefined} */ + w(this, ee); + w(this, m, { + /** @type {Map} */ + "#": /* @__PURE__ */ new Map(), + /** @type {Map} */ + $: /* @__PURE__ */ new Map() + }); + /** @type {Map>} */ + w(this, I, /* @__PURE__ */ new Map()); + /** @type {Set<[string, '#' | '$', RequestOptions & { method: string }, boolean]>} */ + w(this, J, /* @__PURE__ */ new Set()); + /** + * 初始化请求实例 + * @param {string} [appKey] + * @param {string} [appSecret] + * @param {RequestFn} [reqFn] + */ + g(this, "init", (e, t, n) => { + e && C(this, ee, e), n && C(this, G, n), t && C(this, D, new xe(t)), i(this, te).call(this); + }); + w(this, te, () => { + !i(this, J).size || !i(this, G) || (i(this, J).forEach((e) => i(this, V).call(this, ...e)), i(this, J).clear()); + }); + /** + * @param {string} hash + * @param {'#' | '$'} flag + * @param {RequestOptions & { method: string }} params + * @param {boolean} [isCacheRequest] + */ + w(this, V, (e, t, n, s = !1) => { + if (!i(this, G)) + i(this, J).add([e, t, n, s]); + else { + const { url: o, method: h, ...R } = n || {}; + i(this, G).call(this, { url: o, method: h, ...R }).then((c) => { + if (![0, 1].includes(c.code)) + throw re(c.code, c.msg, c.data, o, c == null ? void 0 : c.res); + return [c.code, c.msg, c.data, o, (c == null ? void 0 : c.res) ?? ""]; + }).then((c) => { + const T = ( + /** @type {CacheEntry} */ + c + ); + return (t == "#" || h == "GET") && i(this, m)[t].set(e, T), t != "#" && h == "GET" && !s && setTimeout(() => { + i(this, m)[t].delete(e); + }, 300), T; + }).then((c) => { + var T; + return (T = i(this, I).get(e)) == null ? void 0 : T.forEach((M, _, U) => { + M && M[0](c), delete U[_]; + }); + }).catch((c) => { + var T; + i(this, m)[t].delete(e), (T = i(this, I).get(e)) == null || T.forEach((M, _, U) => { + M && M[1](c instanceof ne ? c : re(-1, c, null, o)), delete U[_]; + }); + }).finally(() => i(this, I).delete(e)); + } + }); + /** + * 发起请求,支持缓存与并发合并 + * @param {RequestOptions} options + * @param {boolean} [isCacheRequest] + * @returns {any} 返回 Proxy 包裹的 Promise,支持链式调用 .then / .catch / .msg / .resp + */ + g(this, "request", ({ url: e = "/", method: t = "GET", ...n }, s = !1) => { + var _, U; + e = Ee(e, "/"); + const o = ( + /** @type {HttpMethod} */ + t.toUpperCase() + ), h = be(JSON.stringify([e, o, n])), R = ( + /** @type {'#' | '$'} */ + (_ = e == null ? void 0 : e.includes) != null && _.call(e, "/_/") ? "#" : "$" + ), { promise: c, resolve: T, reject: M } = Promise.withResolvers(); + return i(this, m)[R].has(h) ? (console.log("cache", e), T(i(this, m)[R].get(h))) : i(this, I).has(h) ? (U = i(this, I).get(h)) == null || U.push([T, M]) : (i(this, I).set(h, [[T, M]]), i(this, V).call(this, h, R, { url: e, method: o, ...n }, s)), new Proxy(c, { + get: (H, l) => (...u) => H.then((f) => ( + /** @type {any} */ + re(.../** @type {[number, string, unknown, string, string]} */ + /** @type {unknown} */ + f)[l](...u) + )).catch((f) => { + if (!(f instanceof ne)) throw f; + return typeof /** @type {any} */ + f[l] == "function" ? ( + /** @type {any} */ + f[l](...u) + ) : ( + /** @type {any} */ + f[l] + ); + }) + }); + }); + /** + * GET 请求 + * @param {string} url + * @param {Record} [params] + */ + g(this, "get", (e, t = {}) => this.request({ url: e, method: "GET", params: t })); + /** + * POST 请求 + * @param {string} url + * @param {unknown} [data] + * @param {Record} [params] + */ + g(this, "post", (e, t = {}, n = {}) => this.request({ url: e, method: "POST", data: t, params: n })); + /** + * PUT 请求 + * @param {string} url + * @param {unknown} [data] + * @param {Record} [params] + */ + g(this, "put", (e, t = {}, n = {}) => this.request({ url: e, method: "PUT", data: t, params: n })); + /** + * DELETE 请求 + * @param {string} url + * @param {unknown} [data] + * @param {Record} [params] + */ + g(this, "del", (e, t = {}, n = {}) => this.request({ url: e, method: "DELETE", data: t, params: n })); + /** + * 下载(待实现) + * @param {string} url + * @param {Record} [params] + */ + g(this, "download", (e, t) => { + }); + /** + * 永久缓存 GET 请求 + * @param {string} url + * @param {Record} [params] + */ + g(this, "cache", (e, t = {}) => this.request({ url: e, method: "GET", params: t }, !0)); + /** + * 通过 Base62 编码参数请求列表接口 + * @param {string} code + * @param {Record} [base62param] + */ + g(this, "list", (e, t = {}) => this.get(`/api/${e}/${this.encode(t)}`)); + g(this, "getAppInfo", () => { + }); + /** + * 清除缓存 + * @param {boolean} [isSystem] 是否同时清除系统缓存(`/_/` 路由) + */ + g(this, "refreshCache", (e = !1) => { + e && i(this, m)["#"].clear(), i(this, m).$.clear(); + }); + /** + * 解码 Base62 字符串为 JSON 对象 + * @param {string} [str] + * @param {object} [defaultValue] + * @returns {unknown} + */ + g(this, "decode", (e = "", t = {}) => { + if (e === void 0 || e === "" || e === null) + return t; + try { + if (!i(this, D)) throw new Error("未初始化 appSecret,请先通过 init 设置 appSecret"); + const n = i(this, D).decode(e); + return ae.unpack(n); + } catch { + return console.warn("core.decode", e), t; + } + }); + /** + * 将 JSON 对象编码为 Base62 字符串 + * @param {Record} [json] + * @returns {string} + */ + g(this, "encode", (e = {}) => { + if (!i(this, D)) throw new Error("未初始化 appSecret,请先通过 init 设置 appSecret"); + const t = JSON.stringify(e, (n, s) => s === void 0 ? null : s); + return i(this, D).encode(ae.pack(t)); + }); + this.init(e, t, n); + } +} +G = new WeakMap(), D = new WeakMap(), ee = new WeakMap(), m = new WeakMap(), I = new WeakMap(), J = new WeakMap(), te = new WeakMap(), V = new WeakMap(); +se.onUnhandledRejection = (r) => { + var e, t, n, s, o, h; + r != null && r.IS_ECHO_MSG ? ((e = r == null ? void 0 : r.$echoMsg) == null || e.call(r), (t = r == null ? void 0 : r.preventDefault) == null || t.call(r)) : (n = r.reason) != null && n.IS_ECHO_MSG && ((o = (s = r.reason) == null ? void 0 : s.$echoMsg) == null || o.call(s), (h = r == null ? void 0 : r.preventDefault) == null || h.call(r)); +}; +se.onMsg = (r, e) => [0, 1].includes(r) ? console.log(e) : console.warn(e); +export { + ne as HttpResponse, + re as NewHttpResponse, + se as default, + be as signature, + Oe as str2uint8array, + Ee as trim, + Ce as uint8array2str +}; diff --git a/ff-request.umd.cjs b/ff-request.umd.cjs new file mode 100644 index 0000000..544f8f7 --- /dev/null +++ b/ff-request.umd.cjs @@ -0,0 +1,2 @@ +(function(o,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(o=typeof globalThis<"u"?globalThis:o||self,h(o["ff-request"]={}))})(this,function(o){"use strict";var Ae=Object.defineProperty;var pe=o=>{throw TypeError(o)};var Ce=(o,h,O)=>h in o?Ae(o,h,{enumerable:!0,configurable:!0,writable:!0,value:O}):o[h]=O;var v=(o,h,O)=>Ce(o,typeof h!="symbol"?h+"":h,O),ve=(o,h,O)=>h.has(o)||pe("Cannot "+O);var i=(o,h,O)=>(ve(o,h,"read from private field"),O?O.call(o):h.get(o)),b=(o,h,O)=>h.has(o)?pe("Cannot add the same private member more than once"):h instanceof WeakSet?h.add(o):h.set(o,O),m=(o,h,O,k)=>(ve(o,h,"write to private field"),k?k.call(o,O):h.set(o,O),O);var q,z,J,B,ne,se,V,ie,oe,Y,Q,H,G,ae,R,F,K,ce,W;function h(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}var O={};(function(r){(function(e){e([],function(){var t=-1,n=-2,s=-3,a=-4,f=-5,j=function(d,g){g=g||{};var l=g.verbose||!1;l&&console.log("Normalize the JSON Object"),d=typeof d=="string"?this.JSON.parse(d):d,l&&console.log("Creating a empty dictionary");var p={strings:[],integers:[],floats:[]};l&&console.log("Creating the AST");var w=function _(c){l&&console.log("Calling recursiveAstBuilder with "+this.JSON.stringify(c));var E=typeof c;if(c===null)return{type:"null",index:s};if(typeof c>"u")return{type:"undefined",index:f};if(c instanceof Array){var A=["@"];for(var T in c)c.hasOwnProperty(T)&&A.push(_(c[T]));return A}if(E==="object"){var A=["$"];for(var I in c)c.hasOwnProperty(I)&&(A.push(_(I)),A.push(_(c[I])));return A}if(c==="")return{type:"empty",index:a};if(E==="string"){var P=X.call(p.strings,c);return P==-1&&(p.strings.push(x(c)),P=p.strings.length-1),{type:"strings",index:P}}if(E==="number"&&c%1===0){var P=X.call(p.integers,c);return P==-1&&(p.integers.push(M(c)),P=p.integers.length-1),{type:"integers",index:P}}if(E==="number"){var P=X.call(p.floats,c);return P==-1&&(p.floats.push(c),P=p.floats.length-1),{type:"floats",index:P}}if(E==="boolean")return{type:"boolean",index:c?t:n};throw new Error("Unexpected argument of type "+typeof c)}(d),S=p.strings.length,L=p.integers.length;p.floats.length,l&&console.log("Parsing the dictionary");var U=p.strings.join("|");return U+="^"+p.integers.join("|"),U+="^"+p.floats.join("|"),l&&console.log("Parsing the structure"),U+="^"+function _(c){if(l&&console.log("Calling a recursiveParser with "+this.JSON.stringify(c)),c instanceof Array){var E=c.shift();for(var A in c)c.hasOwnProperty(A)&&(E+=_(c[A])+"|");return(E[E.length-1]==="|"?E.slice(0,-1):E)+"]"}var T=c.type,I=c.index;if(T==="strings")return M(I);if(T==="integers")return M(S+I);if(T==="floats")return M(S+L+I);if(T==="boolean")return c.index;if(T==="null")return s;if(T==="undefined")return f;if(T==="empty")return a;throw new TypeError("The item is alien!")}(w),l&&console.log("Ending parser"),g.debug?{dictionary:p,ast:w,packed:U}:U},u=function(d,g){g=g||{};var l=d.split("^");g.verbose&&console.log("Building dictionary");var p=[],w=l[0];if(w!==""){w=w.split("|"),g.verbose&&console.log("Parse the strings dictionary");for(var S=0,L=w.length;Si(this,ne).call(this,t),ownKeys:()=>Object.keys(i(this,B).getPrototypeOf()||{}),getPrototypeOf:()=>i(this,z)?this:this.data,getOwnPropertyDescriptor:()=>({configurable:!0,enumerable:!0,writable:!0,value:i(this,B).getPrototypeOf()})});b(this,ne,e=>e==="$echoMsg"?i(this,V):e==="msg"?i(this,se):e==="then"||e==="resp"?(m(this,J,!0),m(this,z,e==="resp"),i(this,ie)):e==="catch"?i(this,oe):e==="IS_ECHO_MSG"?i(this,J):Reflect.get(this,e));b(this,se,(e=n=>n,t=!1)=>(i(this,V).call(this),m(this,z,t),Promise.resolve(e==null?void 0:e(i(this,B).getPrototypeOf()))));b(this,V,()=>{i(this,J)&&(m(this,J,!1),re.onMsg(this.code,this.message))});b(this,ie,e=>[0,1].includes(this.code)?Promise.resolve(e==null?void 0:e(i(this,B).getPrototypeOf())):Promise.reject(i(this,q)));b(this,oe,e=>Promise.resolve(e(i(this,q))));return this.code=e,this.message=t,this.data=n,this.url=s,this.res=a,m(this,q,new Proxy(this,i(this,B)))}}q=new WeakMap,z=new WeakMap,J=new WeakMap,B=new WeakMap,ne=new WeakMap,se=new WeakMap,V=new WeakMap,ie=new WeakMap,oe=new WeakMap;const ee=(r,e,t,n="/",s="")=>new Z(r,e,t,n,s);var ue=["utf8","utf-8","unicode-1-1-utf-8"];function we(r){if(ue.indexOf(r)<0&&typeof r<"u"&&r!=null)throw new RangeError("Invalid encoding type. Only utf-8 is supported");this.encoding="utf-8",this.encode=function(e){if(typeof e!="string")throw new TypeError("passed argument must be of tye string");var t=unescape(encodeURIComponent(e)),n=new Uint8Array(t.length);const s=t.split("");for(let a=0;a"u")return"";var n=typeof t<"u"&&n in t?t.stream:!1;if(typeof n!="boolean")throw new TypeError("stream option must be boolean");if(ArrayBuffer.isView(e)){var s=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),a=new Array(s.length);for(let f=0;f>>0).toString(16)}function he(r,e){return r.replace(new RegExp(`^${e}+|${e}+$`,"g"),"")}function de(r){return be.encode(r||"")}function Te(r){return Ee.decode(new DataView(r),{})}const Oe=62,te=30,ge=31,Se=63;class Pe{constructor(e){v(this,"encodeTable",[]);v(this,"decodeMap",new Uint8Array(256).fill(255));if(e.length!==Oe)throw new Error("Encoding alphabet must be 62 characters long");if(e.includes(` +`)||e.includes("\r"))throw new Error("Encoding alphabet contains newline character");this.encodeTable=e.split(""),this.decodeMap=new Uint8Array(256).fill(255);for(let t=0;t>3;e===0&&(t-=1,e=8);let n=this.src[t]>>8-e;return e<6&&t>0&&(n|=this.src[t-1]<0;){let n=6,s=this.get6bits();(s&te)===te&&((this.pos>6||s>ge)&&(n=5),s&=ge),t.push(i(this,Y).encodeTable[s].charCodeAt(0)),this.pos-=n}return t}}Y=new WeakMap;class _e{constructor(e){b(this,Q);m(this,Q,e)}decode(e){const t=new Uint8Array(Math.ceil(e.length*6/8)+1);let n=t.length,s=0,a=0;for(let f=0;f=8&&(n--,t[n]=a&255,s%=8,a>>=8)}return s>0&&(n--,t[n]=a&255),t.slice(n)}}Q=new WeakMap,Promise.withResolvers||(Promise.withResolvers=function(){let r,e;return{promise:new Promise((n,s)=>{r=n,e=s}),resolve:r,reject:e}});class re{constructor(e,t,n){b(this,H);b(this,G);b(this,ae);b(this,R,{"#":new Map,$:new Map});b(this,F,new Map);b(this,K,new Set);v(this,"init",(e,t,n)=>{e&&m(this,ae,e),n&&m(this,H,n),t&&m(this,G,new Pe(t)),i(this,ce).call(this)});b(this,ce,()=>{!i(this,K).size||!i(this,H)||(i(this,K).forEach(e=>i(this,W).call(this,...e)),i(this,K).clear())});b(this,W,(e,t,n,s=!1)=>{if(!i(this,H))i(this,K).add([e,t,n,s]);else{const{url:a,method:f,...j}=n||{};i(this,H).call(this,{url:a,method:f,...j}).then(u=>{if(![0,1].includes(u.code))throw ee(u.code,u.msg,u.data,a,u==null?void 0:u.res);return[u.code,u.msg,u.data,a,(u==null?void 0:u.res)??""]}).then(u=>{const x=u;return(t=="#"||f=="GET")&&i(this,R)[t].set(e,x),t!="#"&&f=="GET"&&!s&&setTimeout(()=>{i(this,R)[t].delete(e)},300),x}).then(u=>{var x;return(x=i(this,F).get(e))==null?void 0:x.forEach(($,M,D)=>{$&&$[0](u),delete D[M]})}).catch(u=>{var x;i(this,R)[t].delete(e),(x=i(this,F).get(e))==null||x.forEach(($,M,D)=>{$&&$[1](u instanceof Z?u:ee(-1,u,null,a)),delete D[M]})}).finally(()=>i(this,F).delete(e))}});v(this,"request",({url:e="/",method:t="GET",...n},s=!1)=>{var M,D;e=he(e,"/");const a=t.toUpperCase(),f=le(JSON.stringify([e,a,n])),j=(M=e==null?void 0:e.includes)!=null&&M.call(e,"/_/")?"#":"$",{promise:u,resolve:x,reject:$}=Promise.withResolvers();return i(this,R)[j].has(f)?(console.log("cache",e),x(i(this,R)[j].get(f))):i(this,F).has(f)?(D=i(this,F).get(f))==null||D.push([x,$]):(i(this,F).set(f,[[x,$]]),i(this,W).call(this,f,j,{url:e,method:a,...n},s)),new Proxy(u,{get:(X,d)=>(...g)=>X.then(l=>ee(...l)[d](...g)).catch(l=>{if(!(l instanceof Z))throw l;return typeof l[d]=="function"?l[d](...g):l[d]})})});v(this,"get",(e,t={})=>this.request({url:e,method:"GET",params:t}));v(this,"post",(e,t={},n={})=>this.request({url:e,method:"POST",data:t,params:n}));v(this,"put",(e,t={},n={})=>this.request({url:e,method:"PUT",data:t,params:n}));v(this,"del",(e,t={},n={})=>this.request({url:e,method:"DELETE",data:t,params:n}));v(this,"download",(e,t)=>{});v(this,"cache",(e,t={})=>this.request({url:e,method:"GET",params:t},!0));v(this,"list",(e,t={})=>this.get(`/api/${e}/${this.encode(t)}`));v(this,"getAppInfo",()=>{});v(this,"refreshCache",(e=!1)=>{e&&i(this,R)["#"].clear(),i(this,R).$.clear()});v(this,"decode",(e="",t={})=>{if(e===void 0||e===""||e===null)return t;try{if(!i(this,G))throw new Error("未初始化 appSecret,请先通过 init 设置 appSecret");const n=i(this,G).decode(e);return k.unpack(n)}catch{return console.warn("core.decode",e),t}});v(this,"encode",(e={})=>{if(!i(this,G))throw new Error("未初始化 appSecret,请先通过 init 设置 appSecret");const t=JSON.stringify(e,(n,s)=>s===void 0?null:s);return i(this,G).encode(k.pack(t))});this.init(e,t,n)}}H=new WeakMap,G=new WeakMap,ae=new WeakMap,R=new WeakMap,F=new WeakMap,K=new WeakMap,ce=new WeakMap,W=new WeakMap,re.onUnhandledRejection=r=>{var e,t,n,s,a,f;r!=null&&r.IS_ECHO_MSG?((e=r==null?void 0:r.$echoMsg)==null||e.call(r),(t=r==null?void 0:r.preventDefault)==null||t.call(r)):(n=r.reason)!=null&&n.IS_ECHO_MSG&&((a=(s=r.reason)==null?void 0:s.$echoMsg)==null||a.call(s),(f=r==null?void 0:r.preventDefault)==null||f.call(r))},re.onMsg=(r,e)=>[0,1].includes(r)?console.log(e):console.warn(e),o.HttpResponse=Z,o.NewHttpResponse=ee,o.default=re,o.signature=le,o.str2uint8array=de,o.trim=he,o.uint8array2str=Te,Object.defineProperties(o,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..bdb014e --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "ff-request", + "version": "0.11.1", + "type": "module", + "main": "./ff-request.umd.cjs", + "module": "./ff-request.js", + "types": "./types/index.d.ts", + "exports": { + ".": { + "types": "./types/index.d.ts", + "import": "./ff-request.js", + "require": "./ff-request.umd.cjs" + } + }, + "dependencies": { + "jsonpack": "^1.1.5", + "text-encoder": "^0.0.4" + } +} \ No newline at end of file diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..c883540 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,202 @@ +declare type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; + +/** + * @typedef {'GET' | 'POST' | 'PUT' | 'DELETE'} HttpMethod + */ +/** + * @typedef {Object} RequestOptions@typedef {Object} RequestOptions + * @property {string} [url] + * @property {HttpMethod} [method] + * @property {Record} [params] + * @property {unknown} [data] + */ +/** + * 底层请求函数类型(兼容 axios 等) + * @typedef {(config: RequestOptions & Record) => Promise<{ code: number, msg: string, data: unknown, res?: string }>} RequestFn + */ +/** + * 缓存条目:[code, msg, data, url, res] + * @typedef {[number, string, unknown, string, string]} CacheEntry + */ +declare class HttpRequest { + /** + * @param {string} [appKey] + * @param {string} [appSecret] + * @param {RequestFn} [reqFn] + */ + constructor(appKey?: string, appSecret?: string, reqFn?: RequestFn); + /** + * 初始化请求实例 + * @param {string} [appKey] + * @param {string} [appSecret] + * @param {RequestFn} [reqFn] + */ + init: (appKey?: string, appSecret?: string, reqFn?: RequestFn) => void; + /** + * 发起请求,支持缓存与并发合并 + * @param {RequestOptions} options + * @param {boolean} [isCacheRequest] + * @returns {any} 返回 Proxy 包裹的 Promise,支持链式调用 .then / .catch / .msg / .resp + */ + request: ({ url, method, ...params }: RequestOptions, isCacheRequest?: boolean) => any; + /** + * GET 请求 + * @param {string} url + * @param {Record} [params] + */ + get: (url: string, params?: Record) => any; + /** + * POST 请求 + * @param {string} url + * @param {unknown} [data] + * @param {Record} [params] + */ + post: (url: string, data?: unknown, params?: Record) => any; + /** + * PUT 请求 + * @param {string} url + * @param {unknown} [data] + * @param {Record} [params] + */ + put: (url: string, data?: unknown, params?: Record) => any; + /** + * DELETE 请求 + * @param {string} url + * @param {unknown} [data] + * @param {Record} [params] + */ + del: (url: string, data?: unknown, params?: Record) => any; + /** + * 下载(待实现) + * @param {string} url + * @param {Record} [params] + */ + download: (url: string, params?: Record) => void; + /** + * 永久缓存 GET 请求 + * @param {string} url + * @param {Record} [params] + */ + cache: (url: string, params?: Record) => any; + /** + * 通过 Base62 编码参数请求列表接口 + * @param {string} code + * @param {Record} [base62param] + */ + list: (code: string, base62param?: Record) => any; + getAppInfo: () => void; + /** + * 清除缓存 + * @param {boolean} [isSystem] 是否同时清除系统缓存(`/_/` 路由) + */ + refreshCache: (isSystem?: boolean) => void; + /** + * 解码 Base62 字符串为 JSON 对象 + * @param {string} [str] + * @param {object} [defaultValue] + * @returns {unknown} + */ + decode: (str?: string, defaultValue?: object) => unknown; + /** + * 将 JSON 对象编码为 Base62 字符串 + * @param {Record} [json] + * @returns {string} + */ + encode: (json?: Record) => string; + #private; +} + +declare namespace HttpRequest { + /** + * 全局未处理 rejection 处理器,适配浏览器和 Node 环境 + * @param {any} e + */ + function onUnhandledRejection(e: any): void; + /** + * 全局消息回调,默认打印到控制台 + * @param {number} code + * @param {string} msg + */ + function onMsg(code: number, msg: string): void; +} +export default HttpRequest; + +/** + * @typedef {Object} HttpResponseData@typedef {Object} HttpResponseData + * @property {number} code + * @property {string} message + * @property {unknown} data + * @property {string} url + * @property {string} res + */ +export declare class HttpResponse { + /** + * @param {number} code + * @param {string} message + * @param {unknown} data + * @param {string} url + * @param {string} res + */ + constructor(code: number, message: string, data: unknown, url: string, res: string); + /** @type {number} */ + code: number; + /** @type {string} */ + message: string; + /** @type {unknown} */ + data: unknown; + /** @type {string} */ + url: string; + /** @type {string} */ + res: string; + #private; +} + +export declare function NewHttpResponse(code: number, message: string, data: unknown, url?: string, res?: string): HttpResponse; + +/** + * 底层请求函数类型(兼容 axios 等) + */ +declare type RequestFn = (config: RequestOptions & Record) => Promise<{ + code: number; + msg: string; + data: unknown; + res?: string; +}>; + +declare type RequestOptions = { + url?: string | undefined; + method?: HttpMethod | undefined; + params?: Record | undefined; + data?: unknown; +}; + +/** + * DJB2 算法 —— 将字符串散列为十六进制字符串 + * @param {string} input + * @returns {string} + */ +export declare function signature(input: string): string; + +/** + * 将字符串编码为 Uint8Array + * @param {string} str + * @returns {Uint8Array} + */ +export declare function str2uint8array(str: string): Uint8Array; + +/** + * 去除字符串首尾指定字符 + * @param {string} str + * @param {string} char + * @returns {string} + */ +export declare function trim(str: string, char: string): string; + +/** + * 将 ArrayBuffer 解码为字符串 + * @param {ArrayBuffer} buffer + * @returns {string} + */ +export declare function uint8array2str(buffer: ArrayBuffer): string; + +export { }