• Stars
    star
    433
  • Rank 100,464 (Top 2 %)
  • Language
    TypeScript
  • Created almost 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Isomorphic JavaScript SDK for Teambition APIs

CircleCI Coverage Status Dependency Status devDependency Status

isomorphic-sdk for Teambition APIs

Greenkeeper badge

安装

npm install teambition-sdk --save-dev

如果要求在不支持 Fetch API 的浏览器运行,请安装 polyfill 如 whatwg-fetch

开发

目前主分支是 release,而 master 只应用于部分处于维护状态的老项目。常用命令如:

yarn               # 安装依赖
npm run build_test # 构建测试
npm test           # 跑一遍完整测试
npm watch          # 在开发时,以监听模式跑测试,每次代码修改都会重跑测试,帮助及时发现问题

发布

注意目前发布要求使用 NPM 二步验证,请参考文档,在发布命令后面跟随 --otp=验证码

# only publish sdk
npm run preversion   # 查询 npm 官方库,获取当前发布的最新正式版本和最高的预发版本号,避免打版本时出错
npm version v0.12.68 # 打正式版本 0.12.68(包括创建相应标签)
npm version v0.12.69-alpha.0-readme # 打预发版本 0.12.69-alpha.0-readme(包括创建相应标签)
npm run publish_sdk  # 在本地 build 当前代码并发布到 npm 官方库
# 完成发布后,推荐将相应标签(tag)推到远端,如 `git push origin v0.12.69-alpha.0-readme`

# publish sdk, mock and socket
npm version xxx
npm run publish_all

设计理念

SDK 主要解决的是数据同步的问题。通俗点讲,就是在前端使用数据模型模拟出数据库的增删改查等操作。

为什么会有这种需求? 以 https://api.teambition.com/tasks/:_id 为例, Teambition 的 API 会返回下面格式的数据:

{
  "_id": "001",
  "name": "task",
  "executor": {
    "_id": "002",
    "name": "executor 1",
    "avatarUrl": "https://xxx"
  },
  "subtasks": [
    {
      "_id": "003",
      "name": "subtask",
      "executor": {
        "_id": "004",
        "name": "executor 2",
        "avatarUrl": "https://xxx"
      }
    }
  ]
}

而倘若这个任务中包含的子对象,比如 executor 字段对应的数据通过其它 API 进行了变更:

/**
 * @url https://api.teambition.com/subtasks/:_id
 * @method put
 * @body {name: 'executor test'}
 */
SubtasksAPI.update('002', {
  name: 'subtask update'
})
  .subscribe()

在前端,需要自行处理与此 subtask 相关的所有变更情况。例如:

  1. 包含这个子任务的列表中的这个子任务名字的变更。
  2. 包含这个子任务的任务的详情页中,该子任务名字的变更。

然而在现有的 Teambition 数据模型中,需要在每一个 Model 或者 Collection 或者 View 中手动监听与自己相关联的数据,例如:

// 匹配第一种情况
class MyTasksView extends Backbone.View {
  ...
  listen() {
    this.listenTo(warehouse, ':change:task', model => {
      // handler
    })
    this.listenTo(warehouse, ':change:subtask', model => {
      // handler
    })
  }
}
// 匹配第二种情况

class SubtaskCollection extends Backbone.Collection {
  ...

  constructor() {
    this.on('add destroy remove change:isDone', () =>
      Socket.trigger(`:change:task/${this._boundToObjectId}`, {
        subtaskCount: {
          total: this.length
          done: this.getDoneSubTaskCount()
        }
      })
    )
  }
  getDoneSubTaskCount() {
    this.where({isDone: true}).length
  }
}

class TaskView extends Backbone.View {
  ...
  listen() {
    this.listenTo(this.taskModel, 'change', this.render)
  }
}

而在当前的设计中,所有的这种变更情况都在数据层处理,视图/业务 层只需要订阅一个数据源,这个数据源随后的所有变更都会通知到订阅者。 比如获取一个任务:

import 'rxjs/add/operator/distinctUntilKeyChanged'
import 'teambition-sdk/apis/task'
import { SDK } from 'teambition-sdk/SDK'
import { Component, Input } from '@angular/core'

@Component({
  selector: 'task-detail',
  template: `
    <div> {{ task$?.name | async }} </div>
    <div> {{ subtaskCount$ | async }} </div>
  `
})
export default class TaskView {

  @Input('taskId') taskId: string

  private task$ = this.SDK.getTask(this.taskId)
    .publishReplay(1)
    .refCount()

  private subtaskCount$ = this.task$
    .distinctUntilKeyChanged('subtasks')
    .map(task => ({
      total: task.subtasks.length,
      done: task.subtasks.filter(x => x.isDone).length
    }))
}

如果更加纯粹的使用 RxJS,甚至可以组合多种数据和业务:

import 'rxjs/add/operator/distinctUntilKeyChanged'
import 'rxjs/add/operator/distinctUntilChanged'
import 'teambition-sdk/apis/permission'
import 'teambition-sdk/apis/task'
import 'teambition-sdk/apis/project'
import { SDK } from 'teambition-sdk'
import { Component, Input } from '@angular/core'
import * as moment from 'moment'
import { errorHandler } from '../errorHandler'

@Component({
  selector: 'task-detail',
  template: `
    <div [ngClass]="{'active': permission$.canEdit | async}"></div>
    <div> {{ task$?.name | async }} </div>
    <div> {{ subtaskCount$ | async }} </div>
    <div> {{ dueDate$ | async }} </div>
  `
})
export default class TaskView {

  @Input('taskId') taskId: string

  private task$ = SDK.getTask(this.taskId)
    .catch(err => errorHandler(err))
    .publishReplay(1)
    .refCount()

  private subtaskCount$ = this.task$
    .distinctUntilKeyChanged('subtasks')
    .map(task => ({
      total: task.subtasks.length,
      done: task.subtasks.filter(x => x.isDone).length
    }))

  private dueDate$ = this.task$
    .map(task => moment(task.dueDate).format())

  private project$ = this.task$
    .distinctUntilKeyChanged('_projectId')
    .switchMap(task => SDK.getProject(task._projectId))
    .catch(err => errorHandler(err))
    .publishReplay(1)
    .refCount()

  private permission$ = this.task$
    .distinctUntilChanged((before, after) => {
      return before._executorId === after._executorId &&
        before._projectId === after._projectId
    })
    .switchMap(task => {
      return this.project$
        .distinctUntilKeyChanged('_defaultRoleId')
        .switchMap(project => {
          return SDK.getPermission(task, project)
        })
    })
    .catch(err => errorHandler(err))
    .publishReplay(1)
    .refCount()

在这种场景下,关于 task 的任何变更 (tasklist 变更,executor 变更,stage 变更等等,权限变化) 都能让相关的数据自动更新,从而简化 View 层的逻辑。

More Repositories

1

then.js

[快照]史上最快,与 node callback 完美结合的异步流程控制库!
JavaScript
573
star
2

gear

A lightweight, composable and high performance web service framework for Go.
Go
551
star
3

rrule-go

Go library for working with recurrence rules for calendar dates.
Go
313
star
4

TBEmptyDataSet

An extension of UITableView/UICollectionView's super class, it will display a placeholder emptyDataSet when the data of tableView/collectionView is empty.
Swift
206
star
5

Hire

Working With Great People
200
star
6

gulp-sequence

Run a series of gulp tasks in order
JavaScript
195
star
7

gulp-ssh

SSH and SFTP tasks for gulp
JavaScript
183
star
8

merge2

Merge multiple streams into one stream in sequence or parallel (~119M/month downloads).
JavaScript
171
star
9

DropdownMenu

Dropdown menu for NavigationController in Swift, also support Dropup Menu
Swift
133
star
10

snapper-core

Teambition push messaging service, backed by redis.
JavaScript
115
star
11

webapp-solutions

Try to collect anwsers on problems we encounter in Web Apps
113
star
12

ReactiveDB

Reactive ORM for Lovefield
TypeScript
105
star
13

jsonrpc-lite

Parse and Serialize JSON-RPC2 messages in node.js, or browser.
JavaScript
95
star
14

ratelimiter-go

The fastest abstract rate limiter, base on go-redis/redis.
Go
93
star
15

RRuleSwift

Swift rrule library for working with recurrence rules of calendar dates.
JavaScript
90
star
16

swaggo

Convert Go annotations to Swagger Documentation (version 2.0)
Go
68
star
17

SegmentedControl

A highly customizable segmented control for iOS applications.
Swift
64
star
18

HanziPinyin

A lightweight Swift library supporting convertion between Chinese(both Simplified and Tranditional) characters and Pinyin.
Swift
57
star
19

WebBrowser

A web browser using WebKit and written in Swift for iOS apps.
Swift
55
star
20

timed-queue

Distributed timed job queue, backed by Redis.
JavaScript
50
star
21

pdfviewer

PDF Viewer using Mozilla PDF JS
JavaScript
49
star
22

AMRAudioSwift

A useful tool to encode or decode audio between AMR and WAVE.
Swift
38
star
23

CardStyleTableView

An extension of UITableView and UITableViewCell which displays a card style view in grouped tableView, similar to the system's tableView before iOS 7.
Swift
32
star
24

trie-mux

A minimal and powerful trie based url path router (or mux) for Go.
Go
27
star
25

Pocket-Node-SDK

Headless Node.js SDK for integrating with [Pocket](http://getpocket.com/)
CoffeeScript
23
star
26

TB-Icons

A classified icons set that consists of a part of Material Design icons and some original icons by TB-UI team. Available in Icon Fonts and SVG Symbols.
Stylus
23
star
27

limbo

Factory/Loader of mongoose
CoffeeScript
17
star
28

json-mask-go

👺 JSON mask for Go
Go
10
star
29

tb-i18n-loader

i18n loader of teambition web for webpack
JavaScript
9
star
30

tws-auth

Node.js SDK of TWS (Teambition Web Service) client.
TypeScript
8
star
31

snapper-swift

Snapper-core client by Swift 2.0
Swift
8
star
32

node-teambition

JavaScript
7
star
33

redlimit

RedLimit is a redis-based distributed rate limit HTTP service, implemented with Rust.
Rust
7
star
34

tb-apps-sdk

Teambition API Bridge
TypeScript
7
star
35

teambition-node-sdk

teambition node sdk for server applications
TypeScript
6
star
36

WeChatSDK

Swift version of WeChat SDK.
Objective-C
5
star
37

node-chinese-finance-number

JavaScript
4
star
38

smart-limiter

Smart rate limiter middleware for express.
JavaScript
4
star
39

urbs-setting

Urbs 灰度平台灰度策略服务
Go
4
star
40

ilog

light-weight, smart and pure log module
JavaScript
3
star
41

teambition-java-sdk

teambition java sdk for server applications
Java
3
star
42

pipe-errors

Handle errors on piping streams and pipe error to the end.
JavaScript
3
star
43

i18n-middleware

An i18n middleware built for web apps.
CoffeeScript
2
star
44

grpclb

grpclb policy that consistent hash implemention, base on discovery systems like etcd, consul etc.
Go
2
star
45

teambition-server-sdk

TypeScript
2
star
46

gem-next

general entity manager next generation
TypeScript
2
star
47

tws-tcm

Node.js SDK of TWS (Teambition Web Service) cloud messaging service
TypeScript
1
star