UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

314 lines (309 loc) 9.97 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib_es6 = require('../tslib.es6-01322ba9.js'); var sse_helper = require('./helper.js'); /** * 解析 H5 环境下的 SSE 数据流 * @param {Object} params - 参数对象 * @param {Function} params.success - 成功回调函数 * @param {Function} params.fail - 失败回调函数 * @param {Function} params.complete - 完成回调函数 * @param {Response} params.response - 响应对象 * @returns {Promise} 返回一个 Promise,处理 SSE 数据流 */ var parseSSEChunkInH5 = function parseSSEChunkInH5(_a) { var success = _a.success, fail = _a.fail, complete = _a.complete, response = _a.response; return tslib_es6.__awaiter(void 0, void 0, void 0, function () { function processText(_a) { var done = _a.done, value = _a.value; return tslib_es6.__awaiter(this, void 0, void 0, function () { var chunk, buffers, i, line, response_1; return tslib_es6.__generator(this, function (_b) { if (done) { complete === null || complete === void 0 ? void 0 : complete(true); return [2 /*return*/, Promise.resolve()]; } chunk = decoder.decode(value); buffers = chunk.toString().split(/\r?\n/); i = 0; while (i < buffers.length) { line = buffers[i]; response_1 = line.slice(5); success === null || success === void 0 ? void 0 : success(response_1, line); buffers.splice(i, 1); } return [2 /*return*/, reader.read().then(processText)]; }); }); } var reader, decoder; return tslib_es6.__generator(this, function (_b) { if (!(response === null || response === void 0 ? void 0 : response.ok)) { // 失败中不调用完成,如果需要,业务自行在 fail 中调用 // 防止业务在 fail 中调用 complete 时,complete 被调用两次 fail === null || fail === void 0 ? void 0 : fail({ response: response }); // 抛出错误以便链式调用中的下一个.catch()处理 return [2 /*return*/, Promise.reject(new Error('Request failed'))]; } reader = response.body.getReader(); decoder = new TextDecoder(); if (!reader) { return [2 /*return*/, Promise.reject(new Error('[SSE] 获取reader失败'))]; } return [2 /*return*/, reader.read().then(processText)]; }); }); }; /** * 在 H5 环境下发起 SSE 请求的核心函数 * @param {Object} params - 参数对象 * @param {string} params.url - 请求 URL * @param {any} params.data - 请求数据 * @param {Function} params.success - 成功回调函数 * @param {Function} params.fail - 失败回调函数 * @param {Function} params.complete - 完成回调函数 * @returns {Promise} 返回一个 Promise,包含响应对象 */ function fetchSSECoreInH5(_a) { var url = _a.url, data = _a.data, success = _a.success, fail = _a.fail, complete = _a.complete; return new Promise(function (resolve, reject) { var controller = new AbortController(); fetch(url, { method: 'POST', headers: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json;charset=UTF-8' }, body: JSON.stringify(data), credentials: 'include', // mode: 'cors', signal: controller.signal }).then(function (response) { resolve(response); parseSSEChunkInH5({ response: response, success: success, fail: fail, complete: complete }); })["catch"](function (err) { reject(err); }); }); } /** * 获取登录 Cookie * @param {Function} isTestEnv - 是否为测试环境的函数 * @returns {string} 返回拼接后的 Cookie 字符串 */ function getLoginCookie(isTestEnv) { var headerCookie = ''; var testEnv = isTestEnv === null || isTestEnv === void 0 ? void 0 : isTestEnv(); var cookieSuffix = testEnv ? '@test' : '@prod'; if (uni.getStorageSync("request-mp-set-cookie".concat(cookieSuffix))) { headerCookie = uni.getStorageSync("request-mp-set-cookie".concat(cookieSuffix)); } if (uni.getStorageSync("user-info-sessionid".concat(cookieSuffix))) { // 如果是测试环境,需要设置到tiplogin_sessionid_test var sessionKey = 'tiplogin_sessionid'; if (isTestEnv === null || isTestEnv === void 0 ? void 0 : isTestEnv()) { sessionKey = 'tiplogin_sessionid_test'; } headerCookie += ";".concat(sessionKey, "=").concat(uni.getStorageSync("user-info-sessionid".concat(cookieSuffix)), ";"); } return headerCookie; } /** * 解析 MP 环境下的 SSE 数据块 * @param {Object} params - 参数对象 * @param {string} params.chunk - 数据块 * @param {Fail} [params.fail] - 失败回调函数 * @param {Success} [params.success] - 成功回调函数 */ var parseSSEChunkInMP = function parseSSEChunkInMP(_a) { var chunk = _a.chunk, fail = _a.fail, success = _a.success; var buffers = chunk.toString().split(/\r?\n/); var i = 0; try { while (i < buffers.length) { var line = buffers[i]; var response = line.slice(5); success === null || success === void 0 ? void 0 : success(response, line); buffers.splice(i, 1); } } catch (err) { fail === null || fail === void 0 ? void 0 : fail(false); } }; /** * 在 MP 环境下发起 SSE 请求的核心函数 * @param {RequestParams} params - 请求参数 * @returns {Promise} 返回一个 Promise,包含请求任务对象 */ function fetchSSECoreInMP(_a) { var url = _a.url, data = _a.data, success = _a.success, _fail = _a.fail, complete = _a.complete, isTestEnv = _a.isTestEnv; return new Promise(function (resolve) { // 开启分块接收,模拟 SSE var requestTask = wx.request({ url: url, method: 'POST', responseType: 'arraybuffer', enableChunked: true, header: { Accept: 'text/event-stream', 'content-type': 'application/json;charset=UTF-8', cookie: getLoginCookie(isTestEnv), 'Cache-Control': 'no-cache' }, data: data, success: function success(res) { console.log('[SSE] success: ', res); complete === null || complete === void 0 ? void 0 : complete(true, res); }, fail: function fail(err) { console.log('[SSE] fail: ', err); _fail === null || _fail === void 0 ? void 0 : _fail(err); } }); // 监听数据到达事件 requestTask.onChunkReceived(function (res) { // res.data 是 ArrayBuffer,需要转换为字符串 var chunk = sse_helper.ab2str(res.data); parseSSEChunkInMP({ chunk: chunk, fail: _fail, success: success }); }); resolve(requestTask); }); } /** * 发起 SSE 请求的核心函数,根据环境自动选择 H5 或 MP 实现 * @param {RequestParams} params - 请求参数 * @param {string} params.url - 请求地址 * @param {Object} params.data - 请求数据 * @param {Function} params.success - 成功回调 * @param {Function} params.fail - 失败回调 * @param {Function} params.complete - 完成回调 * @returns {Promise} 返回一个 Promise,包含请求任务或响应对象 * @example * ```ts * import { isTestEnv } from '@tencent/pmd-tools/lib/env'; * import { cookie } from '@tencent/pmd-tools/lib/storage'; * import { safeJsonParse } from 't-comm/es/json'; * * import { fetchSSECore, type RequestParams } from 't-comm/es/sse'; * * // 检查是否结束,业务自定义 * function checkFinish(str) { * const data: any = safeJsonParse(str); * return data?.status === 3; * } * * // 业务二次封装,把自己的请求数据、自定义的处理数据的逻辑放进去 * export function sendChatMessage({ * input, * sessionId, * extraInfo, * expectedOp, * * success, * fail, * complete, * }: { * input: string; * sessionId?: string; * extraInfo?: string; * expectedOp?: Record<string, any>; * * success?: (data: any) => void; * fail?: RequestParams['fail']; * complete?: RequestParams['complete']; * }) { * const origin = isTestEnv() ? 'https://xx.com' : 'https://xx.com'; * const url = `${origin}/xx.xx.xx.xx/xx?g_app_tk=${cookie.get('tip_token')}&tstamp=${Date.now()}`; * const reqData = { * input, * session_id: sessionId, * extra_info: extraInfo, * expected_op: expectedOp, * }; * * const parsedSuccess = (str, fullStr) => { * const data: any = safeJsonParse(str); * const fullData: any = safeJsonParse(fullStr); * * if (checkFinish(str)) { * complete?.(str); * return; * } * * // 检查是否失败,业务自定义 * if (fullData?.err_msg) { * fail?.(data); * return; * } * * success?.(data); * }; * * return fetchSSECore({ * url, * data: reqData, * success: parsedSuccess, * fail, * complete, * isTestEnv, * }); * } * * ``` */ function fetchSSECore(_a) { var url = _a.url, data = _a.data, success = _a.success, fail = _a.fail, complete = _a.complete, isTestEnv = _a.isTestEnv; if (typeof wx !== 'undefined' && typeof wx.request === 'function' && typeof fetch === 'undefined' && typeof AbortController === 'undefined') { return fetchSSECoreInMP({ url: url, data: data, success: success, fail: fail, complete: complete, isTestEnv: isTestEnv }); } return fetchSSECoreInH5({ url: url, data: data, success: success, fail: fail, complete: complete }); } exports.fetchSSECore = fetchSSECore; exports.fetchSSECoreInH5 = fetchSSECoreInH5; exports.fetchSSECoreInMP = fetchSSECoreInMP; exports.parseSSEChunkInH5 = parseSSEChunkInH5; exports.parseSSEChunkInMP = parseSSEChunkInMP;