初始化
|
|
@ -0,0 +1,19 @@
|
|||
import { Request } from '../../utils/request'
|
||||
|
||||
export const GetCheckoutRoomNum = (roomNum: string) => Request({
|
||||
url: `/room/checkout?roomNum=${roomNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
export const PostAnonLogin = (data: any) => Request({
|
||||
url: `/auth/anon-login`,
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
export const GetAgoraConf = () => Request({
|
||||
url: `/home/agora-conf`,
|
||||
method: 'get',
|
||||
})
|
||||
export const GetRoomRtcToken = (roomNum: string) => Request({
|
||||
url: `/room/tk/rtc?roomNum=${roomNum}`,
|
||||
method: 'get',
|
||||
})
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { Request } from '../../utils/request'
|
||||
|
||||
export const GetRoomUser = (roomNum: string) => Request({
|
||||
url: `/room/user?roomNum=${roomNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
|
||||
export const GetShowUser = (roomNum: string) => Request({
|
||||
url: `/room/show-user?roomNum=${roomNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
|
||||
export const GetApplySpeak = (roomNum: string) => Request({
|
||||
url: `/room/apply-speak?roomNum=${roomNum}`,
|
||||
method: 'get'
|
||||
})
|
||||
|
||||
export const PostMuteAll = (data: any) => {
|
||||
return Request({
|
||||
url: `/room/mute-all?roomNum=${data.roomNum}&enableMicr=${data.enableMicr}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export const PostOpenMicr = (data: any) => {
|
||||
return Request({
|
||||
url: `/room/oper-micr?roomNum=${data.roomNum}&enableMicr=${data.enableMicr}&uid=${data.uid}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export const PostOpenCamera = (data: any) =>
|
||||
Request({
|
||||
url: `/room/oper-camera`,
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
|
||||
export const DeleteRoomManager = (data: any) =>
|
||||
Request({
|
||||
url: `/room/manager`,
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
|
||||
export const GetRoomInfo = (roomNum: string) =>
|
||||
Request({
|
||||
url: `/room/${roomNum}`,
|
||||
method: 'get',
|
||||
})
|
||||
11
app.js
|
|
@ -1,10 +1,5 @@
|
|||
import gulpError from './utils/gulpError';
|
||||
App({
|
||||
onShow() {
|
||||
if (gulpError !== 'gulpErrorPlaceHolder') {
|
||||
wx.redirectTo({
|
||||
url: `/pages/gulp-error/index?gulpError=${gulpError}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
|
||||
}
|
||||
});
|
||||
|
|
|
|||
117
app.json
|
|
@ -1,113 +1,24 @@
|
|||
{
|
||||
"pages": [
|
||||
"pages/home/home",
|
||||
"pages/button/button",
|
||||
"pages/tabs/tabs",
|
||||
"pages/icon/icon",
|
||||
"pages/loading/loading",
|
||||
"pages/progress/progress",
|
||||
"pages/cascader/cascader",
|
||||
"pages/cell/cell",
|
||||
"pages/cell-group/cell-group",
|
||||
"pages/collapse/collapse",
|
||||
"pages/input/input",
|
||||
"pages/badge/badge",
|
||||
"pages/textarea/textarea",
|
||||
"pages/message/message",
|
||||
"pages/toast/toast",
|
||||
"pages/stepper/stepper",
|
||||
"pages/slider/slider",
|
||||
"pages/radio/radio",
|
||||
"pages/switch/switch",
|
||||
"pages/sticky/sticky",
|
||||
"pages/tag/tag",
|
||||
"pages/checkbox/checkbox",
|
||||
"pages/gulp-error/index",
|
||||
"pages/fab/fab",
|
||||
"pages/tab-bar/tab-bar",
|
||||
"pages/transition/transition",
|
||||
"pages/popup/popup",
|
||||
"pages/steps/steps",
|
||||
"pages/dropdown-menu/dropdown-menu",
|
||||
"pages/drawer/drawer",
|
||||
"pages/pull-down-refresh/pull-down-refresh",
|
||||
"pages/skeleton/skeleton",
|
||||
"pages/footer/footer",
|
||||
"pages/divider/divider",
|
||||
"pages/empty/empty",
|
||||
"pages/back-top/back-top",
|
||||
"pages/grid/grid",
|
||||
"pages/upload/upload",
|
||||
"pages/count-down/count-down",
|
||||
"pages/overlay/overlay",
|
||||
"pages/image/image",
|
||||
"pages/search/search",
|
||||
"pages/home/navigateFail/navigateFail",
|
||||
"pages/navbar/navbar",
|
||||
"pages/date-time-picker/date-time-picker",
|
||||
"pages/notice-bar/notice-bar",
|
||||
"pages/image-viewer/image-viewer",
|
||||
"pages/result/result",
|
||||
"pages/result/result-page",
|
||||
"pages/link/link"
|
||||
],
|
||||
"subpackages": [
|
||||
{
|
||||
"root": "pages/side-bar/",
|
||||
"pages": ["side-bar", "base/index", "switch/index", "custom/index", "with-icon/index"]
|
||||
},
|
||||
{
|
||||
"root": "pages/action-sheet/",
|
||||
"pages": ["action-sheet"]
|
||||
},
|
||||
{
|
||||
"root": "pages/avatar/",
|
||||
"pages": ["avatar"]
|
||||
},
|
||||
{
|
||||
"root": "pages/calendar/",
|
||||
"pages": ["calendar"]
|
||||
},
|
||||
{
|
||||
"root": "pages/dialog/",
|
||||
"pages": ["dialog"]
|
||||
},
|
||||
{
|
||||
"root": "pages/picker/",
|
||||
"pages": ["picker"]
|
||||
},
|
||||
{
|
||||
"root": "pages/rate/",
|
||||
"pages": ["rate"]
|
||||
},
|
||||
{
|
||||
"root": "pages/swiper/",
|
||||
"pages": ["swiper"]
|
||||
},
|
||||
{
|
||||
"root": "pages/swipe-cell/",
|
||||
"pages": ["swipe-cell"]
|
||||
},
|
||||
{
|
||||
"root": "pages/tree-select/",
|
||||
"pages": ["tree-select"]
|
||||
},
|
||||
{
|
||||
"root": "pages/indexes/",
|
||||
"pages": ["indexes", "base/index", "custom/index"]
|
||||
}
|
||||
"pages/form/index",
|
||||
"pages/meeting/index"
|
||||
],
|
||||
"subpackages": [],
|
||||
"usingComponents": {
|
||||
"t-demo": "./components/demo-block/index",
|
||||
"status-bar-height": "components/status-bar-height/index",
|
||||
"header-tab": "components/header-tab/index",
|
||||
"t-input": "tdesign-miniprogram/input/input",
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon"
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-avatar": "tdesign-miniprogram/avatar/avatar",
|
||||
"t-message": "tdesign-miniprogram/message/message",
|
||||
"t-dialog": "tdesign-miniprogram/dialog/dialog",
|
||||
"t-popup": "tdesign-miniprogram/popup/popup"
|
||||
},
|
||||
"entryPagePath": "pages/form/index",
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#f6f6f6",
|
||||
"backgroundColor": "#f6f6f6",
|
||||
"navigationBarTitleText": "TDesign",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
||||
}
|
||||
27
app.wxss
|
|
@ -1,19 +1,10 @@
|
|||
image {
|
||||
display: block;
|
||||
}
|
||||
|
||||
page {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
.demo {
|
||||
padding-bottom: 56rpx;
|
||||
}
|
||||
.demo-title {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
line-height: 64rpx;
|
||||
margin: 48rpx 32rpx 0;
|
||||
color: var(--td-font-gray-1, rgba(0, 0, 0, 0.9));
|
||||
}
|
||||
.demo-desc {
|
||||
font-size: 28rpx;
|
||||
color: var(--td-font-gray-2, rgba(0, 0, 0, 0.6));
|
||||
margin: 16rpx 32rpx 0;
|
||||
line-height: 44rpx;
|
||||
}
|
||||
--td-button-primary-color: white;
|
||||
--td-button-primary-bg-color: #5575F2;
|
||||
--td-button-primary-border-color: #5575F2;
|
||||
--td-switch-checked-color: #5575F2;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 299 B |
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
},
|
||||
properties: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
desc: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
operList: Array,
|
||||
padding: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
clickHandle(e) {
|
||||
const { type } = e.currentTarget.dataset;
|
||||
this.triggerEvent('clickoper', type);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<view class="demo-block {{!title && 'demo-block_notitle'}}">
|
||||
<view wx:if="{{ title || desc }}" class="demo-block__header">
|
||||
<view wx:if="{{ title }}" class="demo-block__header-title">{{ title }}</view>
|
||||
<view wx:if="{{ desc }}" class="demo-block__header-desc {{!title && 'demo-block_subtitle' }}">{{ desc }}</view>
|
||||
<!-- <slot name="title-right" /> -->
|
||||
</view>
|
||||
<view wx:for="{{ operList }}" wx:for-item="operItem" wx:key="oper" class="demo-block__oper">
|
||||
<view wx:if="{{ operItem.title }}" class="demo-block__oper-subtitle">{{ operItem.title }}</view>
|
||||
<view wx:for="{{ operItem.btns }}" wx:for-item="btnItem" wx:key="btn">
|
||||
<t-button t-class="demo-block__oper-btn" size="large" block data-type="{{ btnItem.type }}" bind:tap="clickHandle">
|
||||
{{ btnItem.text }}
|
||||
</t-button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="demo-block__slot {{padding ? 'with-padding' : ''}}">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
.demo-block {
|
||||
margin: var(--td-spacer-4, 64rpx) 0 0;
|
||||
}
|
||||
.demo-block__header {
|
||||
color: #000;
|
||||
margin: 0 var(--td-spacer-2, 32rpx);
|
||||
}
|
||||
.demo-block__header-title {
|
||||
font-weight: 700;
|
||||
font-size: 36rpx;
|
||||
line-height: 52rpx;
|
||||
}
|
||||
.demo-block__header-desc {
|
||||
margin-top: var(--td-spacer, 16rpx);
|
||||
font-size: var(--td-font-size-base, 28rpx);
|
||||
white-space: pre-line;
|
||||
color: var(--td-font-gray-2, rgba(0, 0, 0, 0.6));
|
||||
line-height: 22px;
|
||||
}
|
||||
.demo-block__oper {
|
||||
margin-top: var(--td-spacer, 16rpx);
|
||||
}
|
||||
.demo-block__oper-subtitle {
|
||||
font-size: var(--td-font-size-s, 24rpx);
|
||||
margin-bottom: var(--td-spacer-2, 32rpx);
|
||||
opacity: 0.4;
|
||||
}
|
||||
.demo-block__oper-btn {
|
||||
margin: 0 0 var(--td-spacer-2, 32rpx) 0;
|
||||
height: 96rpx;
|
||||
}
|
||||
.demo-block__slot {
|
||||
margin-top: var(--td-spacer-2, 32rpx);
|
||||
}
|
||||
.demo-block__slot.with-padding {
|
||||
margin: var(--td-spacer-2, 32rpx) var(--td-spacer-2, 32rpx) 0;
|
||||
}
|
||||
.demo-block_notitle {
|
||||
margin-top: 0px;
|
||||
}
|
||||
.demo-block_notitle .demo-block_subtitle {
|
||||
margin-top: var(--td-spacer-3, 48rpx);
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
.header-tab {
|
||||
flex-shrink: 0;
|
||||
|
||||
&-title {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
padding: 24rpx 0;
|
||||
|
||||
&-back {
|
||||
position: absolute;
|
||||
left: 40rpx;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Component({
|
||||
properties: {
|
||||
title: {
|
||||
type: String,
|
||||
value: '无'
|
||||
},
|
||||
backGround: {
|
||||
type: String,
|
||||
value: 'white'
|
||||
},
|
||||
isBack: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
isStatusBarHeight: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
value: 'black'
|
||||
},
|
||||
titleStyle: {
|
||||
type: String,
|
||||
},
|
||||
iconSize: {
|
||||
type: String,
|
||||
value: '48'
|
||||
},
|
||||
},
|
||||
data: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
wx.navigateBack()
|
||||
},
|
||||
},
|
||||
ready() {
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<view class="header-tab" style="background-color: {{backGround}};">
|
||||
<status-bar-height wx:if="{{isStatusBarHeight}}"></status-bar-height>
|
||||
<view class="header-tab-title" style="color: {{color}};{{titleStyle}}">
|
||||
{{title}}
|
||||
<t-icon name="chevron-left" size="{{iconSize}}rpx" data-name="chevron-left" color='{{color}}' class="header-tab-title-back" wx:if="{{isBack === true}}" bind:tap="back" />
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -1 +0,0 @@
|
|||
declare const itemHeight: number;
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
const itemHeight = 56 * 2;
|
||||
Component({
|
||||
data: {
|
||||
childBoxHeight: 0,
|
||||
},
|
||||
externalClasses: ['t-class'],
|
||||
properties: {
|
||||
defaultOpen: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
childArr: {
|
||||
type: Array,
|
||||
value: [],
|
||||
observer(childArr) {
|
||||
this.setData({
|
||||
childBoxHeight: this.data.defaultOpen ? itemHeight * childArr.length : 0,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
switchHandle() {
|
||||
const { childArr, childBoxHeight } = this.data;
|
||||
this.setData({
|
||||
childBoxHeight: childBoxHeight > 0 ? 0 : childArr.length * itemHeight,
|
||||
});
|
||||
},
|
||||
tapChild(e) {
|
||||
this.triggerEvent('click', e.target.dataset);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<view class="pullDownList t-class {{ childBoxHeight > 0 ? 'actived' : '' }}">
|
||||
<view class="switchBox" aria-role="button" aria-expanded="{{!!childBoxHeight}}" catch:tap="switchHandle">
|
||||
<view class="name">{{ name }}</view>
|
||||
<t-icon name="{{icon}}" size="48rpx" color="#A6A6A6" t-class="icon" aria-hidden />
|
||||
</view>
|
||||
<view class="childBox" style="height: {{ childBoxHeight }}rpx" aria-hidden="{{childBoxHeight ? '' : true}}">
|
||||
<view class="child" wx:for="{{childArr}}" wx:key="name" data-item="{{item}}" aria-role="button" bind:tap="tapChild">
|
||||
{{ item.name }} {{ item.label }}
|
||||
<t-icon name="chevron-right" color="#bbb" aria-hidden />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
.pullDownList {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border-radius: 8rpx;
|
||||
margin-bottom: 24rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.pullDownList .switchBox {
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 32rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 48rpx;
|
||||
color: #333;
|
||||
}
|
||||
.pullDownList .name,
|
||||
.pullDownList .icon {
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.pullDownList .name {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.pullDownList.actived .name {
|
||||
opacity: 0.4;
|
||||
}
|
||||
.pullDownList.actived .icon {
|
||||
opacity: 0.4;
|
||||
}
|
||||
.pullDownList .childBox {
|
||||
transition: height 0.3s;
|
||||
}
|
||||
.pullDownList .childBox .child {
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
height: 112rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-left: 32rpx;
|
||||
margin-right: 32rpx;
|
||||
font-size: 32rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.pullDownList .childBox .child:last-of-type {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Component({
|
||||
properties: {
|
||||
|
||||
},
|
||||
data: {
|
||||
height: 0
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
ready() {
|
||||
this.setData({
|
||||
height: wx.getWindowInfo().statusBarHeight
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1 @@
|
|||
<view style="height: {{height}}px;"></view>
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1 +0,0 @@
|
|||
Component({});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<view>
|
||||
<t-radio class="basic-radio" title="单行标题" name="radio1"></t-radio>
|
||||
<t-radio title="双行标题,长文本自动换行,该选项的描述是一段很长的内容" name="radio2"></t-radio>
|
||||
</view>
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
Component({
|
||||
properties: {
|
||||
items: {
|
||||
type: Array,
|
||||
value: [],
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
currentValue: '',
|
||||
},
|
||||
methods: {
|
||||
onChange(event) {
|
||||
this.setData({
|
||||
currentValue: event.detail.name,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<t-radio-group class="radio-group" bind:change="onChange" value="{{value}}">
|
||||
<t-radio
|
||||
wx:for="{{items}}"
|
||||
class="{{item.disabled ? 'radio-disabled' : ''}}"
|
||||
wx:key="index"
|
||||
title="{{item.title}}"
|
||||
name="{{item.name}}"
|
||||
disabled="{{item.disabled}}"
|
||||
data-bordered="{{item.bordered}}"
|
||||
label="{{item.label}}"
|
||||
></t-radio>
|
||||
</t-radio-group>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
module.exports = (function() {
|
||||
var __MODS__ = {};
|
||||
var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
|
||||
var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
|
||||
var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
|
||||
var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
|
||||
__DEFINE__(1731653753937, function(require, module, exports) {
|
||||
|
||||
|
||||
// do not edit .js files directly - edit src/index.jst
|
||||
|
||||
|
||||
|
||||
module.exports = function equal(a, b) {
|
||||
if (a === b) return true;
|
||||
|
||||
if (a && b && typeof a == 'object' && typeof b == 'object') {
|
||||
if (a.constructor !== b.constructor) return false;
|
||||
|
||||
var length, i, keys;
|
||||
if (Array.isArray(a)) {
|
||||
length = a.length;
|
||||
if (length != b.length) return false;
|
||||
for (i = length; i-- !== 0;)
|
||||
if (!equal(a[i], b[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
|
||||
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
|
||||
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
|
||||
|
||||
keys = Object.keys(a);
|
||||
length = keys.length;
|
||||
if (length !== Object.keys(b).length) return false;
|
||||
|
||||
for (i = length; i-- !== 0;)
|
||||
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
|
||||
|
||||
for (i = length; i-- !== 0;) {
|
||||
var key = keys[i];
|
||||
|
||||
if (!equal(a[key], b[key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// true if both NaN, false otherwise
|
||||
return a!==a && b!==b;
|
||||
};
|
||||
|
||||
}, function(modId) {var map = {}; return __REQUIRE__(map[modId], modId); })
|
||||
return __REQUIRE__(1731653753937);
|
||||
})()
|
||||
//miniprogram-npm-outsideDeps=[]
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.js","sourcesContent":["\n\n// do not edit .js files directly - edit src/index.jst\n\n\n\nmodule.exports = function equal(a, b) {\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n if (a.constructor !== b.constructor) return false;\n\n var length, i, keys;\n if (Array.isArray(a)) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n\n\n if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;\n if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();\n if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();\n\n keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length) return false;\n\n for (i = length; i-- !== 0;)\n if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n\n for (i = length; i-- !== 0;) {\n var key = keys[i];\n\n if (!equal(a[key], b[key])) return false;\n }\n\n return true;\n }\n\n // true if both NaN, false otherwise\n return a!==a && b!==b;\n};\n"]}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
module.exports = (function() {
|
||||
var __MODS__ = {};
|
||||
var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
|
||||
var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
|
||||
var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
|
||||
var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
|
||||
__DEFINE__(1731653753938, function(require, module, exports) {
|
||||
|
||||
module.exports = rfdc
|
||||
|
||||
function copyBuffer (cur) {
|
||||
if (cur instanceof Buffer) {
|
||||
return Buffer.from(cur)
|
||||
}
|
||||
|
||||
return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)
|
||||
}
|
||||
|
||||
function rfdc (opts) {
|
||||
opts = opts || {}
|
||||
if (opts.circles) return rfdcCircles(opts)
|
||||
|
||||
const constructorHandlers = new Map()
|
||||
constructorHandlers.set(Date, (o) => new Date(o))
|
||||
constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))
|
||||
constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))
|
||||
if (opts.constructorHandlers) {
|
||||
for (const handler of opts.constructorHandlers) {
|
||||
constructorHandlers.set(handler[0], handler[1])
|
||||
}
|
||||
}
|
||||
|
||||
let handler = null
|
||||
|
||||
return opts.proto ? cloneProto : clone
|
||||
|
||||
function cloneArray (a, fn) {
|
||||
const keys = Object.keys(a)
|
||||
const a2 = new Array(keys.length)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const k = keys[i]
|
||||
const cur = a[k]
|
||||
if (typeof cur !== 'object' || cur === null) {
|
||||
a2[k] = cur
|
||||
} else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
|
||||
a2[k] = handler(cur, fn)
|
||||
} else if (ArrayBuffer.isView(cur)) {
|
||||
a2[k] = copyBuffer(cur)
|
||||
} else {
|
||||
a2[k] = fn(cur)
|
||||
}
|
||||
}
|
||||
return a2
|
||||
}
|
||||
|
||||
function clone (o) {
|
||||
if (typeof o !== 'object' || o === null) return o
|
||||
if (Array.isArray(o)) return cloneArray(o, clone)
|
||||
if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
|
||||
return handler(o, clone)
|
||||
}
|
||||
const o2 = {}
|
||||
for (const k in o) {
|
||||
if (Object.hasOwnProperty.call(o, k) === false) continue
|
||||
const cur = o[k]
|
||||
if (typeof cur !== 'object' || cur === null) {
|
||||
o2[k] = cur
|
||||
} else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
|
||||
o2[k] = handler(cur, clone)
|
||||
} else if (ArrayBuffer.isView(cur)) {
|
||||
o2[k] = copyBuffer(cur)
|
||||
} else {
|
||||
o2[k] = clone(cur)
|
||||
}
|
||||
}
|
||||
return o2
|
||||
}
|
||||
|
||||
function cloneProto (o) {
|
||||
if (typeof o !== 'object' || o === null) return o
|
||||
if (Array.isArray(o)) return cloneArray(o, cloneProto)
|
||||
if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
|
||||
return handler(o, cloneProto)
|
||||
}
|
||||
const o2 = {}
|
||||
for (const k in o) {
|
||||
const cur = o[k]
|
||||
if (typeof cur !== 'object' || cur === null) {
|
||||
o2[k] = cur
|
||||
} else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
|
||||
o2[k] = handler(cur, cloneProto)
|
||||
} else if (ArrayBuffer.isView(cur)) {
|
||||
o2[k] = copyBuffer(cur)
|
||||
} else {
|
||||
o2[k] = cloneProto(cur)
|
||||
}
|
||||
}
|
||||
return o2
|
||||
}
|
||||
}
|
||||
|
||||
function rfdcCircles (opts) {
|
||||
const refs = []
|
||||
const refsNew = []
|
||||
|
||||
const constructorHandlers = new Map()
|
||||
constructorHandlers.set(Date, (o) => new Date(o))
|
||||
constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))
|
||||
constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))
|
||||
if (opts.constructorHandlers) {
|
||||
for (const handler of opts.constructorHandlers) {
|
||||
constructorHandlers.set(handler[0], handler[1])
|
||||
}
|
||||
}
|
||||
|
||||
let handler = null
|
||||
return opts.proto ? cloneProto : clone
|
||||
|
||||
function cloneArray (a, fn) {
|
||||
const keys = Object.keys(a)
|
||||
const a2 = new Array(keys.length)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const k = keys[i]
|
||||
const cur = a[k]
|
||||
if (typeof cur !== 'object' || cur === null) {
|
||||
a2[k] = cur
|
||||
} else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
|
||||
a2[k] = handler(cur, fn)
|
||||
} else if (ArrayBuffer.isView(cur)) {
|
||||
a2[k] = copyBuffer(cur)
|
||||
} else {
|
||||
const index = refs.indexOf(cur)
|
||||
if (index !== -1) {
|
||||
a2[k] = refsNew[index]
|
||||
} else {
|
||||
a2[k] = fn(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
return a2
|
||||
}
|
||||
|
||||
function clone (o) {
|
||||
if (typeof o !== 'object' || o === null) return o
|
||||
if (Array.isArray(o)) return cloneArray(o, clone)
|
||||
if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
|
||||
return handler(o, clone)
|
||||
}
|
||||
const o2 = {}
|
||||
refs.push(o)
|
||||
refsNew.push(o2)
|
||||
for (const k in o) {
|
||||
if (Object.hasOwnProperty.call(o, k) === false) continue
|
||||
const cur = o[k]
|
||||
if (typeof cur !== 'object' || cur === null) {
|
||||
o2[k] = cur
|
||||
} else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
|
||||
o2[k] = handler(cur, clone)
|
||||
} else if (ArrayBuffer.isView(cur)) {
|
||||
o2[k] = copyBuffer(cur)
|
||||
} else {
|
||||
const i = refs.indexOf(cur)
|
||||
if (i !== -1) {
|
||||
o2[k] = refsNew[i]
|
||||
} else {
|
||||
o2[k] = clone(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
refs.pop()
|
||||
refsNew.pop()
|
||||
return o2
|
||||
}
|
||||
|
||||
function cloneProto (o) {
|
||||
if (typeof o !== 'object' || o === null) return o
|
||||
if (Array.isArray(o)) return cloneArray(o, cloneProto)
|
||||
if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
|
||||
return handler(o, cloneProto)
|
||||
}
|
||||
const o2 = {}
|
||||
refs.push(o)
|
||||
refsNew.push(o2)
|
||||
for (const k in o) {
|
||||
const cur = o[k]
|
||||
if (typeof cur !== 'object' || cur === null) {
|
||||
o2[k] = cur
|
||||
} else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
|
||||
o2[k] = handler(cur, cloneProto)
|
||||
} else if (ArrayBuffer.isView(cur)) {
|
||||
o2[k] = copyBuffer(cur)
|
||||
} else {
|
||||
const i = refs.indexOf(cur)
|
||||
if (i !== -1) {
|
||||
o2[k] = refsNew[i]
|
||||
} else {
|
||||
o2[k] = cloneProto(cur)
|
||||
}
|
||||
}
|
||||
}
|
||||
refs.pop()
|
||||
refsNew.pop()
|
||||
return o2
|
||||
}
|
||||
}
|
||||
|
||||
}, function(modId) {var map = {}; return __REQUIRE__(map[modId], modId); })
|
||||
return __REQUIRE__(1731653753938);
|
||||
})()
|
||||
//miniprogram-npm-outsideDeps=[]
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
//粗略填写 https://developer.mozilla.org/en-US/docs/Web/API/AbortController
|
||||
//实际上,我们从来没有使用被polyfill填充的API,我们总是使用polyfill,因为
|
||||
//它现在还是一个非常新的API。
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var AbortController = /** @class */ (function () {
|
||||
function AbortController() {
|
||||
this.isAborted = false;
|
||||
this.onabort = null;
|
||||
}
|
||||
AbortController.prototype.abort = function () {
|
||||
if (!this.isAborted) {
|
||||
this.isAborted = true;
|
||||
if (this.onabort) {
|
||||
this.onabort();
|
||||
}
|
||||
}
|
||||
};
|
||||
Object.defineProperty(AbortController.prototype, "signal", {
|
||||
get: function () {
|
||||
return this;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(AbortController.prototype, "aborted", {
|
||||
get: function () {
|
||||
return this.isAborted;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
return AbortController;
|
||||
}());
|
||||
export { AbortController };
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
import { Request } from "./wx-request/index";
|
||||
import { RequestMethod, ResponseType } from "./wx-request/model";
|
||||
/**
|
||||
* 生成默认请求库
|
||||
*
|
||||
* @export
|
||||
* @class DefaultRequest
|
||||
*/
|
||||
var DefaultRequest = /** @class */ (function (_super) {
|
||||
__extends(DefaultRequest, _super);
|
||||
function DefaultRequest(config, logger) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.logger = logger
|
||||
? logger
|
||||
: {
|
||||
log: function (logLevel, message) {
|
||||
/* 屏蔽打印 */
|
||||
}
|
||||
};
|
||||
// default config
|
||||
_this.setConfig(__assign({ about: false, forceEnableHttps: false, headers: {}, method: RequestMethod.GET, responseEncoding: ResponseType.JSON, timeout: 2 * 60 * 1000, transformRequest: [], transformResponse: [] }, config));
|
||||
return _this;
|
||||
}
|
||||
return DefaultRequest;
|
||||
}(Request));
|
||||
export default DefaultRequest;
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
/**
|
||||
* Error thrown when an HTTP request fails.
|
||||
* HTTP请求失败时引发错误。
|
||||
*/
|
||||
var HttpError = /** @class */ (function (_super) {
|
||||
__extends(HttpError, _super);
|
||||
/** Constructs a new instance of {@link @aspnet/signalr.HttpError}.
|
||||
*
|
||||
* @param {string} errorMessage A descriptive error message.
|
||||
* @param {number} statusCode The HTTP status code represented by this error.
|
||||
*/
|
||||
function HttpError(errorMessage, statusCode) {
|
||||
var _newTarget = this.constructor;
|
||||
var _this = this;
|
||||
var trueProto = _newTarget.prototype;
|
||||
_this = _super.call(this, errorMessage) || this;
|
||||
_this.statusCode = statusCode;
|
||||
// Workaround issue in Typescript compiler
|
||||
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
|
||||
_this.__proto__ = trueProto;
|
||||
return _this;
|
||||
}
|
||||
return HttpError;
|
||||
}(Error));
|
||||
export { HttpError };
|
||||
/**
|
||||
* Error thrown when a timeout elapses.
|
||||
* 超时错误
|
||||
*/
|
||||
var TimeoutError = /** @class */ (function (_super) {
|
||||
__extends(TimeoutError, _super);
|
||||
/** Constructs a new instance of {@link @aspnet/signalr.TimeoutError}.
|
||||
*
|
||||
* @param {string} errorMessage A descriptive error message.
|
||||
*/
|
||||
function TimeoutError(errorMessage) {
|
||||
var _newTarget = this.constructor;
|
||||
if (errorMessage === void 0) { errorMessage = "A timeout occurred."; }
|
||||
var _this = this;
|
||||
var trueProto = _newTarget.prototype;
|
||||
_this = _super.call(this, errorMessage) || this;
|
||||
// Workaround issue in Typescript compiler
|
||||
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
|
||||
_this.__proto__ = trueProto;
|
||||
return _this;
|
||||
}
|
||||
return TimeoutError;
|
||||
}(Error));
|
||||
export { TimeoutError };
|
||||
/**
|
||||
* Error thrown when an action is aborted.
|
||||
* 连接错误
|
||||
*/
|
||||
var AbortError = /** @class */ (function (_super) {
|
||||
__extends(AbortError, _super);
|
||||
/** Constructs a new instance of {@link AbortError}.
|
||||
*
|
||||
* @param {string} errorMessage A descriptive error message.
|
||||
*/
|
||||
function AbortError(errorMessage) {
|
||||
var _newTarget = this.constructor;
|
||||
if (errorMessage === void 0) { errorMessage = "An abort occurred."; }
|
||||
var _this = this;
|
||||
var trueProto = _newTarget.prototype;
|
||||
_this = _super.call(this, errorMessage) || this;
|
||||
// Workaround issue in Typescript compiler
|
||||
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
|
||||
_this.__proto__ = trueProto;
|
||||
return _this;
|
||||
}
|
||||
return AbortError;
|
||||
}(Error));
|
||||
export { AbortError };
|
||||
/**
|
||||
* Error thrown when message event is not found.
|
||||
* 事件未定义
|
||||
*/
|
||||
var EventNotFoundError = /** @class */ (function (_super) {
|
||||
__extends(EventNotFoundError, _super);
|
||||
/** Constructs a new instance of {@link AbortError}.
|
||||
*
|
||||
* @param {string} errorMessage A descriptive error message.
|
||||
*/
|
||||
function EventNotFoundError(invocationMessage, errorMessage) {
|
||||
var _newTarget = this.constructor;
|
||||
if (errorMessage === void 0) { errorMessage = "message event not found."; }
|
||||
var _this = this;
|
||||
var trueProto = _newTarget.prototype;
|
||||
_this = _super.call(this, errorMessage) || this;
|
||||
_this.methodName = invocationMessage.target;
|
||||
_this.invocationMessage = invocationMessage;
|
||||
// Workaround issue in Typescript compiler
|
||||
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
|
||||
_this.__proto__ = trueProto;
|
||||
return _this;
|
||||
}
|
||||
return EventNotFoundError;
|
||||
}(Error));
|
||||
export { EventNotFoundError };
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
import { TextMessageFormat } from "./TextMessageFormat";
|
||||
import { isArrayBuffer } from "./Utils";
|
||||
/**
|
||||
* 握手协议
|
||||
* @private
|
||||
*/
|
||||
var HandshakeProtocol = /** @class */ (function () {
|
||||
function HandshakeProtocol() {
|
||||
}
|
||||
// Handshake request is always JSON - 握手请求总是JSON
|
||||
HandshakeProtocol.prototype.writeHandshakeRequest = function (handshakeRequest) {
|
||||
// commond
|
||||
return TextMessageFormat.write(JSON.stringify(handshakeRequest));
|
||||
};
|
||||
/**
|
||||
* 解析握手协议 response
|
||||
*
|
||||
* @param {*} data
|
||||
* @returns {[any, HandshakeResponseMessage]}
|
||||
* @memberof HandshakeProtocol
|
||||
*/
|
||||
HandshakeProtocol.prototype.parseHandshakeResponse = function (data) {
|
||||
var responseMessage;
|
||||
var messageData;
|
||||
var remainingData;
|
||||
// ! 删除了 @aspnet/signlaR 原有的 Buffer(仅适用 nodejs)判断
|
||||
if (isArrayBuffer(data)) {
|
||||
// Format is binary but still need to read JSON text from handshake response - fy: 格式是二进制的,但仍然需要从握手响应中读取JSON文本
|
||||
var binaryData = new Uint8Array(data);
|
||||
var separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);
|
||||
if (separatorIndex === -1) {
|
||||
throw new Error("Message is incomplete.");
|
||||
}
|
||||
// content before separator is handshake response - fy:分隔符前的内容是握手响应
|
||||
// optional content after is additional messages - fy:后面是附加消息的可选内容
|
||||
var responseLength = separatorIndex + 1;
|
||||
messageData = String.fromCharCode.apply(null, binaryData.slice(0, responseLength));
|
||||
remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;
|
||||
}
|
||||
else {
|
||||
var textData = data;
|
||||
var separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);
|
||||
if (separatorIndex === -1) {
|
||||
throw new Error("Message is incomplete.");
|
||||
}
|
||||
// content before separator is handshake response - fy:分隔符前的内容是握手响应
|
||||
// optional content after is additional messages - fy:后面是附加消息的可选内容
|
||||
var responseLength = separatorIndex + 1;
|
||||
messageData = textData.substring(0, responseLength);
|
||||
remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;
|
||||
}
|
||||
// At this point we should have just the single handshake message - fy: 在这一点上,我们应该只有一个握手信息
|
||||
var messages = TextMessageFormat.parse(messageData);
|
||||
var response = JSON.parse(messages[0]);
|
||||
if (response.type) {
|
||||
throw new Error("Expected a handshake response from the server. -(fy: 需要来自服务器的握手响应)");
|
||||
}
|
||||
responseMessage = response;
|
||||
// multiple messages could have arrived with handshake - fy: 握手时可能会收到多条消息
|
||||
// return additional data to be parsed as usual, or null if all parsed - fy: 返回要像往常一样分析的其他数据,如果所有数据都已分析,则返回null
|
||||
return [remainingData, responseMessage];
|
||||
};
|
||||
return HandshakeProtocol;
|
||||
}());
|
||||
export { HandshakeProtocol };
|
||||
|
|
@ -0,0 +1,479 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
import { LogLevel } from "./ILogger";
|
||||
import { HttpTransportType, TransferFormat } from "./ITransport";
|
||||
import { LongPollingTransport } from "./LongPollingTransport";
|
||||
import { Arg, createLogger } from "./Utils";
|
||||
import DefaultRequest from "./DefualtRequest";
|
||||
import { ResponseType } from "./wx-request/model/ResponseType";
|
||||
import { WxSocketTransport } from "./WxSocketTransport";
|
||||
var MAX_REDIRECTS = 100;
|
||||
var WxSocketModule = WxSocketTransport;
|
||||
var LongPollingModule = LongPollingTransport;
|
||||
/** @private */
|
||||
var HttpConnection = /** @class */ (function () {
|
||||
function HttpConnection(url, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
this.features = {};
|
||||
Arg.isRequired(url, "url");
|
||||
this.logger = createLogger(options.logger);
|
||||
options = options || {};
|
||||
// ! 这里修改为自定义解析 和 默认传入 全路径方式
|
||||
this.baseUrl = options.resolveUrl ? options.resolveUrl(url) : this.resolveUrl(url);
|
||||
options.logMessageContent = options.logMessageContent || false;
|
||||
// ! 修改 options 参数赋值方式
|
||||
if (!options.WxSocket && wx) {
|
||||
options.WxSocket = WxSocketModule;
|
||||
}
|
||||
if (!options.LongPolling) {
|
||||
options.LongPolling = LongPollingModule;
|
||||
}
|
||||
this.request = options.request || new DefaultRequest({}, this.logger);
|
||||
this.connectionState = 2 /* Disconnected */;
|
||||
this.options = options;
|
||||
this.onreceive = null;
|
||||
this.onclose = null;
|
||||
}
|
||||
HttpConnection.prototype.start = function (transferFormat) {
|
||||
transferFormat = transferFormat || TransferFormat.Binary;
|
||||
Arg.isIn(transferFormat, TransferFormat, "transferFormat");
|
||||
this.logger.log(LogLevel.Debug, "Starting connection with transfer format '" + TransferFormat[transferFormat] + "'.", TransferFormat);
|
||||
if (this.connectionState !== 2 /* Disconnected */) {
|
||||
return Promise.reject(new Error("Cannot start a connection that is not in the 'Disconnected' state. state is " + this.connectionState));
|
||||
}
|
||||
this.connectionState = 0 /* Connecting */;
|
||||
this.startPromise = this.startInternal(transferFormat);
|
||||
return this.startPromise;
|
||||
};
|
||||
HttpConnection.prototype.send = function (data) {
|
||||
if (this.connectionState !== 1 /* Connected */) {
|
||||
throw new Error("Cannot send data if the connection is not in the 'Connected' State.");
|
||||
}
|
||||
// Transport will not be null if state is connected
|
||||
return this.transport.send(data);
|
||||
};
|
||||
HttpConnection.prototype.stop = function (error) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var e_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.connectionState = 2 /* Disconnected */;
|
||||
// Set error as soon as possible otherwise there is a race between
|
||||
// the transport closing and providing an error and the error from a close message
|
||||
// We would prefer the close message error.
|
||||
this.stopError = error;
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, this.startPromise];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_1 = _a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 4:
|
||||
if (!this.transport) return [3 /*break*/, 6];
|
||||
return [4 /*yield*/, this.transport.stop()];
|
||||
case 5:
|
||||
_a.sent();
|
||||
this.transport = undefined;
|
||||
_a.label = 6;
|
||||
case 6: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
HttpConnection.prototype.startInternal = function (transferFormat) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var url, negotiateResponse, redirects, _loop_1, this_1, state_1, e_2;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
url = this.baseUrl;
|
||||
this.accessTokenFactory = this.options.accessTokenFactory;
|
||||
this.socketUrlFactory = this.options.socketUrlFactory;
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 12, , 13]);
|
||||
if (!this.options.skipNegotiation) return [3 /*break*/, 5];
|
||||
if (!(this.options.transport === HttpTransportType.WebSockets)) return [3 /*break*/, 3];
|
||||
// No need to add a connection ID in this case
|
||||
this.transport = this.constructTransport(HttpTransportType.WebSockets);
|
||||
// We should just call connect directly in this case.
|
||||
// No fallback or negotiate in this case.
|
||||
return [4 /*yield*/, this.transport.connect({
|
||||
url: url,
|
||||
header: {},
|
||||
protocols: [],
|
||||
tcpNoDelay: true,
|
||||
transferFormat: transferFormat
|
||||
})];
|
||||
case 2:
|
||||
// We should just call connect directly in this case.
|
||||
// No fallback or negotiate in this case.
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3: throw Error("Negotiation can only be skipped when using the WxSocket transport directly.");
|
||||
case 4: return [3 /*break*/, 11];
|
||||
case 5:
|
||||
negotiateResponse = null;
|
||||
redirects = 0;
|
||||
_loop_1 = function () {
|
||||
var accessToken_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this_1.getNegotiationResponse(url)];
|
||||
case 1:
|
||||
negotiateResponse = _a.sent();
|
||||
// the user tries to stop the connection when it is being started
|
||||
if (this_1.connectionState === 2 /* Disconnected */) {
|
||||
return [2 /*return*/, { value: void 0 }];
|
||||
}
|
||||
if (negotiateResponse.error) {
|
||||
throw Error(negotiateResponse.error);
|
||||
}
|
||||
if (negotiateResponse.ProtocolVersion) {
|
||||
throw Error("检测到尝试连接到一个 非 ASP.NET Core 服务器。此客户端仅支持连接到ASP.NET Core 服务器。. See https://aka.ms/signalr-core-differences for details.");
|
||||
}
|
||||
if (negotiateResponse.url) {
|
||||
url = negotiateResponse.url;
|
||||
}
|
||||
if (negotiateResponse.accessToken) {
|
||||
accessToken_1 = negotiateResponse.accessToken;
|
||||
// ! 通过 /negotiate 接口返回的assessToken 仅支持 accessTokenFactory(),如果实现了 socketUrlFactory(),会忽略掉这个token
|
||||
this_1.accessTokenFactory = function () { return accessToken_1; };
|
||||
}
|
||||
redirects++;
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
};
|
||||
this_1 = this;
|
||||
_a.label = 6;
|
||||
case 6: return [5 /*yield**/, _loop_1()];
|
||||
case 7:
|
||||
state_1 = _a.sent();
|
||||
if (typeof state_1 === "object")
|
||||
return [2 /*return*/, state_1.value];
|
||||
_a.label = 8;
|
||||
case 8:
|
||||
if (negotiateResponse.url && redirects < MAX_REDIRECTS) return [3 /*break*/, 6];
|
||||
_a.label = 9;
|
||||
case 9:
|
||||
if (redirects === MAX_REDIRECTS && negotiateResponse.url) {
|
||||
throw Error("Negotiate redirection limit exceeded. -fy : 超出协商重定向限制");
|
||||
}
|
||||
return [4 /*yield*/, this.createTransport(url, this.options.transport, negotiateResponse, transferFormat)];
|
||||
case 10:
|
||||
_a.sent();
|
||||
_a.label = 11;
|
||||
case 11:
|
||||
if (this.transport instanceof LongPollingTransport) {
|
||||
this.features.inherentKeepAlive = true;
|
||||
}
|
||||
this.transport.onreceive = this.onreceive;
|
||||
this.transport.onclose = function (e) { return _this.stopConnection(e); };
|
||||
// only change the state if we were connecting to not overwrite
|
||||
// the state if the connection is already marked as Disconnected
|
||||
this.changeState(0 /* Connecting */, 1 /* Connected */);
|
||||
return [2 /*return*/];
|
||||
case 12:
|
||||
e_2 = _a.sent();
|
||||
this.logger.log(LogLevel.Error, "Failed to start the connection: ", e_2);
|
||||
this.connectionState = 2 /* Disconnected */;
|
||||
this.transport = undefined;
|
||||
throw e_2;
|
||||
case 13: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
HttpConnection.prototype.getNegotiationResponse = function (url) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var headers, token, negotiateUrl, response, e_3;
|
||||
var _a;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
if (!this.accessTokenFactory) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, this.accessTokenFactory()];
|
||||
case 1:
|
||||
token = _b.sent();
|
||||
if (token) {
|
||||
headers = (_a = {},
|
||||
_a["Authorization"] = "Bearer " + token,
|
||||
_a);
|
||||
}
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
negotiateUrl = this.resolveNegotiateUrl(url);
|
||||
this.logger.log(LogLevel.Debug, "Sending negotiation request: " + negotiateUrl + ".");
|
||||
_b.label = 3;
|
||||
case 3:
|
||||
_b.trys.push([3, 5, , 6]);
|
||||
return [4 /*yield*/, this.request.post(negotiateUrl, {}, {
|
||||
headers: headers,
|
||||
responseType: ResponseType.TEXT
|
||||
})];
|
||||
case 4:
|
||||
response = _b.sent();
|
||||
if (response.statusCode !== 200) {
|
||||
throw Error("Unexpected status code returned from negotiate " + response.statusCode);
|
||||
}
|
||||
return [2 /*return*/, JSON.parse(response.data)];
|
||||
case 5:
|
||||
e_3 = _b.sent();
|
||||
this.logger.log(LogLevel.Error, "Failed to complete negotiation with the server: ", e_3);
|
||||
throw e_3;
|
||||
case 6: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
HttpConnection.prototype.createConnectUrl = function (url, connectionId) {
|
||||
if (!connectionId) {
|
||||
return url;
|
||||
}
|
||||
return url + (url.indexOf("?") === -1 ? "?" : "&") + ("id=" + connectionId);
|
||||
};
|
||||
HttpConnection.prototype.createTransport = function (url, requestedTransport, negotiateResponse, requestedTransferFormat) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var connectUrl, transports, _i, transports_1, endpoint, transport, ex_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
connectUrl = this.createConnectUrl(url, negotiateResponse.connectionId);
|
||||
if (!this.isITransport(requestedTransport)) return [3 /*break*/, 2];
|
||||
this.logger.log(LogLevel.Debug, "Connection was provided an instance of ITransport, using that directly.");
|
||||
this.transport = requestedTransport;
|
||||
return [4 /*yield*/, this.transport.connect({
|
||||
url: connectUrl,
|
||||
transferFormat: requestedTransferFormat
|
||||
})];
|
||||
case 1:
|
||||
_a.sent();
|
||||
// only change the state if we were connecting to not overwrite
|
||||
// the state if the connection is already marked as Disconnected
|
||||
this.changeState(0 /* Connecting */, 1 /* Connected */);
|
||||
return [2 /*return*/];
|
||||
case 2:
|
||||
transports = negotiateResponse.availableTransports || [];
|
||||
_i = 0, transports_1 = transports;
|
||||
_a.label = 3;
|
||||
case 3:
|
||||
if (!(_i < transports_1.length)) return [3 /*break*/, 9];
|
||||
endpoint = transports_1[_i];
|
||||
this.connectionState = 0 /* Connecting */;
|
||||
transport = this.resolveTransport(endpoint, requestedTransport, requestedTransferFormat);
|
||||
if (!(typeof transport === "number")) return [3 /*break*/, 8];
|
||||
this.transport = this.constructTransport(transport);
|
||||
if (!!negotiateResponse.connectionId) return [3 /*break*/, 5];
|
||||
return [4 /*yield*/, this.getNegotiationResponse(url)];
|
||||
case 4:
|
||||
negotiateResponse = _a.sent();
|
||||
connectUrl = this.createConnectUrl(url, negotiateResponse.connectionId);
|
||||
_a.label = 5;
|
||||
case 5:
|
||||
_a.trys.push([5, 7, , 8]);
|
||||
return [4 /*yield*/, this.transport.connect({
|
||||
url: connectUrl,
|
||||
transferFormat: requestedTransferFormat
|
||||
})];
|
||||
case 6:
|
||||
_a.sent();
|
||||
this.changeState(0 /* Connecting */, 1 /* Connected */);
|
||||
return [2 /*return*/];
|
||||
case 7:
|
||||
ex_1 = _a.sent();
|
||||
this.logger.log(LogLevel.Error, "Failed to start the transport '" + HttpTransportType[transport] + "':", ex_1);
|
||||
this.connectionState = 2 /* Disconnected */;
|
||||
negotiateResponse.connectionId = undefined;
|
||||
return [3 /*break*/, 8];
|
||||
case 8:
|
||||
_i++;
|
||||
return [3 /*break*/, 3];
|
||||
case 9: throw new Error("Unable to initialize any of the available transports.");
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @description 这里对原来的实例化方式进行了改写,如果传入的是实例化完成的 Transport ,将直接返回
|
||||
* 如果是传入继承 Transport的 class,将执行 new Transport(options)
|
||||
* - 这里对原生的多项入参合并成了options(这点差异需要注意)
|
||||
* @private
|
||||
* @param {HttpTransportType} transport
|
||||
* @returns
|
||||
* @memberof HttpConnection
|
||||
*/
|
||||
HttpConnection.prototype.constructTransport = function (transport) {
|
||||
var _a = this.options, WxSocket = _a.WxSocket, LongPolling = _a.LongPolling, wxSocketTransportOptions = _a.wxSocketTransportOptions, longPollingTransportOptions = _a.longPollingTransportOptions;
|
||||
switch (transport) {
|
||||
case HttpTransportType.WebSockets: // wx socket 方式
|
||||
if (WxSocket instanceof WxSocketTransport) {
|
||||
return WxSocket;
|
||||
}
|
||||
else {
|
||||
return new WxSocket(wxSocketTransportOptions
|
||||
? wxSocketTransportOptions
|
||||
: {
|
||||
// token 工厂
|
||||
accessTokenFactory: this.accessTokenFactory,
|
||||
// socket 单独实现一个socket url factory(用于后端改了 accecc_token 参数名的场景)
|
||||
socketUrlFactory: this.socketUrlFactory,
|
||||
// logger
|
||||
logger: this.logger,
|
||||
logMessageContent: this.options.logMessageContent || false,
|
||||
/** 是否允许替换socket连接
|
||||
*
|
||||
* 小程序 版本 < 1.7.0 时, 最多允许存在一个socket连接, 此参数用于是否允许在这个情况下,替换这个打开的socket
|
||||
*/
|
||||
allowReplaceSocket: true,
|
||||
/** 是否启用消息队列缓存连接建立前消息,并在建立连接后发送 */
|
||||
enableMessageQueue: this.options.enableMessageQueue == undefined ? true : this.options.enableMessageQueue,
|
||||
/** 重连设置 */
|
||||
reconnect: {
|
||||
enable: true,
|
||||
max: 3
|
||||
}
|
||||
});
|
||||
}
|
||||
case HttpTransportType.LongPolling: // 长轮询方式
|
||||
if (LongPolling instanceof LongPollingTransport) {
|
||||
return LongPolling;
|
||||
}
|
||||
else {
|
||||
return new LongPolling(longPollingTransportOptions
|
||||
? longPollingTransportOptions
|
||||
: {
|
||||
request: this.request,
|
||||
accessTokenFactory: this.accessTokenFactory,
|
||||
logger: this.logger,
|
||||
logMessageContent: this.options.logMessageContent || false
|
||||
});
|
||||
}
|
||||
default:
|
||||
throw new Error("Unknown transport: " + transport + ".");
|
||||
}
|
||||
};
|
||||
HttpConnection.prototype.resolveTransport = function (endpoint, requestedTransport, requestedTransferFormat) {
|
||||
var transport = HttpTransportType[endpoint.transport];
|
||||
if (transport === null || transport === undefined) {
|
||||
this.logger.log(LogLevel.Debug, "Skipping transport '" + endpoint.transport + "' because it is not supported by this client.");
|
||||
}
|
||||
else {
|
||||
var transferFormats = endpoint.transferFormats.map(function (s) { return TransferFormat[s]; });
|
||||
if (transportMatches(requestedTransport, transport)) {
|
||||
if (transferFormats.indexOf(requestedTransferFormat) >= 0) {
|
||||
if (transport === HttpTransportType.WebSockets && !this.options.WxSocket) {
|
||||
this.logger.log(LogLevel.Debug, "Skipping transport '" + HttpTransportType[transport] + "' because it is not supported in your environment.'");
|
||||
}
|
||||
else {
|
||||
this.logger.log(LogLevel.Debug, "Selecting transport '" + HttpTransportType[transport] + "'.");
|
||||
return transport;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.log(LogLevel.Debug, "Skipping transport '" + HttpTransportType[transport] + "' because it does not support the requested transfer format '" + TransferFormat[requestedTransferFormat] + "'.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.log(LogLevel.Debug, "Skipping transport '" + HttpTransportType[transport] + "' because it was disabled by the client.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
HttpConnection.prototype.isITransport = function (transport) {
|
||||
return transport && typeof transport === "object" && "connect" in transport;
|
||||
};
|
||||
HttpConnection.prototype.changeState = function (from, to) {
|
||||
if (this.connectionState === from) {
|
||||
this.connectionState = to;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
HttpConnection.prototype.stopConnection = function (error) {
|
||||
this.transport = undefined;
|
||||
// If we have a stopError, it takes precedence over the error from the transport
|
||||
error = this.stopError || error;
|
||||
if (error) {
|
||||
this.logger.log(LogLevel.Error, "Connection disconnected with error '" + error + "'.");
|
||||
}
|
||||
else {
|
||||
this.logger.log(LogLevel.Information, "Connection disconnected.");
|
||||
}
|
||||
this.connectionState = 2 /* Disconnected */;
|
||||
if (this.onclose) {
|
||||
this.onclose(error);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* ! 由于小程序内必须指定 BaseUrl 关系,这里如果不是全路径的话,暂时直接抛出异常
|
||||
* @param url
|
||||
*/
|
||||
HttpConnection.prototype.resolveUrl = function (url) {
|
||||
// startsWith is not supported in IE
|
||||
if (url.lastIndexOf("https://", 0) === 0 || url.lastIndexOf("http://", 0) === 0) {
|
||||
return url;
|
||||
}
|
||||
else {
|
||||
throw new Error("HttpConnection. \u89E3\u6790url\u9519\u8BEF,\u5C0F\u7A0B\u5E8F\u5185\u9700\u8981\u4F20\u5165\u5168\u8DEF\u5F84 ->link: " + url);
|
||||
}
|
||||
};
|
||||
HttpConnection.prototype.resolveNegotiateUrl = function (url) {
|
||||
var index = url.indexOf("?");
|
||||
var negotiateUrl = url.substring(0, index === -1 ? url.length : index);
|
||||
if (negotiateUrl[negotiateUrl.length - 1] !== "/") {
|
||||
negotiateUrl += "/";
|
||||
}
|
||||
negotiateUrl += "negotiate";
|
||||
negotiateUrl += index === -1 ? "" : url.substring(index);
|
||||
return negotiateUrl;
|
||||
};
|
||||
return HttpConnection;
|
||||
}());
|
||||
export { HttpConnection };
|
||||
function transportMatches(requestedTransport, actualTransport) {
|
||||
return !requestedTransport || (actualTransport & requestedTransport) !== 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,546 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
import { HandshakeProtocol } from "./HandshakeProtocol";
|
||||
import { MessageType } from "./IHubProtocol";
|
||||
import { LogLevel } from "./ILogger";
|
||||
import { Arg, Subject } from "./Utils";
|
||||
import { EventNotFoundError } from "./Errors";
|
||||
var DEFAULT_TIMEOUT_IN_MS = 30 * 1000;
|
||||
var DEFAULT_PING_INTERVAL_IN_MS = 15 * 1000;
|
||||
/** Describes the current state of the {@link HubConnection} to the server. */
|
||||
export var HubConnectionState;
|
||||
(function (HubConnectionState) {
|
||||
/** The hub connection is disconnected. */
|
||||
HubConnectionState[HubConnectionState["Disconnected"] = 0] = "Disconnected";
|
||||
/** The hub connection is connected. */
|
||||
HubConnectionState[HubConnectionState["Connected"] = 1] = "Connected";
|
||||
})(HubConnectionState || (HubConnectionState = {}));
|
||||
/** Represents a connection to a SignalR Hub. */
|
||||
var HubConnection = /** @class */ (function () {
|
||||
function HubConnection(connection, logger, protocol) {
|
||||
var _this = this;
|
||||
Arg.isRequired(connection, "connection");
|
||||
Arg.isRequired(logger, "logger");
|
||||
Arg.isRequired(protocol, "protocol");
|
||||
this.serverTimeoutInMilliseconds = DEFAULT_TIMEOUT_IN_MS;
|
||||
this.keepAliveIntervalInMilliseconds = DEFAULT_PING_INTERVAL_IN_MS;
|
||||
this.logger = logger;
|
||||
this.protocol = protocol;
|
||||
this.connection = connection;
|
||||
this.handshakeProtocol = new HandshakeProtocol();
|
||||
this.connection.onreceive = function (data) { return _this.processIncomingData(data); };
|
||||
this.connection.onclose = function (error) { return _this.connectionClosed(error); };
|
||||
this.callbacks = {};
|
||||
this.methods = {};
|
||||
this.closedCallbacks = [];
|
||||
this.id = 0;
|
||||
this.receivedHandshakeResponse = false;
|
||||
this.connectionState = HubConnectionState.Disconnected;
|
||||
this.cachedPingMessage = this.protocol.writeMessage({ type: MessageType.Ping });
|
||||
}
|
||||
/** @internal */
|
||||
// Using a public static factory method means we can have a private constructor and an _internal_
|
||||
// create method that can be used by HubConnectionBuilder. An "internal" constructor would just
|
||||
// be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a
|
||||
// public parameter-less constructor.
|
||||
HubConnection.create = function (connection, logger, protocol) {
|
||||
return new HubConnection(connection, logger, protocol);
|
||||
};
|
||||
Object.defineProperty(HubConnection.prototype, "state", {
|
||||
/** Indicates the state of the {@link HubConnection} to the server. */
|
||||
get: function () {
|
||||
return this.connectionState;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
/** Starts the connection.
|
||||
*
|
||||
* @returns {Promise<void>} A Promise that resolves when the connection has been successfully established, or rejects with an error.
|
||||
*/
|
||||
HubConnection.prototype.start = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var handshakeRequest, handshakePromise;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
handshakeRequest = {
|
||||
protocol: this.protocol.name,
|
||||
version: this.protocol.version
|
||||
};
|
||||
this.logger.log(LogLevel.Debug, "Starting HubConnection.");
|
||||
this.receivedHandshakeResponse = false;
|
||||
handshakePromise = new Promise(function (resolve, reject) {
|
||||
_this.handshakeResolver = resolve;
|
||||
_this.handshakeRejecter = reject;
|
||||
});
|
||||
return [4 /*yield*/, this.connection.start(this.protocol.transferFormat)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
this.logger.log(LogLevel.Debug, "Sending handshake request.");
|
||||
return [4 /*yield*/, this.sendMessage(this.handshakeProtocol.writeHandshakeRequest(handshakeRequest))];
|
||||
case 2:
|
||||
_a.sent();
|
||||
this.logger.log(LogLevel.Information, "Using HubProtocol '" + this.protocol.name + "'.", this.protocol);
|
||||
// defensively cleanup timeout in case we receive a message from the server before we finish start
|
||||
this.cleanupTimeout();
|
||||
this.resetTimeoutPeriod();
|
||||
this.resetKeepAliveInterval();
|
||||
// Wait for the handshake to complete before marking connection as connected
|
||||
return [4 /*yield*/, handshakePromise];
|
||||
case 3:
|
||||
// Wait for the handshake to complete before marking connection as connected
|
||||
_a.sent();
|
||||
this.connectionState = HubConnectionState.Connected;
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Stops the connection.
|
||||
*
|
||||
* @returns {Promise<void>} A Promise that resolves when the connection has been successfully terminated, or rejects with an error.
|
||||
*/
|
||||
HubConnection.prototype.stop = function () {
|
||||
this.logger.log(LogLevel.Debug, "Stopping HubConnection.");
|
||||
this.cleanupTimeout();
|
||||
this.cleanupPingTimer();
|
||||
return this.connection.stop();
|
||||
};
|
||||
/** Invokes a streaming hub method on the server using the specified name and arguments.
|
||||
*
|
||||
* @typeparam T The type of the items returned by the server.
|
||||
* @param {string} methodName The name of the server method to invoke.
|
||||
* @param {any[]} args The arguments used to invoke the server method.
|
||||
* @returns {IStreamResult<T>} An object that yields results from the server as they are received.
|
||||
*/
|
||||
HubConnection.prototype.stream = function (methodName) {
|
||||
var _this = this;
|
||||
var args = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
args[_i - 1] = arguments[_i];
|
||||
}
|
||||
var invocationDescriptor = this.createStreamInvocation(methodName, args);
|
||||
var subject = new Subject(function () {
|
||||
var cancelInvocation = _this.createCancelInvocation(invocationDescriptor.invocationId);
|
||||
var cancelMessage = _this.protocol.writeMessage(cancelInvocation);
|
||||
delete _this.callbacks[invocationDescriptor.invocationId];
|
||||
return _this.sendMessage(cancelMessage);
|
||||
});
|
||||
this.callbacks[invocationDescriptor.invocationId] = function (invocationEvent, error) {
|
||||
if (error) {
|
||||
subject.error(error);
|
||||
return;
|
||||
}
|
||||
else if (invocationEvent) {
|
||||
// invocationEvent will not be null when an error is not passed to the callback
|
||||
if (invocationEvent.type === MessageType.Completion) {
|
||||
if (invocationEvent.error) {
|
||||
subject.error(new Error(invocationEvent.error));
|
||||
}
|
||||
else {
|
||||
subject.complete();
|
||||
}
|
||||
}
|
||||
else {
|
||||
subject.next(invocationEvent.item);
|
||||
}
|
||||
}
|
||||
};
|
||||
var message = this.protocol.writeMessage(invocationDescriptor);
|
||||
this.sendMessage(message).catch(function (e) {
|
||||
subject.error(e);
|
||||
delete _this.callbacks[invocationDescriptor.invocationId];
|
||||
});
|
||||
return subject;
|
||||
};
|
||||
HubConnection.prototype.sendMessage = function (message) {
|
||||
this.resetKeepAliveInterval();
|
||||
return this.connection.send(message);
|
||||
};
|
||||
/** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver.
|
||||
*
|
||||
* The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still
|
||||
* be processing the invocation.
|
||||
*
|
||||
* @param {string} methodName The name of the server method to invoke.
|
||||
* @param {any[]} args The arguments used to invoke the server method.
|
||||
* @returns {Promise<void>} A Promise that resolves when the invocation has been successfully sent, or rejects with an error.
|
||||
*/
|
||||
HubConnection.prototype.send = function (methodName) {
|
||||
var args = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
args[_i - 1] = arguments[_i];
|
||||
}
|
||||
var invocationDescriptor = this.createInvocation(methodName, args, true);
|
||||
var message = this.protocol.writeMessage(invocationDescriptor);
|
||||
return this.sendMessage(message);
|
||||
};
|
||||
/** Invokes a hub method on the server using the specified name and arguments.
|
||||
*
|
||||
* The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise
|
||||
* resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of
|
||||
* resolving the Promise.
|
||||
*
|
||||
* @typeparam T The expected return type.
|
||||
* @param {string} methodName The name of the server method to invoke.
|
||||
* @param {any[]} args The arguments used to invoke the server method.
|
||||
* @returns {Promise<T>} A Promise that resolves with the result of the server method (if any), or rejects with an error.
|
||||
*/
|
||||
HubConnection.prototype.invoke = function (methodName) {
|
||||
var _this = this;
|
||||
var args = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
args[_i - 1] = arguments[_i];
|
||||
}
|
||||
var invocationDescriptor = this.createInvocation(methodName, args, false);
|
||||
var p = new Promise(function (resolve, reject) {
|
||||
// invocationId will always have a value for a non-blocking invocation
|
||||
_this.callbacks[invocationDescriptor.invocationId] = function (invocationEvent, error) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
else if (invocationEvent) {
|
||||
// invocationEvent will not be null when an error is not passed to the callback
|
||||
if (invocationEvent.type === MessageType.Completion) {
|
||||
if (invocationEvent.error) {
|
||||
reject(new Error(invocationEvent.error));
|
||||
}
|
||||
else {
|
||||
resolve(invocationEvent.result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
reject(new Error("Unexpected message type: " + invocationEvent.type));
|
||||
}
|
||||
}
|
||||
};
|
||||
var message = _this.protocol.writeMessage(invocationDescriptor);
|
||||
_this.sendMessage(message).catch(function (e) {
|
||||
reject(e);
|
||||
// invocationId will always have a value for a non-blocking invocation
|
||||
delete _this.callbacks[invocationDescriptor.invocationId];
|
||||
});
|
||||
});
|
||||
return p;
|
||||
};
|
||||
HubConnection.prototype.on = function (methodName, newMethod, only) {
|
||||
if (!methodName || !newMethod) {
|
||||
return;
|
||||
}
|
||||
methodName = methodName.toLowerCase();
|
||||
if (only) {
|
||||
this.methods[methodName] = [newMethod];
|
||||
return;
|
||||
}
|
||||
if (!this.methods[methodName]) {
|
||||
this.methods[methodName] = [];
|
||||
}
|
||||
// Preventing adding the same handler multiple times.
|
||||
if (this.methods[methodName].indexOf(newMethod) !== -1) {
|
||||
return;
|
||||
}
|
||||
this.methods[methodName].push(newMethod);
|
||||
};
|
||||
HubConnection.prototype.off = function (methodName, method) {
|
||||
if (!methodName) {
|
||||
return;
|
||||
}
|
||||
methodName = methodName.toLowerCase();
|
||||
var handlers = this.methods[methodName];
|
||||
if (!handlers) {
|
||||
return;
|
||||
}
|
||||
if (method) {
|
||||
var removeIdx = handlers.indexOf(method);
|
||||
if (removeIdx !== -1) {
|
||||
handlers.splice(removeIdx, 1);
|
||||
if (handlers.length === 0) {
|
||||
delete this.methods[methodName];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
delete this.methods[methodName];
|
||||
}
|
||||
};
|
||||
/** Registers a handler that will be invoked when the connection is closed.
|
||||
*
|
||||
* @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any).
|
||||
*/
|
||||
HubConnection.prototype.onclose = function (callback) {
|
||||
if (callback) {
|
||||
this.closedCallbacks.push(callback);
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.onEventNotFound = function (callback) {
|
||||
if (callback) {
|
||||
this.eventNotFoundCallback = callback;
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.processIncomingData = function (data) {
|
||||
this.cleanupTimeout();
|
||||
if (!this.receivedHandshakeResponse) {
|
||||
data = this.processHandshakeResponse(data);
|
||||
this.receivedHandshakeResponse = true;
|
||||
}
|
||||
// Data may have all been read when processing handshake response
|
||||
if (data) {
|
||||
// Parse the messages
|
||||
var messages = this.protocol.parseMessages(data, this.logger);
|
||||
for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) {
|
||||
var message = messages_1[_i];
|
||||
switch (message.type) {
|
||||
case MessageType.Invocation:
|
||||
this.invokeClientMethod(message);
|
||||
break;
|
||||
case MessageType.StreamItem:
|
||||
case MessageType.Completion:
|
||||
var callback = this.callbacks[message.invocationId];
|
||||
if (callback != null) {
|
||||
if (message.type === MessageType.Completion) {
|
||||
delete this.callbacks[message.invocationId];
|
||||
}
|
||||
callback(message);
|
||||
}
|
||||
break;
|
||||
case MessageType.Ping:
|
||||
// Don't care about pings
|
||||
break;
|
||||
case MessageType.Close:
|
||||
this.logger.log(LogLevel.Information, "Close message received from server.");
|
||||
// We don't want to wait on the stop itself.
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.connection.stop(message.error ? new Error("Server returned an error on close: " + message.error) : undefined);
|
||||
break;
|
||||
default:
|
||||
this.logger.log(LogLevel.Warning, "Invalid message type: " + message.type + ".", message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.resetTimeoutPeriod();
|
||||
};
|
||||
HubConnection.prototype.processHandshakeResponse = function (data) {
|
||||
var _a;
|
||||
var responseMessage;
|
||||
var remainingData;
|
||||
try {
|
||||
_a = this.handshakeProtocol.parseHandshakeResponse(data), remainingData = _a[0], responseMessage = _a[1];
|
||||
}
|
||||
catch (e) {
|
||||
var message = "Error parsing handshake response: " + e;
|
||||
this.logger.log(LogLevel.Error, message);
|
||||
var error = new Error(message);
|
||||
// We don't want to wait on the stop itself.
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.connection.stop(error);
|
||||
this.handshakeRejecter(error);
|
||||
throw error;
|
||||
}
|
||||
if (responseMessage.error) {
|
||||
var message = "Server returned handshake error: " + responseMessage.error;
|
||||
this.logger.log(LogLevel.Error, message);
|
||||
this.handshakeRejecter(message);
|
||||
// We don't want to wait on the stop itself.
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.connection.stop(new Error(message));
|
||||
throw new Error(message);
|
||||
}
|
||||
else {
|
||||
this.logger.log(LogLevel.Debug, "Server handshake complete.");
|
||||
}
|
||||
this.handshakeResolver();
|
||||
return remainingData;
|
||||
};
|
||||
HubConnection.prototype.resetKeepAliveInterval = function () {
|
||||
var _this = this;
|
||||
this.cleanupPingTimer();
|
||||
this.pingServerHandle = setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var _a;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
if (!(this.connectionState === HubConnectionState.Connected)) return [3 /*break*/, 4];
|
||||
_b.label = 1;
|
||||
case 1:
|
||||
_b.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, this.sendMessage(this.cachedPingMessage)];
|
||||
case 2:
|
||||
_b.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
_a = _b.sent();
|
||||
// We don't care about the error. It should be seen elsewhere in the client.
|
||||
// The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering
|
||||
this.cleanupPingTimer();
|
||||
return [3 /*break*/, 4];
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); }, this.keepAliveIntervalInMilliseconds);
|
||||
};
|
||||
HubConnection.prototype.resetTimeoutPeriod = function () {
|
||||
var _this = this;
|
||||
if (!this.connection.features || !this.connection.features.inherentKeepAlive) {
|
||||
// Set the timeout timer
|
||||
this.timeoutHandle = setTimeout(function () { return _this.serverTimeout(); }, this.serverTimeoutInMilliseconds);
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.serverTimeout = function () {
|
||||
// The server hasn't talked to us in a while. It doesn't like us anymore ... :(
|
||||
// Terminate the connection, but we don't need to wait on the promise.
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."));
|
||||
};
|
||||
HubConnection.prototype.invokeClientMethod = function (invocationMessage) {
|
||||
var _this = this;
|
||||
var methods = this.methods[invocationMessage.target.toLowerCase()];
|
||||
if (methods) {
|
||||
try {
|
||||
// Time:2020年1月1日 22:30:30 增加一个 try cache, 获取 signalr 在特定场景下,处理事件失败会关闭问题.
|
||||
methods.forEach(function (m) { return m.apply(_this, invocationMessage.arguments); });
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
if (invocationMessage.invocationId) {
|
||||
// This is not supported in v1. So we return an error to avoid blocking the server waiting for the response.
|
||||
var message = "Server requested a response, which is not supported in this version of the client.";
|
||||
this.logger.log(LogLevel.Error, message);
|
||||
// We don't need to wait on this Promise.
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this.connection.stop(new Error(message));
|
||||
}
|
||||
}
|
||||
else {
|
||||
var message = "No client method with the name '" + invocationMessage.target + "' found.";
|
||||
this.logger.log(LogLevel.Warning, message);
|
||||
this.logger.log(LogLevel.Information, "Current Event Methods:" + Object.keys(this.methods));
|
||||
this.eventNotFound(new EventNotFoundError(invocationMessage, message));
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.connectionClosed = function (error) {
|
||||
var _this = this;
|
||||
var callbacks = this.callbacks;
|
||||
this.callbacks = {};
|
||||
this.connectionState = HubConnectionState.Disconnected;
|
||||
// if handshake is in progress start will be waiting for the handshake promise, so we complete it
|
||||
// if it has already completed this should just noop
|
||||
if (this.handshakeRejecter) {
|
||||
this.handshakeRejecter(error);
|
||||
}
|
||||
Object.keys(callbacks).forEach(function (key) {
|
||||
var callback = callbacks[key];
|
||||
callback(null, error ? error : new Error("Invocation canceled due to connection being closed."));
|
||||
});
|
||||
this.cleanupTimeout();
|
||||
this.cleanupPingTimer();
|
||||
this.closedCallbacks.forEach(function (c) { return c.apply(_this, [error]); });
|
||||
};
|
||||
HubConnection.prototype.eventNotFound = function (error) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var r;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!this.eventNotFoundCallback) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, this.eventNotFoundCallback(error)];
|
||||
case 1:
|
||||
r = _a.sent();
|
||||
if (r === true) {
|
||||
this.logger.log(LogLevel.Information, "retry invoke local message callback.");
|
||||
this.invokeClientMethod(error.invocationMessage);
|
||||
}
|
||||
_a.label = 2;
|
||||
case 2: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
HubConnection.prototype.cleanupPingTimer = function () {
|
||||
if (this.pingServerHandle) {
|
||||
clearTimeout(this.pingServerHandle);
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.cleanupTimeout = function () {
|
||||
if (this.timeoutHandle) {
|
||||
clearTimeout(this.timeoutHandle);
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.createInvocation = function (methodName, args, nonblocking) {
|
||||
if (nonblocking) {
|
||||
return {
|
||||
arguments: args,
|
||||
target: methodName,
|
||||
type: MessageType.Invocation
|
||||
};
|
||||
}
|
||||
else {
|
||||
var id = this.id;
|
||||
this.id++;
|
||||
return {
|
||||
arguments: args,
|
||||
invocationId: id.toString(),
|
||||
target: methodName,
|
||||
type: MessageType.Invocation
|
||||
};
|
||||
}
|
||||
};
|
||||
HubConnection.prototype.createStreamInvocation = function (methodName, args) {
|
||||
var id = this.id;
|
||||
this.id++;
|
||||
return {
|
||||
arguments: args,
|
||||
invocationId: id.toString(),
|
||||
target: methodName,
|
||||
type: MessageType.StreamInvocation
|
||||
};
|
||||
};
|
||||
HubConnection.prototype.createCancelInvocation = function (id) {
|
||||
return {
|
||||
invocationId: id,
|
||||
type: MessageType.CancelInvocation
|
||||
};
|
||||
};
|
||||
return HubConnection;
|
||||
}());
|
||||
export { HubConnection };
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
import { HttpConnection } from "./HttpConnection";
|
||||
import { HubConnection } from "./HubConnection";
|
||||
import { JsonHubProtocol } from "./JsonHubProtocol";
|
||||
import { NullLogger } from "./Loggers";
|
||||
import { Arg, ConsoleLogger } from "./Utils";
|
||||
/** A builder for configuring {@link @aspnet/signalr.HubConnection} instances. */
|
||||
var HubConnectionBuilder = /** @class */ (function () {
|
||||
function HubConnectionBuilder() {
|
||||
}
|
||||
HubConnectionBuilder.prototype.configureLogging = function (logging) {
|
||||
Arg.isRequired(logging, "logging");
|
||||
if (isLogger(logging)) {
|
||||
this.logger = logging;
|
||||
}
|
||||
else {
|
||||
this.logger = new ConsoleLogger(logging);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
HubConnectionBuilder.prototype.withUrl = function (url, transportTypeOrOptions) {
|
||||
Arg.isRequired(url, "url");
|
||||
this.url = url;
|
||||
// Flow-typing knows where it's at. Since HttpTransportType is a number and IHttpConnectionOptions is guaranteed
|
||||
// to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called.
|
||||
if (typeof transportTypeOrOptions === "object") {
|
||||
this.httpConnectionOptions = transportTypeOrOptions;
|
||||
}
|
||||
else {
|
||||
this.httpConnectionOptions = {
|
||||
transport: transportTypeOrOptions,
|
||||
};
|
||||
}
|
||||
return this;
|
||||
};
|
||||
/** Configures the {@link @aspnet/signalr.HubConnection} to use the specified Hub Protocol.
|
||||
*
|
||||
* @param {IHubProtocol} protocol The {@link @aspnet/signalr.IHubProtocol} implementation to use.
|
||||
*/
|
||||
HubConnectionBuilder.prototype.withHubProtocol = function (protocol) {
|
||||
Arg.isRequired(protocol, "protocol");
|
||||
this.protocol = protocol;
|
||||
return this;
|
||||
};
|
||||
/** Creates a {@link @aspnet/signalr.HubConnection} from the configuration options specified in this builder.
|
||||
*
|
||||
* @returns {HubConnection} The configured {@link @aspnet/signalr.HubConnection}.
|
||||
*/
|
||||
HubConnectionBuilder.prototype.build = function () {
|
||||
// If httpConnectionOptions has a logger, use it. Otherwise, override it with the one
|
||||
// provided to configureLogger
|
||||
var httpConnectionOptions = this.httpConnectionOptions || {};
|
||||
// If it's 'null', the user **explicitly** asked for null, don't mess with it.
|
||||
if (httpConnectionOptions.logger === undefined) {
|
||||
// If our logger is undefined or null, that's OK, the HttpConnection constructor will handle it.
|
||||
httpConnectionOptions.logger = this.logger;
|
||||
}
|
||||
// Now create the connection
|
||||
if (!this.url) {
|
||||
throw new Error("The 'HubConnectionBuilder.withUrl' method must be called before building the connection.");
|
||||
}
|
||||
var connection = new HttpConnection(this.url, httpConnectionOptions);
|
||||
return HubConnection.create(connection, this.logger || NullLogger.instance, this.protocol || new JsonHubProtocol());
|
||||
};
|
||||
return HubConnectionBuilder;
|
||||
}());
|
||||
export { HubConnectionBuilder };
|
||||
function isLogger(logger) {
|
||||
return logger.log !== undefined;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
/* 定义消息的类型[枚举] */
|
||||
export var MessageType;
|
||||
(function (MessageType) {
|
||||
/**
|
||||
* - 指示消息是一个 `调用消息` 并实现 {@link @aspnet/signalr.InvocationMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["Invocation"] = 1] = "Invocation";
|
||||
/**
|
||||
* - 指示消息是一个 `流消息` 并实现 {@link @aspnet/signalr.StreamItemMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["StreamItem"] = 2] = "StreamItem";
|
||||
/**
|
||||
* - 指示消息是一个 `完成消息` 并实现 {@link @aspnet/signalr.CompletionMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["Completion"] = 3] = "Completion";
|
||||
/**
|
||||
* - 指示消息是一个 `流调用消息` 并实现 {@link @aspnet/signalr.StreamInvocationMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["StreamInvocation"] = 4] = "StreamInvocation";
|
||||
/**
|
||||
* - 指示消息是一个 `取消调用消息` 并实现 {@link @aspnet/signalr.CancelInvocationMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["CancelInvocation"] = 5] = "CancelInvocation";
|
||||
/**
|
||||
* - 指示消息是一个 `Ping消息` 并实现 {@link @aspnet/signalr.PingMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["Ping"] = 6] = "Ping";
|
||||
/**
|
||||
* - 指示消息是一个 `关闭消息` 并实现 {@link @aspnet/signalr.CloseMessage} 接口。
|
||||
*/
|
||||
MessageType[MessageType["Close"] = 7] = "Close";
|
||||
})(MessageType || (MessageType = {}));
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
//这些值被设计为与ASP.NET日志级别匹配,因为这是我们在这里模拟的模式。
|
||||
/**
|
||||
* 指示日志消息的严重性。
|
||||
* 日志级别按严重性递增的顺序排列。所以“Debug”比“Trace”等更严重。
|
||||
*
|
||||
*/
|
||||
export var LogLevel;
|
||||
(function (LogLevel) {
|
||||
/** 极低严重性诊断消息的日志级别. */
|
||||
LogLevel[LogLevel["Trace"] = 0] = "Trace";
|
||||
/** 调试错误. */
|
||||
LogLevel[LogLevel["Debug"] = 1] = "Debug";
|
||||
/** 消息. */
|
||||
LogLevel[LogLevel["Information"] = 2] = "Information";
|
||||
/** 警告. */
|
||||
LogLevel[LogLevel["Warning"] = 3] = "Warning";
|
||||
/** 错误. */
|
||||
LogLevel[LogLevel["Error"] = 4] = "Error";
|
||||
/** 严重错误. */
|
||||
LogLevel[LogLevel["Critical"] = 5] = "Critical";
|
||||
/** 最高日志级别。在配置日志记录以指示不应发出日志消息时使用. */
|
||||
LogLevel[LogLevel["None"] = 6] = "None";
|
||||
})(LogLevel || (LogLevel = {}));
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
//这在将来会被当作一个位标志,所以我们使用两个值的幂来保持它。
|
||||
/**指定特定的HTTP传输类型。*/
|
||||
export var HttpTransportType;
|
||||
(function (HttpTransportType) {
|
||||
/**未指定传输首选项。*/
|
||||
HttpTransportType[HttpTransportType["None"] = 0] = "None";
|
||||
/**指定WebSocket传输。*/
|
||||
HttpTransportType[HttpTransportType["WebSockets"] = 1] = "WebSockets";
|
||||
/**指定长轮询传输。*/
|
||||
HttpTransportType[HttpTransportType["LongPolling"] = 4] = "LongPolling";
|
||||
})(HttpTransportType || (HttpTransportType = {}));
|
||||
/**指定连接的传输格式。*/
|
||||
export var TransferFormat;
|
||||
(function (TransferFormat) {
|
||||
/**指定仅通过连接传输文本数据。*/
|
||||
TransferFormat[TransferFormat["Text"] = 1] = "Text";
|
||||
/**指定将通过连接传输二进制数据。*/
|
||||
TransferFormat[TransferFormat["Binary"] = 2] = "Binary";
|
||||
})(TransferFormat || (TransferFormat = {}));
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
import { MessageType } from "./IHubProtocol";
|
||||
import { LogLevel } from "./ILogger";
|
||||
import { TransferFormat } from "./ITransport";
|
||||
import { NullLogger } from "./Loggers";
|
||||
import { TextMessageFormat } from "./TextMessageFormat";
|
||||
var JSON_HUB_PROTOCOL_NAME = "json";
|
||||
/** Implements the JSON Hub Protocol. */
|
||||
var JsonHubProtocol = /** @class */ (function () {
|
||||
function JsonHubProtocol() {
|
||||
/** @inheritDoc */
|
||||
this.name = JSON_HUB_PROTOCOL_NAME;
|
||||
/** @inheritDoc */
|
||||
this.version = 1;
|
||||
/** @inheritDoc */
|
||||
this.transferFormat = TransferFormat.Text;
|
||||
}
|
||||
/**
|
||||
* Creates an array of {@link @aspnet/signalr.HubMessage} objects from the specified serialized representation.
|
||||
* 从指定的序列化表示创建{@link@aspnet/signaler.HubMessage}对象数组
|
||||
*
|
||||
* @param {string} input 包含序列化表示的字符串 A string containing the serialized representation.
|
||||
* @param {ILogger} logger
|
||||
*/
|
||||
JsonHubProtocol.prototype.parseMessages = function (input, logger) {
|
||||
// 接口允许传入“ArrayBuffer”,但此实现不允许。所以让我们抛出一个有用的错误
|
||||
if (typeof input !== "string") {
|
||||
throw new Error("Invalid input for JSON hub protocol. Expected a string. (fy:包含一个无效的JSON协议输入,但是这里需要输入string 消息)");
|
||||
}
|
||||
// fixed
|
||||
if (!input) {
|
||||
return [];
|
||||
}
|
||||
// fixed
|
||||
if (logger === null) {
|
||||
logger = NullLogger.instance;
|
||||
}
|
||||
// string 类型消息格式化转换
|
||||
var messages = TextMessageFormat.parse(input);
|
||||
var hubMessages = [];
|
||||
for (var _i = 0, messages_1 = messages; _i < messages_1.length; _i++) {
|
||||
var message = messages_1[_i];
|
||||
// 转换消息
|
||||
var parsedMessage = JSON.parse(message);
|
||||
if (typeof parsedMessage.type !== "number") {
|
||||
throw new Error("Invalid payload. (fy: 无效的消息)");
|
||||
}
|
||||
switch (parsedMessage.type) {
|
||||
case MessageType.Invocation: // 调用命令
|
||||
this.isInvocationMessage(parsedMessage);
|
||||
break;
|
||||
case MessageType.StreamItem: // 流消息
|
||||
this.isStreamItemMessage(parsedMessage);
|
||||
break;
|
||||
case MessageType.Completion: // 完成消息
|
||||
this.isCompletionMessage(parsedMessage);
|
||||
break;
|
||||
case MessageType.Ping: // ping 命令
|
||||
// Single value, no need to validate
|
||||
break;
|
||||
case MessageType.Close: // 关闭命令
|
||||
// All optional values, no need to validate
|
||||
break;
|
||||
default: // 未定义命令,抛出异常
|
||||
// Future protocol changes can add message types, old clients can ignore them
|
||||
logger.log(LogLevel.Information, "Unknown message type '" + parsedMessage.type + "' ignored.");
|
||||
continue;
|
||||
}
|
||||
hubMessages.push(parsedMessage);
|
||||
}
|
||||
return hubMessages;
|
||||
};
|
||||
/**
|
||||
* Writes the specified {@link @aspnet/signalr.HubMessage} to a string and returns it.
|
||||
* 将指定的{@link@aspnet/signalr.HubMessage}写入字符串并返回
|
||||
*
|
||||
* @param {HubMessage} message The message to write. 消息内容
|
||||
* @returns {string} 包含消息的序列化表示形式的字符串。
|
||||
*/
|
||||
JsonHubProtocol.prototype.writeMessage = function (message) {
|
||||
return TextMessageFormat.write(JSON.stringify(message));
|
||||
};
|
||||
/**
|
||||
* 判断是否是一个正常的调用消息
|
||||
* @param message
|
||||
*/
|
||||
JsonHubProtocol.prototype.isInvocationMessage = function (message) {
|
||||
this.assertNotEmptyString(message.target, "Invalid payload for Invocation message.");
|
||||
if (message.invocationId !== undefined) {
|
||||
this.assertNotEmptyString(message.invocationId, "Invalid payload for Invocation message. (fy:无效的 [调用] 消息)");
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 判断是否是一个流消息子项
|
||||
* @param message
|
||||
*/
|
||||
JsonHubProtocol.prototype.isStreamItemMessage = function (message) {
|
||||
this.assertNotEmptyString(message.invocationId, "Invalid payload for StreamItem message. (fy:无效的 [StreamItem] 消息)");
|
||||
if (message.item === undefined) {
|
||||
throw new Error("Invalid payload for StreamItem message. (fy:无效的 [StreamItem] 消息)");
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 判断是否是一个完整的消息
|
||||
* @param message
|
||||
*/
|
||||
JsonHubProtocol.prototype.isCompletionMessage = function (message) {
|
||||
if (message.result && message.error) {
|
||||
throw new Error("Invalid payload for Completion message (fy:消息不完整).");
|
||||
}
|
||||
if (!message.result && message.error) {
|
||||
this.assertNotEmptyString(message.error, "Invalid payload for Completion message (fy:消息不完整).");
|
||||
}
|
||||
this.assertNotEmptyString(message.invocationId, "Invalid payload for Completion message (fy:消息不完整).");
|
||||
};
|
||||
/**
|
||||
* 断言非空字符串
|
||||
* @param value
|
||||
* @param errorMessage
|
||||
*/
|
||||
JsonHubProtocol.prototype.assertNotEmptyString = function (value, errorMessage) {
|
||||
if (typeof value !== "string" || value === "") {
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
};
|
||||
return JsonHubProtocol;
|
||||
}());
|
||||
export { JsonHubProtocol };
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
/** 未定义 logger 时使用的 空输出实现. */
|
||||
var NullLogger = /** @class */ (function () {
|
||||
function NullLogger() {
|
||||
}
|
||||
NullLogger.prototype.log = function (logLevel) {
|
||||
var msg = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
msg[_i - 1] = arguments[_i];
|
||||
}
|
||||
};
|
||||
/** The singleton instance of the {@link @aspnet/signalr.NullLogger}. */
|
||||
NullLogger.instance = new NullLogger();
|
||||
return NullLogger;
|
||||
}());
|
||||
export { NullLogger };
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
import { AbortController } from "./AbortController";
|
||||
import { HttpError, TimeoutError } from "./Errors";
|
||||
import { LogLevel } from "./ILogger";
|
||||
import { TransferFormat } from "./ITransport";
|
||||
import { Arg, getDataDetail, sendMessage } from "./Utils";
|
||||
import { ResponseType } from "./wx-request/model/ResponseType";
|
||||
import { NullLogger } from './Loggers';
|
||||
import DefaultRequest from "./DefualtRequest";
|
||||
// Not exported from 'index', this type is internal.
|
||||
/**
|
||||
* 长轮询
|
||||
* @private
|
||||
*/
|
||||
var LongPollingTransport = /** @class */ (function () {
|
||||
/**
|
||||
* 导出 request 工具
|
||||
* @param {Request} request
|
||||
* @param {((() => string | Promise<string>) | undefined)} accessTokenFactory access-token-factory
|
||||
* @param {ILogger} logger
|
||||
* @param {boolean} logMessageContent
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
function LongPollingTransport(options) {
|
||||
this.accessTokenFactory = options.accessTokenFactory ? options.accessTokenFactory : undefined;
|
||||
this.logger = options.logger ? options.logger : new NullLogger();
|
||||
this.pollAbort = new AbortController();
|
||||
this.logMessageContent = options.logMessageContent ? options.logMessageContent : false;
|
||||
this.request = options.request ? options.request : new DefaultRequest({}, this.logger);
|
||||
this.running = false;
|
||||
this.onreceive = null;
|
||||
this.onclose = null;
|
||||
}
|
||||
Object.defineProperty(LongPollingTransport.prototype, "pollAborted", {
|
||||
// This is an internal type, not exported from 'index' so this is really just internal.
|
||||
get: function () {
|
||||
return this.pollAbort.aborted;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
/**
|
||||
* 连接 - 这里理解为请求
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {TransferFormat} transferFormat
|
||||
* @returns {Promise<void>}
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.connect = function (options) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var pollOptions, token, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
/* 验证参数完整性,不完整抛出异常 */
|
||||
Arg.isRequired(options, "options");
|
||||
Arg.isRequired(options.transferFormat, "transferFormat");
|
||||
Arg.isIn(options.transferFormat, TransferFormat, "transferFormat");
|
||||
// update options
|
||||
this.url = options.url;
|
||||
// print log
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Connecting.");
|
||||
pollOptions = {
|
||||
config: {
|
||||
// 中断信号
|
||||
about: this.pollAbort.signal.aborted,
|
||||
timeout: 120 * 1000 // 超时时间 2 min
|
||||
},
|
||||
// origin header 头
|
||||
headers: {}
|
||||
};
|
||||
if (options.transferFormat === TransferFormat.Binary) {
|
||||
pollOptions.responseType = ResponseType.ARRAY_BUFFER;
|
||||
}
|
||||
return [4 /*yield*/, this.getAccessToken()];
|
||||
case 1:
|
||||
token = _a.sent();
|
||||
this.updateHeaderToken(pollOptions, token);
|
||||
// Make initial long polling request
|
||||
// Server uses first long polling request to finish initializing connection and it returns without data
|
||||
//发出初始长轮询请求
|
||||
//服务器使用第一个长轮询请求完成连接初始化,它返回时不带数据
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) polling: [url]" + this.url);
|
||||
return [4 /*yield*/, this.request.get(this.url, {
|
||||
_: Date.now()
|
||||
}, pollOptions)];
|
||||
case 2:
|
||||
response = _a.sent();
|
||||
if (response.statusCode !== 200) {
|
||||
this.logger.log(LogLevel.Error, "(LongPolling transport) Unexpected response code: " + response.statusCode + ".");
|
||||
// Mark running as false so that the poll immediately ends and runs the close logic
|
||||
// ! 重写了 内置 的 创建 `HttpError` 方法
|
||||
this.closeError = new HttpError(response.errMsg || "", response.statusCode);
|
||||
this.running = false;
|
||||
}
|
||||
else {
|
||||
this.running = true;
|
||||
}
|
||||
this.receiving = this.poll(this.url, pollOptions);
|
||||
return [2 /*return*/, Promise.resolve({
|
||||
errMsg: "connect success"
|
||||
})];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取 access-token
|
||||
*
|
||||
* @private
|
||||
* @returns {(Promise<string | null>)}
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.getAccessToken = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!this.accessTokenFactory) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, this.accessTokenFactory()];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
case 2: return [2 /*return*/, null];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 更新 access-token
|
||||
*
|
||||
* @private
|
||||
* @param {RequestOption} request
|
||||
* @param {(string | null)} token
|
||||
* @returns
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.updateHeaderToken = function (request, token) {
|
||||
/**
|
||||
* fix header
|
||||
*/
|
||||
if (!request.headers) {
|
||||
request.headers = {};
|
||||
}
|
||||
/**
|
||||
* push token to headers
|
||||
*/
|
||||
if (token) {
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
request.headers["Authorization"] = "Bearer " + token;
|
||||
return;
|
||||
}
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
if (request.headers["Authorization"]) {
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
delete request.headers["Authorization"];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 异步计数?
|
||||
*
|
||||
* @private
|
||||
* @param {string} url
|
||||
* @param {RequestOption} pollOptions
|
||||
* @returns {Promise<void>}
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.poll = function (url, pollOptions) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var token, pollUrl, response, e_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
_a.trys.push([0, , 8, 9]);
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
if (!this.running) return [3 /*break*/, 7];
|
||||
return [4 /*yield*/, this.getAccessToken()];
|
||||
case 2:
|
||||
token = _a.sent();
|
||||
this.updateHeaderToken(pollOptions, token);
|
||||
_a.label = 3;
|
||||
case 3:
|
||||
_a.trys.push([3, 5, , 6]);
|
||||
pollUrl = url + "&_=" + Date.now();
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) polling: " + pollUrl + ". - (fy:\u957F\u8F6E\u8BE2\u4F20\u8F93 - polling)");
|
||||
return [4 /*yield*/, this.request.get(this.url, {
|
||||
_: Date.now()
|
||||
}, pollOptions)];
|
||||
case 4:
|
||||
response = _a.sent();
|
||||
if (response.statusCode === 204) {
|
||||
this.logger.log(LogLevel.Information, "(LongPolling transport) Poll terminated by server. - (fy:长轮询传输 - 由服务器终止轮询。)");
|
||||
this.running = false;
|
||||
}
|
||||
else if (response.statusCode !== 200) {
|
||||
this.logger.log(LogLevel.Error, "(LongPolling transport) Unexpected response code: " + response.statusCode + ". - (fy:\u957F\u8F6E\u8BE2\u4F20\u8F93 - \u610F\u5916\u7684\u54CD\u5E94\u4EE3\u7801)");
|
||||
// Unexpected status code
|
||||
this.closeError = new HttpError(response.errMsg || "", response.statusCode);
|
||||
this.running = false;
|
||||
}
|
||||
else {
|
||||
// Process the response
|
||||
if (response.data) {
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) data received. " + getDataDetail(response.data, this.logMessageContent) + ".");
|
||||
if (this.onreceive) {
|
||||
this.onreceive(response.data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is another way timeout manifest.
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing.");
|
||||
}
|
||||
}
|
||||
return [3 /*break*/, 6];
|
||||
case 5:
|
||||
e_1 = _a.sent();
|
||||
if (!this.running) {
|
||||
// Log but disregard errors that occur after stopping - fy: 记录但忽略停止后发生的错误
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Poll errored after shutdown: " + e_1.message);
|
||||
}
|
||||
else {
|
||||
if (e_1 instanceof TimeoutError) {
|
||||
// Ignore timeouts and reissue the poll. - 忽略超时并重新发出投票
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Poll timed out, reissuing. - (fy:长轮询传输 - 请求超时)");
|
||||
}
|
||||
else {
|
||||
// Close the connection with the error as the result.
|
||||
this.closeError = e_1;
|
||||
this.running = false;
|
||||
}
|
||||
}
|
||||
return [3 /*break*/, 6];
|
||||
case 6: return [3 /*break*/, 1];
|
||||
case 7: return [3 /*break*/, 9];
|
||||
case 8:
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Polling complete. - (fy:长轮询传输 - 请求完成)");
|
||||
// We will reach here with pollAborted==false when the server returned a response causing the transport to stop.
|
||||
// If pollAborted==true then client initiated the stop and the stop method will raise the close event after DELETE is sent.
|
||||
//当服务器返回导致传输停止的响应时,我们将使用pollAborted==false到达这里。
|
||||
//如果pollAborted==true,则客户端启动了stop,stop方法将在发送DELETE后引发close事件。
|
||||
if (!this.pollAborted) {
|
||||
this.raiseOnClose();
|
||||
}
|
||||
return [7 /*endfinally*/];
|
||||
case 9: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 发送轮询包
|
||||
*
|
||||
* @param {*} data
|
||||
* @returns {Promise<void>}
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.send = function (data) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
if (!this.running) {
|
||||
return [2 /*return*/, Promise.reject(new Error("Cannot send until the transport is connected"))];
|
||||
}
|
||||
return [2 /*return*/, sendMessage(this.logger, "LongPolling", this.request, this.url, this.accessTokenFactory, data, this.logMessageContent)];
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 停止
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.stop = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var deleteOptions, token, e_2;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Stopping polling.");
|
||||
// Tell receiving loop to stop, abort any current request, and then wait for it to finish
|
||||
this.running = false;
|
||||
this.pollAbort.abort();
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 5, 6, 7]);
|
||||
return [4 /*yield*/, this.receiving];
|
||||
case 2:
|
||||
_a.sent(); // 这里 receiving 本身是一个 promise result, 用这个对象来监控请求未完成
|
||||
// Send DELETE to clean up long polling on the server
|
||||
// 发送DELETE以清除服务器上的长轮询
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) sending DELETE request to " + this.url + ".");
|
||||
deleteOptions = {
|
||||
headers: {}
|
||||
};
|
||||
return [4 /*yield*/, this.getAccessToken()];
|
||||
case 3:
|
||||
token = _a.sent();
|
||||
this.updateHeaderToken(deleteOptions, token);
|
||||
return [4 /*yield*/, this.request.delete(this.url, {}, deleteOptions)];
|
||||
case 4:
|
||||
_a.sent();
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) DELETE request sent.");
|
||||
return [2 /*return*/, Promise.resolve({
|
||||
errMsg: "stop success"
|
||||
})];
|
||||
case 5:
|
||||
e_2 = _a.sent();
|
||||
this.logger.log(LogLevel.Error, "(LongPolling transport) Stop error.", e_2);
|
||||
return [2 /*return*/, Promise.reject({
|
||||
errMsg: "stop fail"
|
||||
})];
|
||||
case 6:
|
||||
this.logger.log(LogLevel.Trace, "(LongPolling transport) Stop finished.");
|
||||
// Raise close event here instead of in polling
|
||||
// It needs to happen after the DELETE request is sent
|
||||
//在此处引发关闭事件,而不是在轮询中
|
||||
//它需要在发送删除请求后发生
|
||||
this.raiseOnClose();
|
||||
return [7 /*endfinally*/];
|
||||
case 7: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 调用关闭回调
|
||||
*
|
||||
* @private
|
||||
* @memberof LongPollingTransport
|
||||
*/
|
||||
LongPollingTransport.prototype.raiseOnClose = function () {
|
||||
if (this.onclose) {
|
||||
var logMessage = "(LongPolling transport) Firing onclose event.";
|
||||
if (this.closeError) {
|
||||
logMessage += " Error: " + this.closeError;
|
||||
}
|
||||
this.logger.log(LogLevel.Trace, logMessage);
|
||||
this.onclose(this.closeError);
|
||||
}
|
||||
};
|
||||
return LongPollingTransport;
|
||||
}());
|
||||
export { LongPollingTransport };
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt
|
||||
// Not exported from index
|
||||
/**
|
||||
* 小程序socket连接状态[枚举]
|
||||
*/
|
||||
export var WxSocketReadyState;
|
||||
(function (WxSocketReadyState) {
|
||||
WxSocketReadyState[WxSocketReadyState["CONNECTING"] = 0] = "CONNECTING";
|
||||
WxSocketReadyState[WxSocketReadyState["OPEN"] = 1] = "OPEN";
|
||||
WxSocketReadyState[WxSocketReadyState["CLOSING"] = 2] = "CLOSING";
|
||||
WxSocketReadyState[WxSocketReadyState["CLOSED"] = 3] = "CLOSED";
|
||||
})(WxSocketReadyState || (WxSocketReadyState = {}));
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
// 未从索引导出
|
||||
/**
|
||||
* 文本类型消息格式化
|
||||
* @private
|
||||
*/
|
||||
var TextMessageFormat = /** @class */ (function () {
|
||||
function TextMessageFormat() {
|
||||
}
|
||||
/**
|
||||
* 输出一个格式化过的消息
|
||||
* @param output
|
||||
*/
|
||||
TextMessageFormat.write = function (output) {
|
||||
return "" + output + TextMessageFormat.RecordSeparator;
|
||||
};
|
||||
/**
|
||||
* 解析
|
||||
* @param input
|
||||
*/
|
||||
TextMessageFormat.parse = function (input) {
|
||||
if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) {
|
||||
throw new Error("Message is incomplete.");
|
||||
}
|
||||
var messages = input.split(TextMessageFormat.RecordSeparator);
|
||||
messages.pop();
|
||||
return messages;
|
||||
};
|
||||
/**
|
||||
* 记录分隔符 code
|
||||
*
|
||||
* @static
|
||||
* @memberof TextMessageFormat
|
||||
*/
|
||||
TextMessageFormat.RecordSeparatorCode = 0x1e;
|
||||
/**
|
||||
* 记录分隔符(string)
|
||||
*
|
||||
* @static
|
||||
* @memberof TextMessageFormat
|
||||
*/
|
||||
TextMessageFormat.RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode);
|
||||
return TextMessageFormat;
|
||||
}());
|
||||
export { TextMessageFormat };
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||
r[k] = a[j];
|
||||
return r;
|
||||
};
|
||||
import { LogLevel } from "./ILogger";
|
||||
import { NullLogger } from "./Loggers";
|
||||
import { ResponseType } from "./wx-request/model/ResponseType";
|
||||
/**
|
||||
* 参数处理方法
|
||||
* @private
|
||||
*/
|
||||
var Arg = /** @class */ (function () {
|
||||
function Arg() {
|
||||
}
|
||||
/**
|
||||
* 是否存在
|
||||
*
|
||||
* @static
|
||||
* @param {*} val
|
||||
* @param {string} name
|
||||
* @memberof Arg
|
||||
*/
|
||||
Arg.isRequired = function (val, name) {
|
||||
if (val === null || val === undefined) {
|
||||
throw new Error("The '" + name + "' argument is required.");
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 是否包含
|
||||
*
|
||||
* @static
|
||||
* @param {*} val
|
||||
* @param {*} values
|
||||
* @param {string} name
|
||||
* @memberof Arg
|
||||
*/
|
||||
Arg.isIn = function (val, values, name) {
|
||||
// TypeScript enums have keys for **both** the name and the value of each enum member on the type itself.
|
||||
if (!(val in values)) {
|
||||
throw new Error("Unknown " + name + " value: " + val + ".");
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 验证url是否被微信支持
|
||||
*/
|
||||
Arg.validationUrlIsSupportByWechat = function (url) {
|
||||
if (!url) {
|
||||
throw new Error("Url is undefined.");
|
||||
}
|
||||
else if (!/^(ws|wws):\/\//.test(url)) {
|
||||
if (/^http/.test(url)) {
|
||||
return url.replace(/^http/, "wx");
|
||||
}
|
||||
throw new Error("error: instantiation [url](" + url + ") not supported by wechat miniprogram.");
|
||||
}
|
||||
else {
|
||||
return url;
|
||||
}
|
||||
};
|
||||
return Arg;
|
||||
}());
|
||||
export { Arg };
|
||||
/**
|
||||
* 获取data details
|
||||
* @param data origin data
|
||||
* @param includeContent 是否导出上下文?
|
||||
*/
|
||||
export function getDataDetail(data, includeContent) {
|
||||
var detail = "";
|
||||
if (isArrayBuffer(data)) {
|
||||
detail = "Binary data of length " + data.byteLength;
|
||||
if (includeContent) {
|
||||
detail += ". Content: '" + formatArrayBuffer(data) + "'";
|
||||
}
|
||||
}
|
||||
else if (typeof data === "string") {
|
||||
detail = "String data of length " + data.length;
|
||||
if (includeContent) {
|
||||
detail += ". Content: '" + data + "'";
|
||||
}
|
||||
}
|
||||
return detail;
|
||||
}
|
||||
/**
|
||||
* 格式化 array buffer
|
||||
* @private
|
||||
*/
|
||||
export function formatArrayBuffer(data) {
|
||||
var view = new Uint8Array(data);
|
||||
// Uint8Array.map only supports returning another Uint8Array?
|
||||
var str = "";
|
||||
view.forEach(function (num) {
|
||||
var pad = num < 16 ? "0" : "";
|
||||
str += "0x" + pad + num.toString(16) + " ";
|
||||
});
|
||||
// Trim of trailing space.
|
||||
return str.substr(0, str.length - 1);
|
||||
}
|
||||
// Also in signalr-protocol-msgpack/Utils.ts
|
||||
/**
|
||||
* 判断是不是 ArrayBuffer
|
||||
* @private
|
||||
*/
|
||||
export function isArrayBuffer(val) {
|
||||
return (val &&
|
||||
typeof ArrayBuffer !== "undefined" &&
|
||||
(val instanceof ArrayBuffer ||
|
||||
// Sometimes we get an ArrayBuffer that doesn't satisfy instanceof
|
||||
(val.constructor && val.constructor.name === "ArrayBuffer")));
|
||||
}
|
||||
/**
|
||||
* 发送消息
|
||||
* @param logger 日志工具
|
||||
* @param transportName
|
||||
* @param request - 注: 原版代码为 httpClient,这里使用 wx-request.
|
||||
* @param url
|
||||
* @param accessTokenFactory
|
||||
* @param content
|
||||
* @param logMessageContent
|
||||
*/
|
||||
export function sendMessage(logger, transportName, request, url, accessTokenFactory, content, logMessageContent) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var headers, token, responseType, response;
|
||||
var _a;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
if (!accessTokenFactory) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, accessTokenFactory()];
|
||||
case 1:
|
||||
token = _b.sent();
|
||||
if (token) {
|
||||
headers = (_a = {},
|
||||
_a["Authorization"] = "Bearer " + token,
|
||||
_a);
|
||||
}
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
logger.log(LogLevel.Trace, "(" + transportName + " transport) sending data. " + getDataDetail(content, logMessageContent) + ".");
|
||||
responseType = isArrayBuffer(content) ? ResponseType.ARRAY_BUFFER : ResponseType.TEXT;
|
||||
return [4 /*yield*/, request.post(url, content, {
|
||||
headers: headers,
|
||||
responseType: responseType
|
||||
})];
|
||||
case 3:
|
||||
response = _b.sent();
|
||||
logger.log(LogLevel.Trace, "(" + transportName + " transport) request complete. Response status: " + response.statusCode + ".");
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 创建一个 logger
|
||||
* @private
|
||||
*/
|
||||
export function createLogger(logger) {
|
||||
if (logger === undefined) {
|
||||
return new ConsoleLogger(LogLevel.Information);
|
||||
}
|
||||
if (logger === null) {
|
||||
return NullLogger.instance;
|
||||
}
|
||||
if (logger.log) {
|
||||
return logger;
|
||||
}
|
||||
return new ConsoleLogger(logger);
|
||||
}
|
||||
/**
|
||||
* 订阅接口实现
|
||||
* @private
|
||||
*/
|
||||
var Subject = /** @class */ (function () {
|
||||
function Subject(cancelCallback) {
|
||||
this.observers = [];
|
||||
this.cancelCallback = cancelCallback;
|
||||
}
|
||||
Subject.prototype.next = function (item) {
|
||||
for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {
|
||||
var observer = _a[_i];
|
||||
observer.next(item);
|
||||
}
|
||||
};
|
||||
Subject.prototype.error = function (err) {
|
||||
for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {
|
||||
var observer = _a[_i];
|
||||
if (observer.error) {
|
||||
observer.error(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
Subject.prototype.complete = function () {
|
||||
for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {
|
||||
var observer = _a[_i];
|
||||
if (observer.complete) {
|
||||
observer.complete();
|
||||
}
|
||||
}
|
||||
};
|
||||
Subject.prototype.subscribe = function (observer) {
|
||||
this.observers.push(observer);
|
||||
return new SubjectSubscription(this, observer);
|
||||
};
|
||||
return Subject;
|
||||
}());
|
||||
export { Subject };
|
||||
/**
|
||||
* 主题订阅??
|
||||
* 应该时定制 断开流 的 实现吧.
|
||||
* @private
|
||||
*/
|
||||
var SubjectSubscription = /** @class */ (function () {
|
||||
function SubjectSubscription(subject, observer) {
|
||||
this.subject = subject;
|
||||
this.observer = observer;
|
||||
}
|
||||
SubjectSubscription.prototype.dispose = function () {
|
||||
var index = this.subject.observers.indexOf(this.observer);
|
||||
if (index > -1) {
|
||||
this.subject.observers.splice(index, 1);
|
||||
}
|
||||
if (this.subject.observers.length === 0) {
|
||||
this.subject.cancelCallback().catch(function (_) { });
|
||||
}
|
||||
};
|
||||
return SubjectSubscription;
|
||||
}());
|
||||
export { SubjectSubscription };
|
||||
/**
|
||||
* console logger 内置实现
|
||||
* @private
|
||||
*/
|
||||
var ConsoleLogger = /** @class */ (function () {
|
||||
/**
|
||||
* 构造方法 定义 最小输出日志等级
|
||||
* @param {LogLevel} minimumLogLevel
|
||||
* @memberof ConsoleLogger
|
||||
*/
|
||||
function ConsoleLogger(minimumLogLevel) {
|
||||
this.minimumLogLevel = minimumLogLevel;
|
||||
}
|
||||
/**
|
||||
* 日志输出
|
||||
*
|
||||
* @param {LogLevel} logLevel
|
||||
* @param {string} message
|
||||
* @memberof ConsoleLogger
|
||||
*/
|
||||
ConsoleLogger.prototype.log = function () {
|
||||
var msg = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
msg[_i] = arguments[_i];
|
||||
}
|
||||
var logLevel = LogLevel.Information;
|
||||
for (var _a = 0, _b = arguments; _a < _b.length; _a++) {
|
||||
var ll = _b[_a];
|
||||
if (Object.values(LogLevel).indexOf(ll) != -1) {
|
||||
logLevel = ll;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (logLevel >= this.minimumLogLevel) {
|
||||
switch (logLevel) {
|
||||
case LogLevel.Critical:
|
||||
case LogLevel.Error:
|
||||
console.error.apply(console, __spreadArrays(["[" + new Date().toISOString() + "] " + LogLevel[logLevel] + " =>"], msg.slice(1, msg.length)));
|
||||
break;
|
||||
case LogLevel.Warning:
|
||||
console.warn.apply(console, __spreadArrays(["[" + new Date().toISOString() + "] " + LogLevel[logLevel] + " =>"], msg));
|
||||
break;
|
||||
case LogLevel.Information:
|
||||
console.info.apply(console, __spreadArrays(["[" + new Date().toISOString() + "] " + LogLevel[logLevel] + " =>"], msg));
|
||||
break;
|
||||
default:
|
||||
// console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug
|
||||
console.log.apply(console, __spreadArrays(["[" + new Date().toISOString() + "] " + LogLevel[logLevel] + " =>"], msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
return ConsoleLogger;
|
||||
}());
|
||||
export { ConsoleLogger };
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* 小程序版本支持
|
||||
* @param minimumVersion 最小支持版本号
|
||||
*/
|
||||
export var isVersionSupport = function (minimumVersion) {
|
||||
// diff
|
||||
var compareVersion = function (v1, v2) {
|
||||
v1 = v1.split(".");
|
||||
v2 = v2.split(".");
|
||||
var len = Math.max(v1.length, v2.length);
|
||||
while (v1.length < len) {
|
||||
v1.push("0");
|
||||
}
|
||||
while (v2.length < len) {
|
||||
v2.push("0");
|
||||
}
|
||||
for (var i = 0; i < len; i++) {
|
||||
var num1 = parseInt(v1[i]);
|
||||
var num2 = parseInt(v2[i]);
|
||||
if (num1 > num2) {
|
||||
return 1;
|
||||
}
|
||||
else if (num1 < num2) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
// 获取当前小程序 版本号
|
||||
var SDKVersion = wx.getSystemInfoSync().SDKVersion;
|
||||
// check
|
||||
return compareVersion(SDKVersion, minimumVersion) >= 0;
|
||||
};
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
import { LogLevel } from "./ILogger";
|
||||
import { Arg, getDataDetail } from "./Utils";
|
||||
import { WxSocketReadyState } from "./Polyfills";
|
||||
import { isVersionSupport } from "./WechatVersionDiff";
|
||||
/**
|
||||
* 微信 sosocket 数据传输
|
||||
* @description 整体重写了这部分websocket支持,逻辑这样看起来合理一些
|
||||
*/
|
||||
var WxSocketTransport = /** @class */ (function () {
|
||||
function WxSocketTransport(options) {
|
||||
this.readyState = WxSocketReadyState.CONNECTING;
|
||||
this.logger = options.logger;
|
||||
this.accessTokenFactory = options.accessTokenFactory;
|
||||
this.socketUrlFactory = options.socketUrlFactory;
|
||||
this.logMessageContent = options.logMessageContent;
|
||||
this.onreceive = null;
|
||||
this.onclose = null;
|
||||
this.allowReplaceSocket = options.allowReplaceSocket;
|
||||
this.timeout = options.timeout ? options.timeout : 60 * 1000;
|
||||
this.delayTime = options.delayTime ? options.delayTime : 100;
|
||||
if (options.enableMessageQueue) {
|
||||
this.enableMessageQueue = true;
|
||||
this.messageQueue = [];
|
||||
}
|
||||
else {
|
||||
this.enableMessageQueue = false;
|
||||
}
|
||||
if (options.reconnect) {
|
||||
this.reconnect = {
|
||||
enable: options.reconnect.enable == true ? true : false,
|
||||
max: options.reconnect.max ? options.reconnect.max : 3,
|
||||
val: 0
|
||||
};
|
||||
}
|
||||
else {
|
||||
this.reconnect = {
|
||||
enable: false,
|
||||
max: 3,
|
||||
val: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
WxSocketTransport.prototype.connect = function (options) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var replacedUrl, token;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
// vali is exists
|
||||
Arg.isRequired(options, "options");
|
||||
// vali url is support by wechat
|
||||
Arg.validationUrlIsSupportByWechat(options.url);
|
||||
this.connectOptions = options; // 连接参数缓存
|
||||
this.logger.log(LogLevel.Trace, "(WebSockets transport) Connecting.");
|
||||
if (!this.socketUrlFactory) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, this.socketUrlFactory(options.url)];
|
||||
case 1:
|
||||
replacedUrl = _a.sent();
|
||||
if (replacedUrl) {
|
||||
options.url = replacedUrl;
|
||||
}
|
||||
return [3 /*break*/, 4];
|
||||
case 2:
|
||||
if (!this.accessTokenFactory) return [3 /*break*/, 4];
|
||||
return [4 /*yield*/, this.accessTokenFactory()];
|
||||
case 3:
|
||||
token = _a.sent();
|
||||
this.logger.log(LogLevel.Debug, "getted token:", token);
|
||||
if (token) {
|
||||
options.url += (options.url.indexOf("?") < 0 ? "?" : "&") + ("access_token=" + encodeURIComponent(token));
|
||||
}
|
||||
_a.label = 4;
|
||||
case 4: return [2 /*return*/, new Promise(function (resolve, reject) {
|
||||
// 忽略url修正,因为传入错误url的话,将直接抛出异常
|
||||
options.url = options.url.replace(/^http/, "ws");
|
||||
// 这里执行的是连接操socket的逻辑
|
||||
var socketTask;
|
||||
// 1.7.0 及以上版本,最多可以同时存在 5 个 WebSocket 连接, 以下版本,一个小程序同时只能有一个 WebSocket 连接,如果当前已存在一个 WebSocket 连接,会自动关闭该连接,并重新创建一个 WebSocket 连接
|
||||
var supportCount = isVersionSupport("1.7.0") ? 5 : 1;
|
||||
if (supportCount <= WxSocketTransport.count && !_this.allowReplaceSocket) {
|
||||
// 抛出异常, 并return
|
||||
reject({
|
||||
errMsg: "Maximum connections|" + WxSocketTransport.count
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if (WxSocketTransport.count == 5) {
|
||||
// 抛出异常, 并return
|
||||
reject({
|
||||
errMsg: "Maximum connections|" + WxSocketTransport.count
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!socketTask) {
|
||||
socketTask = wx.connectSocket(__assign({
|
||||
// 传入 两个默认的 回调,当然也可以在 options 里面覆盖 使用自定义回调.
|
||||
success: function (res) {
|
||||
_this.logger.log(LogLevel.Debug, "wx.connectSocket():success");
|
||||
}, fail: function (res) {
|
||||
_this.logger.log(LogLevel.Debug, "wx.connectSocket():fail");
|
||||
reject(res);
|
||||
} }, options));
|
||||
}
|
||||
// ! 因为小程序两种协议都支持,所以不需要指定特定的 binaryType
|
||||
/** 连接成功处理 */
|
||||
socketTask.onOpen(function (result) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var _i, _a, msg;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
this.logger.log(LogLevel.Information, "websocket\u8FDE\u63A5\u5EFA\u7ACB " + (this.logMessageContent ? "wx api:[" + options.url + "]" : ""));
|
||||
this.logger.log(LogLevel.Debug, "wx.connectSocket success message:", result);
|
||||
WxSocketTransport.count += 1;
|
||||
this.readyState = WxSocketReadyState.OPEN;
|
||||
this.socketTask = socketTask;
|
||||
// 等待回调执行完成后,再重新队列中消息
|
||||
return [4 /*yield*/, resolve()];
|
||||
case 1:
|
||||
// 等待回调执行完成后,再重新队列中消息
|
||||
_b.sent();
|
||||
if (!(this.enableMessageQueue && this.messageQueue.length > 0)) return [3 /*break*/, 5];
|
||||
_i = 0, _a = this.messageQueue;
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
if (!(_i < _a.length)) return [3 /*break*/, 5];
|
||||
msg = _a[_i];
|
||||
this.logger.log(LogLevel.Debug, "\u63A8\u9001\u79BB\u7EBF\u6D88\u606F", this.logMessageContent ? msg : "");
|
||||
return [4 /*yield*/, this.send(msg)];
|
||||
case 3:
|
||||
_b.sent();
|
||||
_b.label = 4;
|
||||
case 4:
|
||||
_i++;
|
||||
return [3 /*break*/, 2];
|
||||
case 5: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
/** 建立连接出错处理 */
|
||||
socketTask.onError(function (res) {
|
||||
_this.readyState = WxSocketReadyState.CLOSED;
|
||||
reject(res);
|
||||
});
|
||||
/** 接收到消息处理 */
|
||||
socketTask.onMessage(function (res) {
|
||||
_this.logger.log(LogLevel.Trace, "(WebSockets transport) data received.", getDataDetail(res.data, _this.logMessageContent));
|
||||
if (_this.onreceive) {
|
||||
_this.onreceive(res.data);
|
||||
}
|
||||
});
|
||||
socketTask.onClose(function (res) { return _this.close(res); });
|
||||
})];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** 休眠 */
|
||||
WxSocketTransport.prototype.delay = function () {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve) {
|
||||
// ! 由于小程序机制,所以需要手工清理timer
|
||||
var timer = setTimeout(function () {
|
||||
clearTimeout(timer);
|
||||
resolve();
|
||||
}, _this.delayTime);
|
||||
});
|
||||
};
|
||||
/** 发送 */
|
||||
WxSocketTransport.prototype.send = function (data) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var loop;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!(this.socketTask && this.readyState === WxSocketReadyState.OPEN)) return [3 /*break*/, 1];
|
||||
this.logger.log(LogLevel.Trace, "[WxSocket] \u63A8\u9001\u6570\u636E.", getDataDetail(data, this.logMessageContent));
|
||||
return [2 /*return*/, new Promise(function (resolve, reject) {
|
||||
_this.socketTask.send({
|
||||
data: data,
|
||||
success: function () { return resolve(); },
|
||||
fail: function () { return reject(); }
|
||||
});
|
||||
})];
|
||||
case 1:
|
||||
if (!this.enableMessageQueue) return [3 /*break*/, 5];
|
||||
this.messageQueue.push(data);
|
||||
loop = 0;
|
||||
_a.label = 2;
|
||||
case 2:
|
||||
if (!(this.socketTask && this.readyState !== WxSocketReadyState.OPEN)) return [3 /*break*/, 4];
|
||||
return [4 /*yield*/, this.delay()];
|
||||
case 3:
|
||||
_a.sent();
|
||||
loop += this.delayTime;
|
||||
if (loop >= this.timeout) {
|
||||
// 超时设置
|
||||
return [2 /*return*/, Promise.reject({
|
||||
errMsg: "WebSocket connect timeout."
|
||||
})];
|
||||
}
|
||||
return [3 /*break*/, 2];
|
||||
case 4:
|
||||
// 回调
|
||||
return [2 /*return*/, this.send(data)];
|
||||
case 5: return [2 /*return*/, Promise.reject({
|
||||
errMsg: "WebSocket is not in the OPEN state"
|
||||
})];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** 停止 */
|
||||
WxSocketTransport.prototype.stop = function (msg) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (_this.socketTask) {
|
||||
_this.socketTask.close({
|
||||
code: 1000,
|
||||
reason: "stop socket",
|
||||
success: function (res) { return resolve(msg || res); },
|
||||
fail: function (res) { return reject(res); }
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 连接断开处理
|
||||
* @param res
|
||||
*/
|
||||
WxSocketTransport.prototype.close = function (res) {
|
||||
// webSocket will be null if the transport did not start successfully
|
||||
this.logger.log(LogLevel.Trace, "(WebSockets transport) socket closed.");
|
||||
WxSocketTransport.count = WxSocketTransport.count > 0 ? WxSocketTransport.count - 1 : 0;
|
||||
if (this.onclose) {
|
||||
if (res && res.code !== 1000) {
|
||||
this.onclose(new Error("WebSocket closed with status code: " + res.code + " (" + res.reason + ")."));
|
||||
}
|
||||
else {
|
||||
this.onclose();
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 静态变量 - 表示当前是否有正在连接中的socket
|
||||
*/
|
||||
WxSocketTransport.count = 0;
|
||||
return WxSocketTransport;
|
||||
}());
|
||||
export { WxSocketTransport };
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// 版权所有(c).NET基金会。保留所有权利。
|
||||
// 在2.0版Apache许可下授权。有关许可证信息,请参见项目根目录中的License.txt。
|
||||
// 版本号模板 - builder 自动更新,无需手动
|
||||
/** The version of the SignalR client. */
|
||||
export var VERSION = "1.1.6";
|
||||
// 协议|类型参数 导出
|
||||
export { MessageType } from "./IHubProtocol";
|
||||
// json格式传输协议
|
||||
export { JsonHubProtocol } from "./JsonHubProtocol";
|
||||
export { HubConnectionBuilder } from "./HubConnectionBuilder";
|
||||
export { HubConnection, HubConnectionState } from "./HubConnection";
|
||||
// 微信最低版本支持检查
|
||||
export { isVersionSupport } from "./WechatVersionDiff";
|
||||
// 微信socket传输实现
|
||||
export { WxSocketTransport } from "./WxSocketTransport";
|
||||
// 微信 request 请求实现(封装 wx.request)
|
||||
export { Request } from "./wx-request/index";
|
||||
export { RequestMethod, ResponseType } from "./wx-request/model";
|
||||
// Error 接口
|
||||
export { AbortError, HttpError, TimeoutError } from "./Errors";
|
||||
// logger 接口
|
||||
export { LogLevel } from "./ILogger";
|
||||
// Transport 接口
|
||||
export { HttpTransportType, TransferFormat } from "./ITransport";
|
||||
|
|
@ -0,0 +1,477 @@
|
|||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
import { RequestMethod } from "./model/RequestMethod";
|
||||
import { ResponseType } from "./model/ResponseType";
|
||||
import { LogLevel } from "../ILogger";
|
||||
import { TimeoutError, HttpError } from "../Errors";
|
||||
import { NullLogger } from "../Loggers";
|
||||
/**
|
||||
* 封装微信ajax请求工具
|
||||
* @author halo
|
||||
*/
|
||||
var Request = /** @class */ (function () {
|
||||
/**
|
||||
* Creates an instance of Request.
|
||||
* 实例化配置
|
||||
* @param {*} [config]
|
||||
* @memberof Request
|
||||
*/
|
||||
function Request(config, logger) {
|
||||
if (config === void 0) { config = {}; }
|
||||
// 写入配置
|
||||
if (wx) {
|
||||
// Time: 继承 signalR logger. 日志统一维护
|
||||
this.logger = logger ? logger : new NullLogger();
|
||||
}
|
||||
else {
|
||||
throw new Error("当前运行环境不是微信运行环境");
|
||||
}
|
||||
// custom wx request promise library.
|
||||
this.setConfig(config);
|
||||
}
|
||||
/**
|
||||
* merge config
|
||||
* @param config
|
||||
*/
|
||||
Request.prototype.setConfig = function (config) {
|
||||
if (config === void 0) { config = {}; }
|
||||
// 合并默认配置和
|
||||
this.config = __assign({ baseUrl: "http://", headers: { "Content-Type": "application/json" }, forceEnableHttps: false, method: RequestMethod.GET, responseType: ResponseType.JSON, responseEncoding: "utf8", timeout: 60 * 1000, transformRequest: [], transformResponse: [] }, config);
|
||||
// 请求头默认附加response 解析器
|
||||
if (!this.config.transformResponse) {
|
||||
this.config.transformResponse = [];
|
||||
}
|
||||
this.logger.log(LogLevel.Information, "set config success.");
|
||||
};
|
||||
/**
|
||||
* 请求参数序列化
|
||||
*
|
||||
* @param {RequestOptions} options
|
||||
* @memberof Request
|
||||
*
|
||||
* @description 只支持普通get请求,和content-type = json 的 其他请求(post,put,delete,patch)
|
||||
*/
|
||||
Request.prototype.handleRequestOptions = function (options) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _i, _a, fun, e_1;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
// 请求地址处理,对于非<scene>:// 请求,附加baseUrl
|
||||
if (options.url && !/:\/\/.+?/.test(options.url)) {
|
||||
options.url = ((options.config ? options.config.baseUrl : "") + "/" + options.url).replace(/([^:])(\/\/)/g, "$1/");
|
||||
}
|
||||
this.logger.log(LogLevel.Trace, "checked request url");
|
||||
// https 处理
|
||||
if (options.config && options.config.forceEnableHttps) {
|
||||
options.url = options.url.replace(/http:/, "https:");
|
||||
this.logger.log(LogLevel.Trace, "execute fix [request.config.forceEnableHttps] " + options.url);
|
||||
}
|
||||
// header 合并
|
||||
options.headers = Object.assign({}, options.config ? options.config.headers : {}, options.headers);
|
||||
this.logger.log(LogLevel.Trace, "merge headers ", options.headers);
|
||||
// 移除微信封锁参数
|
||||
delete options.headers["Referer"];
|
||||
this.logger.log(LogLevel.Trace, "try delete headers Referer.");
|
||||
// 替换请求内的ResponseType
|
||||
options.responseType = options.responseType
|
||||
? options.responseType
|
||||
: options.config
|
||||
? options.config.responseType
|
||||
: ResponseType.TEXT;
|
||||
this.logger.log(LogLevel.Trace, "checked responseType [" + options.responseType + "]");
|
||||
if (!(options.config && options.config.transformRequest)) return [3 /*break*/, 6];
|
||||
this.logger.log(LogLevel.Trace, "execute transform request list. -result\n", options.config);
|
||||
_i = 0, _a = options.config.transformRequest;
|
||||
_b.label = 1;
|
||||
case 1:
|
||||
if (!(_i < _a.length)) return [3 /*break*/, 6];
|
||||
fun = _a[_i];
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
_b.trys.push([2, 4, , 5]);
|
||||
return [4 /*yield*/, fun(options)];
|
||||
case 3:
|
||||
_b.sent();
|
||||
return [3 /*break*/, 5];
|
||||
case 4:
|
||||
e_1 = _b.sent();
|
||||
throw e_1;
|
||||
case 5:
|
||||
_i++;
|
||||
return [3 /*break*/, 1];
|
||||
case 6:
|
||||
// debug print handled request options
|
||||
this.logger.log(LogLevel.Debug, "handled request options \n", options);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 验证响应结果,执行回调
|
||||
*
|
||||
* @param {*} resolve
|
||||
* @param {*} reject
|
||||
* @param {*} response
|
||||
* @memberof Request
|
||||
*/
|
||||
Request.prototype.handleResponse = function (response) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _i, _a, fun, res_1;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
if (!(response.options.config &&
|
||||
response.options.config.responseType == "json" &&
|
||||
response.options.config.transformResponse)) return [3 /*break*/, 6];
|
||||
_i = 0, _a = response.options.config.transformResponse;
|
||||
_b.label = 1;
|
||||
case 1:
|
||||
if (!(_i < _a.length)) return [3 /*break*/, 6];
|
||||
fun = _a[_i];
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
_b.trys.push([2, 4, , 5]);
|
||||
// handler response
|
||||
return [4 /*yield*/, fun(response)];
|
||||
case 3:
|
||||
// handler response
|
||||
_b.sent();
|
||||
return [3 /*break*/, 5];
|
||||
case 4:
|
||||
res_1 = _b.sent();
|
||||
this.logger.log(LogLevel.Trace, "execute transform request list. -result \n ", res_1);
|
||||
throw res_1;
|
||||
case 5:
|
||||
_i++;
|
||||
return [3 /*break*/, 1];
|
||||
case 6:
|
||||
// debug print handled response context
|
||||
this.logger.log(LogLevel.Debug, "handled response context \n", response);
|
||||
return [2 /*return*/, Promise.resolve(response)];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 执行请求
|
||||
*
|
||||
* @param {RequestOptions} [options={
|
||||
* url: this.config.baseUrl
|
||||
* }]
|
||||
* @returns {Promise<any>}
|
||||
* @memberof Request
|
||||
*/
|
||||
Request.prototype.executeRequest = function (options) {
|
||||
var _this = this;
|
||||
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var error_1, task;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.logger.log(LogLevel.Trace, "execute request -options \n", options);
|
||||
// 合并 baseConfig
|
||||
options.config = options.config ? __assign(__assign({}, this.config), options.config) : __assign({}, this.config);
|
||||
if (this.checkAbout(options.config, reject))
|
||||
return [2 /*return*/];
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
// 序列化请求参数
|
||||
return [4 /*yield*/, this.handleRequestOptions(options)];
|
||||
case 2:
|
||||
// 序列化请求参数
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
error_1 = _a.sent();
|
||||
// 抛出异常.
|
||||
return [2 /*return*/, reject(__assign({ data: null, header: null, statusCode: -1, options: options }, error_1))];
|
||||
case 4:
|
||||
if (this.checkAbout(options.config, reject))
|
||||
return [2 /*return*/];
|
||||
// print fixed options
|
||||
this.logger.log(LogLevel.Debug, "fixed options \n", options);
|
||||
// execute request
|
||||
this.logger.log(LogLevel.Trace, "invoke wx.request");
|
||||
task = wx.request({
|
||||
url: options.url,
|
||||
data: options.data,
|
||||
dataType: options.responseType,
|
||||
header: options.headers,
|
||||
method: options.method,
|
||||
responseType: (function () {
|
||||
switch (options.responseType) {
|
||||
case "json":
|
||||
case "text":
|
||||
return "text";
|
||||
case "arraybuffer":
|
||||
return "arraybuffer";
|
||||
}
|
||||
})(),
|
||||
success: function (res) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var data, header, statusCode, errMsg, responseOptions;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
if (this.checkAbout(options.config, reject))
|
||||
return [2 /*return*/];
|
||||
this.logger.log(LogLevel.Debug, "origin response context \n", res);
|
||||
data = res.data, header = res.header, statusCode = res.statusCode, errMsg = res.errMsg;
|
||||
responseOptions = {
|
||||
data: data,
|
||||
header: header,
|
||||
statusCode: statusCode,
|
||||
options: options,
|
||||
errMsg: errMsg
|
||||
};
|
||||
// 调用响应处理链(并返回结果)
|
||||
this.handleResponse(responseOptions)
|
||||
.then(function (res) {
|
||||
// print debug
|
||||
_this.logger.log(LogLevel.Debug, "handle response context is success. \n", res);
|
||||
/**
|
||||
* check and cache cookie (if has) |
|
||||
* @description 这里因为 signalR的原因,内置了一个 cookies.js [library](https://github.com/jshttp/cookie/index.js)
|
||||
* 略有改写,暂时将cookie 扔到内存中维护(毕竟就signalr使用,不考虑扔到 localStore 中占地方).
|
||||
*/
|
||||
if (options.config.cookie)
|
||||
options.config.cookie.set(options.url, header);
|
||||
// callback
|
||||
resolve(res);
|
||||
})
|
||||
.catch(function (res) {
|
||||
// print log
|
||||
_this.logger.log(LogLevel.Error, "handle response context is fail. \n ", res);
|
||||
// ! 这里为了兼容 signalR的错误格式,抛出继承了HttpError异常.
|
||||
var httpError = new HttpError(res.errMsg, res.statusCode);
|
||||
// callback - 合并后,返回,可以被认定为 继承 HttpError对象.
|
||||
reject(__assign(__assign({}, res), httpError));
|
||||
});
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); },
|
||||
fail: function (res) {
|
||||
var responseOptions = null;
|
||||
if (res && /request:fail socket time out timeout/.test(res.errMsg)) {
|
||||
// ! 这里为了兼容 signalR的错误格式,抛出继承了TimeoutError异常.
|
||||
responseOptions = __assign({ data: null, status: -1, errMsg: res.errMsg }, new TimeoutError(res.errMsg));
|
||||
}
|
||||
else {
|
||||
// ! 这里为了兼容 signalR的错误格式,抛出继承了HttpError异常.
|
||||
responseOptions = __assign({ data: null, status: -1, errMsg: res.errMsg }, new HttpError(res.errMsg, 500));
|
||||
}
|
||||
/**
|
||||
* @date 2019年12月11日 13:14:25
|
||||
* ! 修复bug,wx.request fail 情况下, 未调用 response 处理链.
|
||||
*/
|
||||
// 调用响应处理链(并返回结果)
|
||||
_this.handleResponse(responseOptions)
|
||||
.then(function (res) {
|
||||
// print debug
|
||||
_this.logger.log(LogLevel.Debug, "handle response context is success. \n", res);
|
||||
/**
|
||||
* check and cache cookie (if has) |
|
||||
* @description 这里因为 signalR的原因,内置了一个 cookies.js [library](https://github.com/jshttp/cookie/index.js)
|
||||
* 略有改写,暂时将cookie 扔到内存中维护(毕竟就signalr使用,不考虑扔到 localStore 中占地方).
|
||||
*/
|
||||
if (options.config.cookie)
|
||||
options.config.cookie.set(options.url, {});
|
||||
// callback
|
||||
resolve(res);
|
||||
})
|
||||
.catch(function (res) {
|
||||
// print log
|
||||
_this.logger.log(LogLevel.Error, "handle response context is fail. \n ", res);
|
||||
// ! 这里为了兼容 signalR的错误格式,抛出继承了HttpError异常.
|
||||
var httpError = new HttpError(res.errMsg, res.statusCode);
|
||||
// callback - 合并后,返回,可以被认定为 继承 HttpError对象.
|
||||
reject(__assign(__assign({}, res), httpError));
|
||||
});
|
||||
}
|
||||
});
|
||||
// 监听 headers 变化
|
||||
task.onHeadersReceived(function () {
|
||||
// 当检查到 about() 状态,中断请求
|
||||
if (_this.checkAbout(options.config, reject)) {
|
||||
// 中断请求
|
||||
task.abort();
|
||||
return;
|
||||
}
|
||||
});
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
};
|
||||
/**
|
||||
* 检查中断
|
||||
*
|
||||
* @memberof Request
|
||||
*/
|
||||
Request.prototype.checkAbout = function (options, reject) {
|
||||
if (options.config && options.config.about) {
|
||||
reject({
|
||||
data: null,
|
||||
header: options.headers,
|
||||
statusCode: 412,
|
||||
options: options,
|
||||
errMsg: "网络异常" // 直接自定义错误了.
|
||||
});
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* GET 请求
|
||||
* @description 封装调用
|
||||
* @param url 请求地址
|
||||
* @param data 请求参数
|
||||
* @param options 请求配置
|
||||
*/
|
||||
Request.prototype.get = function (url, data, options) {
|
||||
if (data === void 0) { data = {}; }
|
||||
// print execute step
|
||||
this.logger.log(LogLevel.Trace, "invoke request.get()");
|
||||
// merge config
|
||||
var requestOptions = __assign(__assign({}, (function () { return (options ? options : {}); })()), { method: RequestMethod.GET, url: url,
|
||||
data: data });
|
||||
// execute and response
|
||||
return this.executeRequest(requestOptions);
|
||||
};
|
||||
/**
|
||||
* POST 请求
|
||||
* @description 封装调用
|
||||
* @param url 请求地址
|
||||
* @param data 请求参数
|
||||
* @param options 请求配置
|
||||
*/
|
||||
Request.prototype.post = function (url, data, options) {
|
||||
if (data === void 0) { data = {}; }
|
||||
// print execute step
|
||||
this.logger.log(LogLevel.Trace, "invoke request.post()");
|
||||
// merge config
|
||||
var requestOptions = __assign(__assign({}, (function () { return (options ? options : {}); })()), { method: RequestMethod.POST, url: url,
|
||||
data: data });
|
||||
// execute and response
|
||||
return this.executeRequest(requestOptions);
|
||||
};
|
||||
/**
|
||||
* PUT 请求
|
||||
* @description 封装调用
|
||||
* @param url 请求地址
|
||||
* @param data 请求参数
|
||||
* @param options 请求配置
|
||||
*/
|
||||
Request.prototype.put = function (url, data, options) {
|
||||
if (data === void 0) { data = {}; }
|
||||
// print execute step
|
||||
this.logger.log(LogLevel.Trace, "invoke request.put()");
|
||||
// merge config
|
||||
var requestOptions = __assign(__assign({}, (function () { return (options ? options : {}); })()), { method: RequestMethod.PUT, url: url,
|
||||
data: data });
|
||||
// execute and response
|
||||
return this.executeRequest(requestOptions);
|
||||
};
|
||||
/**
|
||||
* DELETE 请求
|
||||
* @description 封装调用
|
||||
* @param url 请求地址
|
||||
* @param data 请求参数
|
||||
* @param options 请求配置
|
||||
*/
|
||||
Request.prototype.delete = function (url, data, options) {
|
||||
if (data === void 0) { data = {}; }
|
||||
// print execute step
|
||||
this.logger.log(LogLevel.Trace, "invoke request.delete()");
|
||||
// merge config
|
||||
var requestOptions = __assign(__assign({}, (function () { return (options ? options : {}); })()), { method: RequestMethod.DELETE, url: url,
|
||||
data: data });
|
||||
// execute and response
|
||||
return this.executeRequest(requestOptions);
|
||||
};
|
||||
/**
|
||||
* 多请求同步执行
|
||||
* @param taskQueue
|
||||
*/
|
||||
Request.prototype.all = function (taskQueue) {
|
||||
// print execute step
|
||||
this.logger.log(LogLevel.Trace, "invoke request.all()");
|
||||
// merge config
|
||||
return Promise.all(taskQueue);
|
||||
};
|
||||
/**
|
||||
* 用于兼容 @aspnet/signalR 的 获取 cookie 方法
|
||||
*
|
||||
* @description 这里用内存对象来维护一个 在线 cookies
|
||||
* @param {string} url
|
||||
* @returns
|
||||
* @memberof Request
|
||||
*/
|
||||
Request.prototype.getCookieString = function (url) {
|
||||
if (this.config && this.config.cookie) {
|
||||
return this.config.cookie.origin(url);
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
Request.prototype.cookie = function (url, key) {
|
||||
if (this.config && this.config.cookie) {
|
||||
return this.config.cookie.get(url, key);
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
return Request;
|
||||
}());
|
||||
export { Request };
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export { RequestMethod } from "./model/RequestMethod";
|
||||
export { ResponseType } from "./model/ResponseType";
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* 请求类型
|
||||
*/
|
||||
export var RequestMethod;
|
||||
(function (RequestMethod) {
|
||||
RequestMethod["GET"] = "GET";
|
||||
RequestMethod["POST"] = "POST";
|
||||
RequestMethod["PUT"] = "PUT";
|
||||
RequestMethod["DELETE"] = "DELETE";
|
||||
})(RequestMethod || (RequestMethod = {}));
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* 响应数据类型
|
||||
*
|
||||
* @interface ResponseType
|
||||
*/
|
||||
export var ResponseType;
|
||||
(function (ResponseType) {
|
||||
/**
|
||||
* JSON 类型
|
||||
*/
|
||||
ResponseType["JSON"] = "json";
|
||||
/**
|
||||
* 文本类型(跳过返回数据处理链,直接返回)
|
||||
*/
|
||||
ResponseType["TEXT"] = "text";
|
||||
/**
|
||||
* 二进制数据
|
||||
*/
|
||||
ResponseType["ARRAY_BUFFER"] = "arraybuffer";
|
||||
})(ResponseType || (ResponseType = {}));
|
||||
|
|
@ -1,17 +1,23 @@
|
|||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### ActionSheet Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
align | String | center | `0.29.0`。options:center/left | N
|
||||
style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets),used to set style on virtual component | N
|
||||
align | String | center | `0.29.0`。options: center/left | N
|
||||
cancel-text | String | - | \- | N
|
||||
count | Number | 8 | \- | N
|
||||
description | String | - | `0.29.0` | N
|
||||
items | Array | - | required。Typescript:`Array<string \| ActionSheetItem>` `interface ActionSheetItem {label: string; color?: string; disabled?: boolean }`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts) | Y
|
||||
items | Array | - | required。Typescript:`Array<string \| ActionSheetItem>` `interface ActionSheetItem {label: string; color?: string; disabled?: boolean;icon?: string;suffixIcon?: string; }`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts) | Y
|
||||
popup-props | Object | {} | Typescript:`PopupProps`,[Popup API Documents](./popup?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts) | N
|
||||
show-cancel | Boolean | true | \- | N
|
||||
theme | String | list | options:list/grid | N
|
||||
show-overlay | Boolean | true | \- | N
|
||||
theme | String | list | options: list/grid | N
|
||||
using-custom-navbar | Boolean | false | \- | N
|
||||
visible | Boolean | false | required | Y
|
||||
default-visible | Boolean | undefined | required。uncontrolled property | Y
|
||||
|
||||
|
|
@ -22,3 +28,25 @@ name | params | description
|
|||
cancel | \- | \-
|
||||
close | `(trigger: TriggerSource)` | [see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts)。<br/>`type TriggerSource = 'overlay' \| 'command' \| 'select' `<br/>
|
||||
selected | `(selected: ActionSheetItem \| string, index: number)` | \-
|
||||
### ActionSheet External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-cancel | \-
|
||||
t-class-content | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-action-sheet-border-color | @gray-color-1 | -
|
||||
--td-action-sheet-border-radius | @radius-extra-large | -
|
||||
--td-action-sheet-cancel-color | @font-gray-1 | -
|
||||
--td-action-sheet-cancel-height | 96rpx | -
|
||||
--td-action-sheet-color | @font-gray-1 | -
|
||||
--td-action-sheet-description-color | @font-gray-3 | -
|
||||
--td-action-sheet-list-item-disabled-color | @font-gray-4 | -
|
||||
--td-action-sheet-list-item-height | 112rpx | -
|
||||
--td-action-sheet-text-align | center | -
|
||||
|
|
@ -26,6 +26,12 @@ isComponent: true
|
|||
|
||||
## 代码演示
|
||||
|
||||
<a href="https://developers.weixin.qq.com/s/EM7cxim37USn" title="在开发者工具中预览效果" target="_blank" rel="noopener noreferrer"> 在开发者工具中预览效果 </a>
|
||||
|
||||
<blockquote style="background-color: #d9e1ff; font-size: 15px; line-height: 26px;margin: 16px 0 0;padding: 16px; border-radius: 6px; color: #0052d9" >
|
||||
<p>Tips: 请确保开发者工具为打开状态。导入开发者工具后,依次执行:npm i > 构建npm包 > 勾选 "将JS编译成ES5"</p>
|
||||
</blockquote>
|
||||
|
||||
### 组件类型
|
||||
|
||||
列表型动作面板
|
||||
|
|
@ -83,20 +89,25 @@ handler.close();
|
|||
|
||||
|
||||
## API
|
||||
|
||||
### ActionSheet Props
|
||||
|
||||
名称 | 类型 | 默认值 | 说明 | 必传
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
style | Object | - | 样式 | N
|
||||
custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N
|
||||
align | String | center | `0.29.0`。水平对齐方式。可选项:center/left | N
|
||||
cancel-text | String | - | 设置取消按钮的文本 | N
|
||||
count | Number | 8 | 设置每页展示菜单的数量,仅当 type=grid 时有效 | N
|
||||
description | String | - | `0.29.0`。动作面板描述文字 | N
|
||||
items | Array | - | 必需。菜单项。TS 类型:`Array<string \| ActionSheetItem>` `interface ActionSheetItem {label: string; color?: string; disabled?: boolean }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts) | Y
|
||||
items | Array | - | 必需。菜单项。TS 类型:`Array<string \| ActionSheetItem>` `interface ActionSheetItem {label: string; color?: string; disabled?: boolean;icon?: string;suffixIcon?: string; }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts) | Y
|
||||
popup-props | Object | {} | popupProps透传。TS 类型:`PopupProps`,[Popup API Documents](./popup?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts) | N
|
||||
show-cancel | Boolean | true | 是否显示取消按钮 | N
|
||||
show-overlay | Boolean | true | 是否显示遮罩层 | N
|
||||
theme | String | list | 展示类型,列表和表格形式展示。可选项:list/grid | N
|
||||
using-custom-navbar | Boolean | false | 是否使用了自定义导航栏 | N
|
||||
visible | Boolean | false | 必需。显示与隐藏 | Y
|
||||
default-visible | Boolean | undefined | 必需。显示与隐藏。非受控属性 | Y
|
||||
external-classes | Array | - | 组件类名,用于设置组件外层元素类名。`['t-class', 't-class-content', 't-class-cancel']` | N
|
||||
|
||||
### ActionSheet Events
|
||||
|
||||
|
|
@ -105,3 +116,25 @@ external-classes | Array | - | 组件类名,用于设置组件外层元素类
|
|||
cancel | \- | 点击取消按钮时触发
|
||||
close | `(trigger: TriggerSource)` | 关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts)。<br/>`type TriggerSource = 'overlay' \| 'command' \| 'select' `<br/>
|
||||
selected | `(selected: ActionSheetItem \| string, index: number)` | 选择菜单项时触发
|
||||
### ActionSheet External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-cancel | 取消样式类
|
||||
t-class-content | 内容样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-action-sheet-border-color | @gray-color-1 | -
|
||||
--td-action-sheet-border-radius | @radius-extra-large | -
|
||||
--td-action-sheet-cancel-color | @font-gray-1 | -
|
||||
--td-action-sheet-cancel-height | 96rpx | -
|
||||
--td-action-sheet-color | @font-gray-1 | -
|
||||
--td-action-sheet-description-color | @font-gray-3 | -
|
||||
--td-action-sheet-list-item-disabled-color | @font-gray-4 | -
|
||||
--td-action-sheet-list-item-height | 112rpx | -
|
||||
--td-action-sheet-text-align | center | -
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { SuperComponent } from '../common/src/index';
|
||||
export default class ActionSheet extends SuperComponent {
|
||||
static show: (options: import("./show").ActionSheetShowOption) => WechatMiniprogram.Component.TrivialInstance;
|
||||
behaviors: string[];
|
||||
externalClasses: string[];
|
||||
properties: {
|
||||
align?: {
|
||||
|
|
@ -22,22 +23,37 @@ export default class ActionSheet extends SuperComponent {
|
|||
items: {
|
||||
type: ArrayConstructor;
|
||||
value?: (string | import("./type").ActionSheetItem)[];
|
||||
required?: boolean;
|
||||
};
|
||||
popupProps?: {
|
||||
type: ObjectConstructor;
|
||||
value?: import("../popup").TdPopupProps;
|
||||
};
|
||||
showCancel?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
showOverlay?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
theme?: {
|
||||
type: StringConstructor;
|
||||
value?: "list" | "grid";
|
||||
};
|
||||
usingCustomNavbar?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
visible: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
defaultVisible: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
};
|
||||
data: {
|
||||
|
|
@ -45,6 +61,8 @@ export default class ActionSheet extends SuperComponent {
|
|||
classPrefix: string;
|
||||
gridThemeItems: any[];
|
||||
currentSwiperIndex: number;
|
||||
defaultPopUpProps: {};
|
||||
defaultPopUpzIndex: number;
|
||||
};
|
||||
controlledProps: {
|
||||
key: string;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ import { SuperComponent, wxComponent } from '../common/src/index';
|
|||
import config from '../common/config';
|
||||
import { ActionSheetTheme, show } from './show';
|
||||
import props from './props';
|
||||
import useCustomNavbar from '../mixins/using-custom-navbar';
|
||||
const { prefix } = config;
|
||||
const name = `${prefix}-action-sheet`;
|
||||
let ActionSheet = class ActionSheet extends SuperComponent {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.behaviors = [useCustomNavbar];
|
||||
this.externalClasses = [`${prefix}-class`, `${prefix}-class-content`, `${prefix}-class-cancel`];
|
||||
this.properties = Object.assign({}, props);
|
||||
this.data = {
|
||||
|
|
@ -21,6 +23,8 @@ let ActionSheet = class ActionSheet extends SuperComponent {
|
|||
classPrefix: name,
|
||||
gridThemeItems: [],
|
||||
currentSwiperIndex: 0,
|
||||
defaultPopUpProps: {},
|
||||
defaultPopUpzIndex: 11500,
|
||||
};
|
||||
this.controlledProps = [
|
||||
{
|
||||
|
|
@ -73,12 +77,18 @@ let ActionSheet = class ActionSheet extends SuperComponent {
|
|||
const realIndex = isSwiperMode ? index + currentSwiperIndex * count : index;
|
||||
if (item) {
|
||||
this.triggerEvent('selected', { selected: item, index: realIndex });
|
||||
this.trigger('close', { trigger: 'select' });
|
||||
this._trigger('visible-change', { visible: false });
|
||||
if (!item.disabled) {
|
||||
this.triggerEvent('close', { trigger: 'select' });
|
||||
this._trigger('visible-change', { visible: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
this.triggerEvent('cancel');
|
||||
if (this.autoClose) {
|
||||
this.setData({ visible: false });
|
||||
this.autoClose = false;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"component": true,
|
||||
"styleIsolation": "apply-shared",
|
||||
"usingComponents": {
|
||||
"t-icon": "../icon/icon",
|
||||
"t-popup": "../popup/popup",
|
||||
"t-grid": "../grid/grid",
|
||||
"t-grid-item": "../grid-item/grid-item",
|
||||
"t-swiper-nav": "../swiper-nav/swiper-nav"
|
||||
"t-grid-item": "../grid-item/grid-item"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,15 @@
|
|||
<import src="./template/grid.wxml" />
|
||||
|
||||
<view id="{{classPrefix}}" style="{{_._style([style, customStyle])}}" class="{{classPrefix}} class {{prefix}}-class">
|
||||
<t-popup visible="{{visible}}" placement="bottom" bind:visible-change="onPopupVisibleChange">
|
||||
<t-popup
|
||||
visible="{{visible}}"
|
||||
placement="bottom"
|
||||
usingCustomNavbar="{{usingCustomNavbar}}"
|
||||
bind:visible-change="onPopupVisibleChange"
|
||||
show-overlay="{{showOverlay}}"
|
||||
z-index="{{ popupProps.zIndex || defaultPopUpzIndex }}"
|
||||
overlay-props="{{ popupProps.overlayProps || defaultPopUpProps }}"
|
||||
>
|
||||
<view
|
||||
class="{{_.cls(classPrefix + '__content', [['grid', gridThemeItems.length]])}} {{prefix}}-class-content"
|
||||
tabindex="0"
|
||||
|
|
@ -25,7 +33,7 @@
|
|||
</view>
|
||||
</view>
|
||||
<slot />
|
||||
<view wx:if="{{showCancel}}" class="{{classPrefix}}__footer {{classPrefix}}__safe">
|
||||
<view wx:if="{{showCancel}}" class="{{classPrefix}}__footer">
|
||||
<view class="{{classPrefix}}__gap-{{theme}}" />
|
||||
<view
|
||||
class="{{classPrefix}}__cancel {{prefix}}-class-cancel"
|
||||
|
|
@ -34,7 +42,7 @@
|
|||
bind:tap="onCancel"
|
||||
aria-role="button"
|
||||
>
|
||||
{{ cancelText }}
|
||||
{{ cancelText || '取消' }}
|
||||
</view>
|
||||
</view>
|
||||
</t-popup>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
transform: scale(1.5);
|
||||
}
|
||||
.t-action-sheet__content {
|
||||
color: var(--td-action-sheet-color, var(--td-font-gray-1, rgba(0, 0, 0, 0.9)));
|
||||
color: var(--td-action-sheet-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
border-top-left-radius: var(--td-action-sheet-border-radius, var(--td-radius-extra-large, 24rpx));
|
||||
border-top-right-radius: var(--td-action-sheet-border-radius, var(--td-radius-extra-large, 24rpx));
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
padding-bottom: 48rpx;
|
||||
}
|
||||
.t-action-sheet__description {
|
||||
color: var(--td-action-sheet-description-color, var(--td-font-gray-3, rgba(0, 0, 0, 0.4)));
|
||||
color: var(--td-action-sheet-description-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
line-height: 44rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: var(--td-action-sheet-text-align, center);
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-gray-color-1, #f3f3f3));
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-action-sheet__description::after {
|
||||
height: 1px;
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-gray-color-1, #f3f3f3));
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-action-sheet__list-item::after {
|
||||
height: 1px;
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
left: 32rpx;
|
||||
}
|
||||
.t-action-sheet__list-item--disabled {
|
||||
color: var(--td-action-sheet-list-item-disabled-color, var(--td-font-gray-4, rgba(0, 0, 0, 0.26)));
|
||||
color: var(--td-action-sheet-list-item-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-action-sheet__list-item-text {
|
||||
font-size: var(--td-font-size-m, 32rpx);
|
||||
|
|
@ -123,6 +123,9 @@
|
|||
.t-action-sheet__list-item-icon {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.t-action-sheet__list-item-icon--suffix {
|
||||
margin-left: auto;
|
||||
}
|
||||
.t-action-sheet__swiper-wrap {
|
||||
margin-top: 8rpx;
|
||||
position: relative;
|
||||
|
|
@ -132,16 +135,17 @@
|
|||
}
|
||||
.t-action-sheet__gap-list {
|
||||
height: 16rpx;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-gray-color-1, #f3f3f3));
|
||||
background-color: var(--td-action-sheet-gap-color, var(--td-bg-color-page, var(--td-gray-color-1, #f3f3f3)));
|
||||
}
|
||||
.t-action-sheet__gap-grid {
|
||||
height: 1rpx;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-gray-color-1, #f3f3f3));
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-action-sheet__cancel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--td-action-sheet-cancel-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
height: var(--td-action-sheet-cancel-height, 96rpx);
|
||||
}
|
||||
.t-action-sheet__dots {
|
||||
|
|
@ -163,7 +167,3 @@
|
|||
.t-action-sheet__dots-item.t-is-active {
|
||||
background-color: #0052d9;
|
||||
}
|
||||
.t-action-sheet__safe {
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
import ActionSheet from './action-sheet';
|
||||
export * from './show';
|
||||
export default ActionSheet;
|
||||
/// <reference types="miniprogram-api-typings" />
|
||||
import { ActionSheetItem, ActionSheetTheme, ActionSheetShowOption } from './show';
|
||||
export { ActionSheetItem, ActionSheetTheme, ActionSheetShowOption };
|
||||
declare const _default: {
|
||||
show(options: ActionSheetShowOption): WechatMiniprogram.Component.TrivialInstance;
|
||||
close(options: ActionSheetShowOption): void;
|
||||
};
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
import ActionSheet from './action-sheet';
|
||||
export * from './show';
|
||||
export default ActionSheet;
|
||||
import { show, close, ActionSheetTheme } from './show';
|
||||
export { ActionSheetTheme };
|
||||
export default {
|
||||
show(options) {
|
||||
return show(options);
|
||||
},
|
||||
close(options) {
|
||||
return close(options);
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const props = {
|
|||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
value: '取消',
|
||||
value: '',
|
||||
},
|
||||
count: {
|
||||
type: Number,
|
||||
|
|
@ -17,22 +17,37 @@ const props = {
|
|||
},
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
popupProps: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
showCancel: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
showOverlay: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
value: 'list',
|
||||
},
|
||||
usingCustomNavbar: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
value: null,
|
||||
required: true,
|
||||
},
|
||||
defaultVisible: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
export default props;
|
||||
|
|
|
|||
|
|
@ -12,13 +12,15 @@ export declare enum ActionSheetTheme {
|
|||
Grid = "grid"
|
||||
}
|
||||
interface ActionSheetProps {
|
||||
visible: boolean;
|
||||
items: Array<string | ActionSheetItem>;
|
||||
defaultVisible?: boolean;
|
||||
align: 'center' | 'left';
|
||||
cancelText?: string;
|
||||
count?: number;
|
||||
description: string;
|
||||
items: Array<string | ActionSheetItem>;
|
||||
showCancel?: boolean;
|
||||
theme?: ActionSheetTheme;
|
||||
visible: boolean;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
export interface ActionSheetShowOption extends Omit<ActionSheetProps, 'visible'> {
|
||||
context?: Context;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@
|
|||
wx:key="index"
|
||||
bind:tap="onSelect"
|
||||
data-index="{{index}}"
|
||||
icon="{{item.icon}}"
|
||||
text="{{item.label}}"
|
||||
image="{{item.image}}"
|
||||
icon="{{ { name: item.icon, color: item.color } }}"
|
||||
text="{{item.label || ''}}"
|
||||
image="{{item.image || ''}}"
|
||||
style="--td-grid-item-text-color: {{item.color}}"
|
||||
>
|
||||
</t-grid-item>
|
||||
</t-grid>
|
||||
|
|
@ -27,9 +28,10 @@
|
|||
wx:key="index"
|
||||
data-index="{{index}}"
|
||||
bind:tap="onSelect"
|
||||
icon="{{item.icon}}"
|
||||
text="{{item.label}}"
|
||||
image="{{item.image}}"
|
||||
icon="{{ { name: item.icon, color: item.color } }}"
|
||||
text="{{item.label || ''}}"
|
||||
image="{{item.image || ''}}"
|
||||
style="--td-grid-item-text-color: {{item.color}}"
|
||||
>
|
||||
</t-grid-item>
|
||||
</t-grid>
|
||||
|
|
|
|||
|
|
@ -10,5 +10,11 @@
|
|||
>
|
||||
<t-icon wx:if="{{item.icon}}" name="{{item.icon}}" class="{{classPrefix}}__list-item-icon" size="48rpx"></t-icon>
|
||||
<view class="{{classPrefix}}__list-item-text">{{item.label || item}}</view>
|
||||
<t-icon
|
||||
wx:if="{{item.suffixIcon}}"
|
||||
name="{{item.suffixIcon}}"
|
||||
class="{{classPrefix}}__list-item-icon {{classPrefix}}__list-item-icon--suffix"
|
||||
size="48rpx"
|
||||
></t-icon>
|
||||
</view>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { PopupProps } from '../popup/index';
|
||||
export interface TdActionSheetProps {
|
||||
align?: {
|
||||
type: StringConstructor;
|
||||
|
|
@ -18,26 +19,43 @@ export interface TdActionSheetProps {
|
|||
items: {
|
||||
type: ArrayConstructor;
|
||||
value?: Array<string | ActionSheetItem>;
|
||||
required?: boolean;
|
||||
};
|
||||
popupProps?: {
|
||||
type: ObjectConstructor;
|
||||
value?: PopupProps;
|
||||
};
|
||||
showCancel?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
showOverlay?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
theme?: {
|
||||
type: StringConstructor;
|
||||
value?: 'list' | 'grid';
|
||||
};
|
||||
usingCustomNavbar?: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
};
|
||||
visible: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
defaultVisible: {
|
||||
type: BooleanConstructor;
|
||||
value?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
}
|
||||
export interface ActionSheetItem {
|
||||
label: string;
|
||||
color?: string;
|
||||
disabled?: boolean;
|
||||
icon?: string;
|
||||
suffixIcon?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,6 @@ export default class AvatarGroup extends SuperComponent {
|
|||
methods: {
|
||||
setClass(): void;
|
||||
handleMax(): void;
|
||||
handleChildCascading(): void;
|
||||
onCollapsedItemClick(e: WechatMiniprogram.CustomEvent): void;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ let AvatarGroup = class AvatarGroup extends SuperComponent {
|
|||
length: this.$children.length,
|
||||
});
|
||||
this.handleMax();
|
||||
this.handleChildCascading();
|
||||
},
|
||||
};
|
||||
this.observers = {
|
||||
|
|
@ -53,7 +52,8 @@ let AvatarGroup = class AvatarGroup extends SuperComponent {
|
|||
const classList = [
|
||||
name,
|
||||
`${prefix}-class`,
|
||||
`${name}-offset-${direction}-${size.indexOf('px') > -1 ? 'medium' : size}`,
|
||||
`${name}-offset-${direction}`,
|
||||
`${name}-offset-${direction}-${size.indexOf('px') > -1 ? 'medium' : size || 'medium'}`,
|
||||
];
|
||||
this.setData({
|
||||
className: classList.join(' '),
|
||||
|
|
@ -69,13 +69,8 @@ let AvatarGroup = class AvatarGroup extends SuperComponent {
|
|||
child.hide();
|
||||
});
|
||||
},
|
||||
handleChildCascading() {
|
||||
if (this.properties.cascading === 'right-up')
|
||||
return;
|
||||
const defaultZIndex = 100;
|
||||
this.$children.forEach((child, index) => {
|
||||
child.updateCascading(defaultZIndex - index * 10);
|
||||
});
|
||||
onCollapsedItemClick(e) {
|
||||
this.triggerEvent('collapsed-item-click', e.detail);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"component": true,
|
||||
"styleIsolation": "shared",
|
||||
"usingComponents": {
|
||||
"t-avatar": "../avatar/avatar"
|
||||
}
|
||||
|
|
|
|||