初始化

This commit is contained in:
yj 2024-11-20 17:29:49 +08:00
parent d281aab5b3
commit dd589f646c
2215 changed files with 33356 additions and 20836 deletions

19
api/form/index.ts Normal file
View File

@ -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',
})

50
api/meeting/index.ts Normal file
View File

@ -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
View File

@ -1,10 +1,5 @@
import gulpError from './utils/gulpError';
App({ App({
onShow() { onShow() {
if (gulpError !== 'gulpErrorPlaceHolder') {
wx.redirectTo({ }
url: `/pages/gulp-error/index?gulpError=${gulpError}`,
});
}
},
}); });

117
app.json
View File

@ -1,113 +1,24 @@
{ {
"pages": [ "pages": [
"pages/home/home", "pages/form/index",
"pages/button/button", "pages/meeting/index"
"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"]
}
], ],
"subpackages": [],
"usingComponents": { "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-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": { "window": {
"backgroundTextStyle": "light", "navigationStyle": "custom",
"navigationBarBackgroundColor": "#f6f6f6",
"backgroundColor": "#f6f6f6",
"navigationBarTitleText": "TDesign",
"navigationBarTextStyle": "black" "navigationBarTextStyle": "black"
}, },
"sitemapLocation": "sitemap.json" "sitemapLocation": "sitemap.json"
} }

View File

@ -1,19 +1,10 @@
image {
display: block;
}
page { page {
background: #f6f6f6; --td-button-primary-color: white;
} --td-button-primary-bg-color: #5575F2;
.demo { --td-button-primary-border-color: #5575F2;
padding-bottom: 56rpx; --td-switch-checked-color: #5575F2;
} }
.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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/icon1-active.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
assets/icon1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
assets/icon2-active.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/icon2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
assets/icon3-active.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
assets/icon3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
assets/icon4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
assets/icon5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
assets/icon6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
assets/icon7-active.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
assets/icon7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
assets/icon8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
assets/icon9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

View File

@ -1 +0,0 @@

View File

@ -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);
},
},
});

View File

@ -1,3 +0,0 @@
{
"component": true
}

View File

@ -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>

View File

@ -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);
}

View File

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -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%);
}
}
}

View File

@ -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() {
}
})

View File

@ -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>

View File

@ -1 +0,0 @@
declare const itemHeight: number;

View File

@ -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);
},
},
});

View File

@ -1,3 +0,0 @@
{
"component": true
}

View File

@ -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>

View File

@ -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;
}

View File

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -0,0 +1,16 @@
Component({
properties: {
},
data: {
height: 0
},
methods: {
},
ready() {
this.setData({
height: wx.getWindowInfo().statusBarHeight
})
}
})

View File

@ -0,0 +1 @@
<view style="height: {{height}}px;"></view>

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@
Component({});

View File

@ -1,3 +0,0 @@
{
"component": true
}

View File

@ -1,4 +0,0 @@
<view>
<t-radio class="basic-radio" title="单行标题" name="radio1"></t-radio>
<t-radio title="双行标题,长文本自动换行,该选项的描述是一段很长的内容" name="radio2"></t-radio>
</view>

View File

@ -1 +0,0 @@

View File

@ -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,
});
},
},
});

View File

@ -1,3 +0,0 @@
{
"component": true
}

View File

@ -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>

2
lib/agora-miniapp-sdk.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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"]}

File diff suppressed because one or more lines are too long

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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 };

View File

@ -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;

View File

@ -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 };

View File

@ -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 };

View File

@ -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;
}

View File

@ -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 };

View File

@ -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;
}

View File

@ -0,0 +1,2 @@
// 版权所有c.NET基金会。保留所有权利。
// 在2.0版Apache许可下授权。有关许可证信息请参见项目根目录中的License.txt。

View File

@ -0,0 +1,2 @@
// 版权所有c.NET基金会。保留所有权利。
// 在2.0版Apache许可下授权。有关许可证信息请参见项目根目录中的License.txt。

View File

@ -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 = {}));

View File

@ -0,0 +1,25 @@
// 版权所有c.NET基金会。保留所有权利。
// 在2.0版Apache许可下授权。有关许可证信息请参见项目根目录中的License.txt。
//这些值被设计为与ASP.NET日志级别匹配因为这是我们在这里模拟的模式。
/**
* 指示日志消息的严重性
* 日志级别按严重性递增的顺序排列所以DebugTrace等更严重
*
*/
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 = {}));

View File

@ -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 = {}));

View File

@ -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 };

View File

@ -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 };

View File

@ -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则客户端启动了stopstop方法将在发送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 };

View File

@ -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 = {}));

View File

@ -0,0 +1,2 @@
// 版权所有c.NET基金会。保留所有权利。
// 在2.0版Apache许可下授权。有关许可证信息请参见项目根目录中的License.txt。

View File

@ -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 };

View File

@ -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 };

View File

@ -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;
};

View File

@ -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 };

View File

@ -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";

View File

@ -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 };

View File

@ -0,0 +1,2 @@
export { RequestMethod } from "./model/RequestMethod";
export { ResponseType } from "./model/ResponseType";

View File

@ -0,0 +1,10 @@
/**
* 请求类型
*/
export var RequestMethod;
(function (RequestMethod) {
RequestMethod["GET"] = "GET";
RequestMethod["POST"] = "POST";
RequestMethod["PUT"] = "PUT";
RequestMethod["DELETE"] = "DELETE";
})(RequestMethod || (RequestMethod = {}));

View File

@ -0,0 +1,20 @@
/**
* 响应数据类型
*
* @interface ResponseType
*/
export var ResponseType;
(function (ResponseType) {
/**
* JSON 类型
*/
ResponseType["JSON"] = "json";
/**
* 文本类型(跳过返回数据处理链,直接返回)
*/
ResponseType["TEXT"] = "text";
/**
* 二进制数据
*/
ResponseType["ARRAY_BUFFER"] = "arraybuffer";
})(ResponseType || (ResponseType = {}));

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,23 @@
:: BASE_DOC :: :: BASE_DOC ::
## API ## API
### ActionSheet Props ### ActionSheet Props
name | type | default | description | required name | type | default | description | required
-- | -- | -- | -- | -- -- | -- | -- | -- | --
align | String | center | `0.29.0`。optionscenter/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 cancel-text | String | - | \- | N
count | Number | 8 | \- | N count | Number | 8 | \- | N
description | String | - | `0.29.0` | 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 show-cancel | Boolean | true | \- | N
theme | String | list | optionslist/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 visible | Boolean | false | required | Y
default-visible | Boolean | undefined | required。uncontrolled property | Y default-visible | Boolean | undefined | required。uncontrolled property | Y
@ -22,3 +28,25 @@ name | params | description
cancel | \- | \- 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/> 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)` | \- 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 | -

View File

@ -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 ## API
### ActionSheet Props ### ActionSheet Props
名称 | 类型 | 默认值 | 说明 | 必传 名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | -- -- | -- | -- | -- | --
style | Object | - | 样式 | N
custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N
align | String | center | `0.29.0`。水平对齐方式。可选项center/left | N align | String | center | `0.29.0`。水平对齐方式。可选项center/left | N
cancel-text | String | - | 设置取消按钮的文本 | N cancel-text | String | - | 设置取消按钮的文本 | N
count | Number | 8 | 设置每页展示菜单的数量,仅当 type=grid 时有效 | N count | Number | 8 | 设置每页展示菜单的数量,仅当 type=grid 时有效 | N
description | String | - | `0.29.0`。动作面板描述文字 | 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-cancel | Boolean | true | 是否显示取消按钮 | N
show-overlay | Boolean | true | 是否显示遮罩层 | N
theme | String | list | 展示类型列表和表格形式展示。可选项list/grid | N theme | String | list | 展示类型列表和表格形式展示。可选项list/grid | N
using-custom-navbar | Boolean | false | 是否使用了自定义导航栏 | N
visible | Boolean | false | 必需。显示与隐藏 | Y visible | Boolean | false | 必需。显示与隐藏 | Y
default-visible | Boolean | undefined | 必需。显示与隐藏。非受控属性 | Y default-visible | Boolean | undefined | 必需。显示与隐藏。非受控属性 | Y
external-classes | Array | - | 组件类名,用于设置组件外层元素类名。`['t-class', 't-class-content', 't-class-cancel']` | N
### ActionSheet Events ### ActionSheet Events
@ -105,3 +116,25 @@ external-classes | Array | - | 组件类名,用于设置组件外层元素类
cancel | \- | 点击取消按钮时触发 cancel | \- | 点击取消按钮时触发
close | `(trigger: TriggerSource)` | 关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/action-sheet/type.ts)。<br/>`type TriggerSource = 'overlay' \| 'command' \| 'select' `<br/> 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)` | 选择菜单项时触发 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 | -

View File

@ -1,6 +1,7 @@
import { SuperComponent } from '../common/src/index'; import { SuperComponent } from '../common/src/index';
export default class ActionSheet extends SuperComponent { export default class ActionSheet extends SuperComponent {
static show: (options: import("./show").ActionSheetShowOption) => WechatMiniprogram.Component.TrivialInstance; static show: (options: import("./show").ActionSheetShowOption) => WechatMiniprogram.Component.TrivialInstance;
behaviors: string[];
externalClasses: string[]; externalClasses: string[];
properties: { properties: {
align?: { align?: {
@ -22,22 +23,37 @@ export default class ActionSheet extends SuperComponent {
items: { items: {
type: ArrayConstructor; type: ArrayConstructor;
value?: (string | import("./type").ActionSheetItem)[]; value?: (string | import("./type").ActionSheetItem)[];
required?: boolean;
};
popupProps?: {
type: ObjectConstructor;
value?: import("../popup").TdPopupProps;
}; };
showCancel?: { showCancel?: {
type: BooleanConstructor; type: BooleanConstructor;
value?: boolean; value?: boolean;
}; };
showOverlay?: {
type: BooleanConstructor;
value?: boolean;
};
theme?: { theme?: {
type: StringConstructor; type: StringConstructor;
value?: "list" | "grid"; value?: "list" | "grid";
}; };
usingCustomNavbar?: {
type: BooleanConstructor;
value?: boolean;
};
visible: { visible: {
type: BooleanConstructor; type: BooleanConstructor;
value?: boolean; value?: boolean;
required?: boolean;
}; };
defaultVisible: { defaultVisible: {
type: BooleanConstructor; type: BooleanConstructor;
value?: boolean; value?: boolean;
required?: boolean;
}; };
}; };
data: { data: {
@ -45,6 +61,8 @@ export default class ActionSheet extends SuperComponent {
classPrefix: string; classPrefix: string;
gridThemeItems: any[]; gridThemeItems: any[];
currentSwiperIndex: number; currentSwiperIndex: number;
defaultPopUpProps: {};
defaultPopUpzIndex: number;
}; };
controlledProps: { controlledProps: {
key: string; key: string;

View File

@ -9,11 +9,13 @@ import { SuperComponent, wxComponent } from '../common/src/index';
import config from '../common/config'; import config from '../common/config';
import { ActionSheetTheme, show } from './show'; import { ActionSheetTheme, show } from './show';
import props from './props'; import props from './props';
import useCustomNavbar from '../mixins/using-custom-navbar';
const { prefix } = config; const { prefix } = config;
const name = `${prefix}-action-sheet`; const name = `${prefix}-action-sheet`;
let ActionSheet = class ActionSheet extends SuperComponent { let ActionSheet = class ActionSheet extends SuperComponent {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.behaviors = [useCustomNavbar];
this.externalClasses = [`${prefix}-class`, `${prefix}-class-content`, `${prefix}-class-cancel`]; this.externalClasses = [`${prefix}-class`, `${prefix}-class-content`, `${prefix}-class-cancel`];
this.properties = Object.assign({}, props); this.properties = Object.assign({}, props);
this.data = { this.data = {
@ -21,6 +23,8 @@ let ActionSheet = class ActionSheet extends SuperComponent {
classPrefix: name, classPrefix: name,
gridThemeItems: [], gridThemeItems: [],
currentSwiperIndex: 0, currentSwiperIndex: 0,
defaultPopUpProps: {},
defaultPopUpzIndex: 11500,
}; };
this.controlledProps = [ this.controlledProps = [
{ {
@ -73,12 +77,18 @@ let ActionSheet = class ActionSheet extends SuperComponent {
const realIndex = isSwiperMode ? index + currentSwiperIndex * count : index; const realIndex = isSwiperMode ? index + currentSwiperIndex * count : index;
if (item) { if (item) {
this.triggerEvent('selected', { selected: item, index: realIndex }); this.triggerEvent('selected', { selected: item, index: realIndex });
this.trigger('close', { trigger: 'select' }); if (!item.disabled) {
this._trigger('visible-change', { visible: false }); this.triggerEvent('close', { trigger: 'select' });
this._trigger('visible-change', { visible: false });
}
} }
}, },
onCancel() { onCancel() {
this.triggerEvent('cancel'); this.triggerEvent('cancel');
if (this.autoClose) {
this.setData({ visible: false });
this.autoClose = false;
}
}, },
}; };
} }

View File

@ -1,10 +1,10 @@
{ {
"component": true, "component": true,
"styleIsolation": "apply-shared",
"usingComponents": { "usingComponents": {
"t-icon": "../icon/icon", "t-icon": "../icon/icon",
"t-popup": "../popup/popup", "t-popup": "../popup/popup",
"t-grid": "../grid/grid", "t-grid": "../grid/grid",
"t-grid-item": "../grid-item/grid-item", "t-grid-item": "../grid-item/grid-item"
"t-swiper-nav": "../swiper-nav/swiper-nav"
} }
} }

View File

@ -4,7 +4,15 @@
<import src="./template/grid.wxml" /> <import src="./template/grid.wxml" />
<view id="{{classPrefix}}" style="{{_._style([style, customStyle])}}" class="{{classPrefix}} class {{prefix}}-class"> <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 <view
class="{{_.cls(classPrefix + '__content', [['grid', gridThemeItems.length]])}} {{prefix}}-class-content" class="{{_.cls(classPrefix + '__content', [['grid', gridThemeItems.length]])}} {{prefix}}-class-content"
tabindex="0" tabindex="0"
@ -25,7 +33,7 @@
</view> </view>
</view> </view>
<slot /> <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}}__gap-{{theme}}" />
<view <view
class="{{classPrefix}}__cancel {{prefix}}-class-cancel" class="{{classPrefix}}__cancel {{prefix}}-class-cancel"
@ -34,7 +42,7 @@
bind:tap="onCancel" bind:tap="onCancel"
aria-role="button" aria-role="button"
> >
{{ cancelText }} {{ cancelText || '取消' }}
</view> </view>
</view> </view>
</t-popup> </t-popup>

View File

@ -26,7 +26,7 @@
transform: scale(1.5); transform: scale(1.5);
} }
.t-action-sheet__content { .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-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)); 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)); background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
@ -45,7 +45,7 @@
padding-bottom: 48rpx; padding-bottom: 48rpx;
} }
.t-action-sheet__description { .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; line-height: 44rpx;
font-size: 28rpx; font-size: 28rpx;
text-align: var(--td-action-sheet-text-align, center); text-align: var(--td-action-sheet-text-align, center);
@ -63,7 +63,7 @@
bottom: 0; bottom: 0;
left: unset; left: unset;
right: 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 { .t-action-sheet__description::after {
height: 1px; height: 1px;
@ -93,7 +93,7 @@
bottom: 0; bottom: 0;
left: unset; left: unset;
right: 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 { .t-action-sheet__list-item::after {
height: 1px; height: 1px;
@ -111,7 +111,7 @@
left: 32rpx; left: 32rpx;
} }
.t-action-sheet__list-item--disabled { .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 { .t-action-sheet__list-item-text {
font-size: var(--td-font-size-m, 32rpx); font-size: var(--td-font-size-m, 32rpx);
@ -123,6 +123,9 @@
.t-action-sheet__list-item-icon { .t-action-sheet__list-item-icon {
margin-right: 16rpx; margin-right: 16rpx;
} }
.t-action-sheet__list-item-icon--suffix {
margin-left: auto;
}
.t-action-sheet__swiper-wrap { .t-action-sheet__swiper-wrap {
margin-top: 8rpx; margin-top: 8rpx;
position: relative; position: relative;
@ -132,16 +135,17 @@
} }
.t-action-sheet__gap-list { .t-action-sheet__gap-list {
height: 16rpx; 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 { .t-action-sheet__gap-grid {
height: 1rpx; 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 { .t-action-sheet__cancel {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: 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); height: var(--td-action-sheet-cancel-height, 96rpx);
} }
.t-action-sheet__dots { .t-action-sheet__dots {
@ -163,7 +167,3 @@
.t-action-sheet__dots-item.t-is-active { .t-action-sheet__dots-item.t-is-active {
background-color: #0052d9; background-color: #0052d9;
} }
.t-action-sheet__safe {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}

View File

@ -1,3 +1,8 @@
import ActionSheet from './action-sheet'; /// <reference types="miniprogram-api-typings" />
export * from './show'; import { ActionSheetItem, ActionSheetTheme, ActionSheetShowOption } from './show';
export default ActionSheet; export { ActionSheetItem, ActionSheetTheme, ActionSheetShowOption };
declare const _default: {
show(options: ActionSheetShowOption): WechatMiniprogram.Component.TrivialInstance;
close(options: ActionSheetShowOption): void;
};
export default _default;

View File

@ -1,3 +1,10 @@
import ActionSheet from './action-sheet'; import { show, close, ActionSheetTheme } from './show';
export * from './show'; export { ActionSheetTheme };
export default ActionSheet; export default {
show(options) {
return show(options);
},
close(options) {
return close(options);
},
};

View File

@ -5,7 +5,7 @@ const props = {
}, },
cancelText: { cancelText: {
type: String, type: String,
value: '取消', value: '',
}, },
count: { count: {
type: Number, type: Number,
@ -17,22 +17,37 @@ const props = {
}, },
items: { items: {
type: Array, type: Array,
required: true,
},
popupProps: {
type: Object,
value: {},
}, },
showCancel: { showCancel: {
type: Boolean, type: Boolean,
value: true, value: true,
}, },
showOverlay: {
type: Boolean,
value: true,
},
theme: { theme: {
type: String, type: String,
value: 'list', value: 'list',
}, },
usingCustomNavbar: {
type: Boolean,
value: false,
},
visible: { visible: {
type: Boolean, type: Boolean,
value: null, value: null,
required: true,
}, },
defaultVisible: { defaultVisible: {
type: Boolean, type: Boolean,
value: false, value: false,
required: true,
}, },
}; };
export default props; export default props;

View File

@ -12,13 +12,15 @@ export declare enum ActionSheetTheme {
Grid = "grid" Grid = "grid"
} }
interface ActionSheetProps { interface ActionSheetProps {
visible: boolean; align: 'center' | 'left';
items: Array<string | ActionSheetItem>;
defaultVisible?: boolean;
cancelText?: string; cancelText?: string;
count?: number; count?: number;
description: string;
items: Array<string | ActionSheetItem>;
showCancel?: boolean; showCancel?: boolean;
theme?: ActionSheetTheme; theme?: ActionSheetTheme;
visible: boolean;
defaultVisible?: boolean;
} }
export interface ActionSheetShowOption extends Omit<ActionSheetProps, 'visible'> { export interface ActionSheetShowOption extends Omit<ActionSheetProps, 'visible'> {
context?: Context; context?: Context;

View File

@ -8,9 +8,10 @@
wx:key="index" wx:key="index"
bind:tap="onSelect" bind:tap="onSelect"
data-index="{{index}}" data-index="{{index}}"
icon="{{item.icon}}" icon="{{ { name: item.icon, color: item.color } }}"
text="{{item.label}}" text="{{item.label || ''}}"
image="{{item.image}}" image="{{item.image || ''}}"
style="--td-grid-item-text-color: {{item.color}}"
> >
</t-grid-item> </t-grid-item>
</t-grid> </t-grid>
@ -27,9 +28,10 @@
wx:key="index" wx:key="index"
data-index="{{index}}" data-index="{{index}}"
bind:tap="onSelect" bind:tap="onSelect"
icon="{{item.icon}}" icon="{{ { name: item.icon, color: item.color } }}"
text="{{item.label}}" text="{{item.label || ''}}"
image="{{item.image}}" image="{{item.image || ''}}"
style="--td-grid-item-text-color: {{item.color}}"
> >
</t-grid-item> </t-grid-item>
</t-grid> </t-grid>

View File

@ -10,5 +10,11 @@
> >
<t-icon wx:if="{{item.icon}}" name="{{item.icon}}" class="{{classPrefix}}__list-item-icon" size="48rpx"></t-icon> <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> <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> </view>
</template> </template>

View File

@ -1,3 +1,4 @@
import { PopupProps } from '../popup/index';
export interface TdActionSheetProps { export interface TdActionSheetProps {
align?: { align?: {
type: StringConstructor; type: StringConstructor;
@ -18,26 +19,43 @@ export interface TdActionSheetProps {
items: { items: {
type: ArrayConstructor; type: ArrayConstructor;
value?: Array<string | ActionSheetItem>; value?: Array<string | ActionSheetItem>;
required?: boolean;
};
popupProps?: {
type: ObjectConstructor;
value?: PopupProps;
}; };
showCancel?: { showCancel?: {
type: BooleanConstructor; type: BooleanConstructor;
value?: boolean; value?: boolean;
}; };
showOverlay?: {
type: BooleanConstructor;
value?: boolean;
};
theme?: { theme?: {
type: StringConstructor; type: StringConstructor;
value?: 'list' | 'grid'; value?: 'list' | 'grid';
}; };
usingCustomNavbar?: {
type: BooleanConstructor;
value?: boolean;
};
visible: { visible: {
type: BooleanConstructor; type: BooleanConstructor;
value?: boolean; value?: boolean;
required?: boolean;
}; };
defaultVisible: { defaultVisible: {
type: BooleanConstructor; type: BooleanConstructor;
value?: boolean; value?: boolean;
required?: boolean;
}; };
} }
export interface ActionSheetItem { export interface ActionSheetItem {
label: string; label: string;
color?: string; color?: string;
disabled?: boolean; disabled?: boolean;
icon?: string;
suffixIcon?: string;
} }

View File

@ -23,6 +23,6 @@ export default class AvatarGroup extends SuperComponent {
methods: { methods: {
setClass(): void; setClass(): void;
handleMax(): void; handleMax(): void;
handleChildCascading(): void; onCollapsedItemClick(e: WechatMiniprogram.CustomEvent): void;
}; };
} }

View File

@ -38,7 +38,6 @@ let AvatarGroup = class AvatarGroup extends SuperComponent {
length: this.$children.length, length: this.$children.length,
}); });
this.handleMax(); this.handleMax();
this.handleChildCascading();
}, },
}; };
this.observers = { this.observers = {
@ -53,7 +52,8 @@ let AvatarGroup = class AvatarGroup extends SuperComponent {
const classList = [ const classList = [
name, name,
`${prefix}-class`, `${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({ this.setData({
className: classList.join(' '), className: classList.join(' '),
@ -69,13 +69,8 @@ let AvatarGroup = class AvatarGroup extends SuperComponent {
child.hide(); child.hide();
}); });
}, },
handleChildCascading() { onCollapsedItemClick(e) {
if (this.properties.cascading === 'right-up') this.triggerEvent('collapsed-item-click', e.detail);
return;
const defaultZIndex = 100;
this.$children.forEach((child, index) => {
child.updateCascading(defaultZIndex - index * 10);
});
}, },
}; };
} }

View File

@ -1,5 +1,6 @@
{ {
"component": true, "component": true,
"styleIsolation": "shared",
"usingComponents": { "usingComponents": {
"t-avatar": "../avatar/avatar" "t-avatar": "../avatar/avatar"
} }

Some files were not shown because too many files have changed in this diff Show More