
# **参考手册**  

## 全局函数 
### + runtime getCurrentRuntime() 
常用接口，获得当前代码所在的RuntimeInstance对象。  
如果该函数返回null,说明框架没有正确初始化。  

### + app getCurrentApp()  
常用接口，获得当前的应用系统。  
如果该函数返回null,说明框架没有正确初始化。  

### + xar getCurrentXAR()
获取当前代码所属的xar，一般在xar的内部代码或者模块代码里面，用以获取当前所属的xar

### + initCurrentRuntime   
在各种javascript环境中用来初始化bucky的client runtime。根据javascript运行环境的不同，该函数可能有不同的参数。  
在小程序环境中初始化Bucky Runtime  

## 日志
#### + BX_XXX(content)
输出一行日志，内容为info,级别为一下可选值
* BX_DEBUG
* BX_TRACE
* BX_LOG
* BX_INFO  
* BX_WARN
* BX_ERROR 
* BX_FATAL

条件检测，功能类似于assert
* BX_CHECK
* BX_ASSERT

设置日志级别
>BX_SetLogLevel(levelstring)
其中levelstring可取值以下，设置后低于该级别的日志不再被输出

* BLOG_LEVEL_ALL
* BLOG_LEVEL_TRACE
* BLOG_LEVEL_DEBUG
* BLOG_LEVEL_INFO
* BLOG_LEVEL_WARN
* BLOG_LEVEL_ERROR
* BLOG_LEVEL_CHECK
* BLOG_LEVEL_FATAL
* BLOG_LEVEL_OFF



## Application  
Application对象，用来得到当前运行的分布式应用的信息  

### + void Application.init(metaInfo,function onInitComplete)  
异步初始化Application对象。Application对象会从core service中读取必要的信息，所以这个操作时异步的。  
#### 参数列表  
#### `metaInfo`：一般从app.json读取，内容如下：  
```
{
  "appid": "bx.demos.account",
  "repositoryHost": "https://dev.buckycloud.com/services/repository",
  "knowledgeHost": "https://dev.buckycloud.com/services/knowledge",
  "schedulerHost" : "https://dev.buckycloud.com/services/scheduler",
  "appver" : "1.0.0.1",
  "token" : "abcdef0123"
} 
```

appID是应用的唯一ID。  
repositoryHost与knowledgeHost是app运行依赖的核心服务地址。配置不同的服务器可以用来区分线上版本和开发版本。  
其中repositoryHost可以配置一个或者多个仓库地址，具体如下
```
"repositoryHost" : "https://xxxx",  // 如果直接配置一个字符串，则是默认是normal模式
"repositoryHost": {
    "value" : "xxxx",
    "type": "[normal/local/config]"
},
// 多个仓库配置
"repositoryHost" : [
    {
        "value" : "https://xxx",
        "type" : "normal"
    },{
        "value" : "[local dir]",
        "type" : "local"
    }, {
        "value" : "[packagelist]",
        "type" : "config"
    }
]
```
#### `onInitComplete`: function(erroCode,appInfo){...}  
当初始化完成后，会调用该函数。  

### + string Application.getID()  
返回Application的唯一ID.   

### + string Application.getRuntime()  
返回当前app绑定的runtime实例

### + string getKnowledgeHost()
获取配置的knowledge地址

### + string getSchedulerHost()
获取配置的scheduler地址

### + addRepository(type, value)
添加一个仓库地址，需要注意的是动态调整仓库地址要在初始化runtime之前

### + cleanRepository()
清除所有的仓库地址列表

### + array getRepositoryList()
获取所有的仓库地址列表


##RuntimeInfo  
用来表示一个具体的RuntimeInstance.这个对象应用开发很少使用，我们并不鼓励在应用逻辑中过于依赖某个具体的RuntimeInstance。  
#### `RuntimeInfo.runtime_id` : RuntimeInstance的唯一ID
#### `RuntimeInfo.runtime_type` : RuntimeInstance的类型 
#### `RuntimeInfo.device_id` : RuntimeInstance所在的设备ID  
#### `RuntimeInfo.device_type` : RuntimeInstance所在的设备类型  
#### `RuntimeInfo.app_id` : RuntimeInstance所属的Application ID。  
#### `RuntimeInfo.ability` : 当前runtime支持的能力列表  
#### `RuntimeInfo.drivers` : 当前runtime支持的驱动列表  
#### `RuntimeInfo.tag` : 当前runtime的标签列表
#### `RuntimeInfo.storages` : 当前runtime的绑定的存储路径列表

## RuntimeInstance  
核心对象。    
RuntimeInstance代表的是当前代码的运行环境。一般通过全局函数getCurrentRuntime()来获取。  

### + string RuntimeInstance.getID()  
返回当前Runtime的唯一ID  

### + Device RuntimeInstance.getOwnerDevice()  
返回当前Runtime所在的设备对象。  

### + Application RuntimeInstance.getOwnerApp()  
返回当前Runtime属于哪个Application. 通常该函数的返回等价于getCurrentApp()  


### + RuntimeInfo RuntimeInstance.createRuntimeInfo()
返回与指代RuntimeInstance的一个RuntimeInfo 

### + KnowledgeManager RuntimeInstance.getKnowledgeManager()
返回当前的Runtime所使用的KnowledegeManager对象。这是应用开发得到KnowledgeManager对象的主要方法。  

### + GlobalEventManager RuntimeInstance.getGlobalEventManager()
返回当前的Runtime所使用的GlobalEventManager对象。这是应用开发得到GlobalEventManager对象的主要方法。

### + XARManager RuntimeInstance.getXARManager()
返回当前的Runtime的XARManager，用以管理xar相关逻辑

### + UIEnv RuntimeInstance.getUIEnv()
返回当前的Runtime对应的uienv，只有在有前端情况下才会使用此接口，第一次调用该接口会自动创建对应的UIEnv

### + Driver RuntimeInstance.getDriver(string driverID)
得到一个驱动。驱动能否获取成功取决于当前Runtime所在的设备。  
驱动通常能提供一些功能，用于与旧世界打交道。应用开发应该尽量避免使用驱动。  
目前实现的驱动：(`小应用暂未开放加载驱动`)  
+ bx.mysql.client  
+ bx.mongo.client  

### + void RuntimeInstance.loadXARPackage(xarInfo xarID,function onComplete)
核心函数,用于加载一个指定的package

### + void RuntimeInstance.loadXARPackageEx(xarInfo xarID,function onComplete)
核心函数,用于加载一个指定的package，其中options可以指定该包的特性
options包含如下字段
* isProxy 需要加载的包是不是代理包
* originOnly 是不是只能加载本体包，而不能加载代理包

### + void RuntimeInstance.refreshXARPackage(xarInfo xarID)
刷新一个已经加载的xar包，下次使用该包会触发重新加载的流程

### + XARPackage RuntimeInstance.getXARPackage(xarInfo xarID)
返回当前RuntimeInstance已经加载成功的一个Package。  
这是一个同步函数。 

### + RuntimeInstance.loadModule(moduleFullID, function onComplete)
加载指定的模块，其中moduleFullID形如xarID:moduleID
onComplete(result, module)

### + RuntimeInstance.loadModules(moduleFullIDList, function onComplete)
加载指定的模块列表，其中moduleFullIDList形如[xarID:moduleID]数组，里面包含了多个moduleFullID
onComplete(moduleList)
其中moduleList[packageID][moduleID] = module


### + module RuntimeInstance.getModule(moduleID)
同步获取指定的模块，其中moduleID形如xarID:moduleID,
如果该模块已经加载，那么会同步返回该module，否则返回null

### + [result, exports] RuntimeInstance.loadFile(fileInfo)
同步加载指定的文件为模块，其中moduleID形如xarID:moduleID,
其中fileInfo包含以下字段
* path 文件路径
* content 文件内容


### + RuntimeInstance.selectTargetRuntime(packageID,packageInfo,useCache,onComplete)
为一个包选择一个合适的runtime
* packageID 包名称
* packageInfo package.json对应的内容
* useCache 是否使用缓存，不使用缓存会从scheduler查询，否则从本地和knowledge查询
* onComplete(ret, runtimeInfo)

### + RuntimeInstance.rpcCall(packageInfo, functionName, args, onComplete)
直接调用目标包里面的函数
* packageInfo 目标包的package.json
* functionName的定义参考BaseLib.parseFunctionName  
* args 调用的参数列表
* onComplete(result, errCode)


### - bool RuntimeInstance.isXARPackageCanLoad(packageInfo,string instanceID) 
判断当前Runtime是否允许`直接加载`目标XAR包。如果不允许，那么当前Runtime在加载目标XAR包时，会加载该XAR的proxy包



## XARPackage
代表Bucky框架里最重要一个基础概念，是对各种工程文件进行模块化以后，物理上的一个包。  
通常通过RuntimeInstance对象的loadXARPackage函数获得。  

### + packageInfo XARPackage.getPackageInfo()
返回该XARPackage定义在config.json中的配置信息。

### + [errorCode, Module] XARPackage.getModule(string moduleID)
通过模块ID获取XARPackage中的一个模块,加载结果同步返回。
XARPackage的config.json里定义了可以被加载的模块。
通过数组[errorCode, Module]返回结果。加载成功Module为非null值。

### XARPackage.isModuleExist(string moduleID)
判断模块是否存在。存在返回true.

### - XARPackage.loadLocalModule()
私有函数，微信小程序的环境加载js文件的方法较为特殊。

##Module
通过loadModule返回的对象，是一个包含所有导出函数的字典。
如果一个模块的结尾是按以下方法导出的：
>module.exports = {};
>module.exports.Login = Login;
>module.exports.Register = Register;

那么加载该模块返回的字典为
>{
>    "Login" : [Function],
>    "Register" : [Function]
>}

##RuntimeStorage 
Application所要永久保存的数据，最后一定会在某些Runtime上落地。当应用代码在这些有数据的Runtime上运行时，就能通过RuntimeStorage得到保存的数据。  
RuntimeStorage使用K-V设计来保存结构化数据。

### + RuntimeStorage.setObject（string objID,object objItem,function onComplete）
要求在当前Storage目录保存一个ObjectItem.保存完成后会触发onComplete通知
该调用成功后一定会触发一次磁盘写入。消耗App的磁盘空间资源和IO吞吐资源。

### + RuntimeStorage.getObject(string objID,function onComplete)
要求从当前Storage目录读取一个ObjectItem.读取成功通过onComplete返回。
该调用成功后一定会触发一次磁盘读取。消耗App的IO吞吐资源。

### + RuntimeStorage.removeObject(string objID,function onComplete)
要求从当前Storage目录删除一个ObjectItem。删除结果通过onComplete返回。
该调用成功后会释放App的磁盘空间资源，消耗一定的IO吞吐资源。

### + RuntimeStorage.isObjectExists(string objID,function onComplete)
判断当前Storage目录是否存在一个ObjectItem.判断结果通过onComplete返回。
该调用会消耗App的IO吞吐资源。

##RuntimeCache
`内测版暂未开放`

## ErrorCode
Bukcy使用一些通用的错误代码（还会持续增加）来表示API的结果。

+ `ErrorCode.RESULT_OK` : 0  表示成功
+ `ErrorCode.RESULT_TIMEOUT` : 操作超时失败
+ `ErrorCode.RESULT_WAIT_INIT` : 2 操作失败，需要等待初始化成功
+ `ErrorCode.RESULT_ERROR_STATE` : 3 操作失败，处于错误的状态
+ `ErrorCode.RESULT_NOT_FOUND` : 4 操作失败，对象未找到   
+ `ErrorCode.RESULT_SCRIPT_ERROR` : 5 操作失败，脚本错误  
+ `ErrorCode.RESULT_NO_IMP` : 6 操作失败，该功能未实现  
+ `ErrorCode.RESULT_ALREADY_EXIST` : 7 操作失败，对象已存在  
+ `ErrorCode.RESULT_UNKNOWN` : 8 操作失败，未知错误

## KnowledgeManager
知识管理器是Bucky的一个关键设计，用于管理／同步 分布式系统里的一些关键的全局状态。   
在开发者看来，可以把KnowledgeManager想象成一个全局变量管理器（读多写少，但写有强一致性保证）  
提供必要的并行同步设施。  
内测阶段请简单实用KnowledgeManager,我们以后会有更详细的文档来更全面的介绍该设施

### InfoNode
KnowledgeManager通过Key返回的一个指定的全局状态对象。为了方便应用开发，读操作被设计为同步的。
目前只支持两种数据类型，不同的数据类型有不同粒度的操作函数。 
+ Object
+ Map 

#### + int InfoNode.getType()
获得该全局对象的类型。

#### + int InfoNode.getState()
获得该全局对象当前的状态，正常使用下能拿到的InfoNode的状态都是STATE_READY

#### + Object InfoNode.objectRead()
如果该状态的类型是Object,那么返回该Object

#### + void InfoNode.objectUpdate(Object newObj,function onComplete)
如果该状态的类型是Object，那么异步更新该全局状态。
`内测版未支持`  

#### + Object InfoNode.mapGet(string key)
如果该状态的类型是Map,那么返回key对应的value对象。  

#### + void InfoNode.mapSet(string key,Object objItem,function onComplete)
如果该状态的类型是Map，那么异步更新设置key对应的value对象为objItem。 更新结果通过onComplete返回。
`内测版未支持`  

#### + void InfoNode.mapGetClone()
如果该状态的类型是Map，那么返回整个map（通常用于便利)  

### + InfoNode KnowledgeManager.getKnowledge(string key)
核心函数，通过key返回一个全局状态对象。该函数是同步的。
该key必需通过KnowledgeManager.dependKnowledge事先要求依赖了。

### + void KnowledgeManager.dependKnowledge(string key,Object options)
核心函数，Runtime要求依赖key指定的全局状态。  

### + void KnowledgeManager.ready(function onReady)
核心函数，调用后当前所有依赖的全局状态如果都已同步完成，会触发onReady通知。

### + int KnowledgeManager.getState()
返回当前KnowledgeManager的状态。一般不需要调用函数。  

### - string KnowledgeManager.getInfoURL(string key)
私有函数  

### - void KnowledgeManager.addknowledgeKey(string key,InfoNode aNode)
私有函数  

### - void KnowledgeManager.removeknowledgeKey(string key)
私有函数   

##BaseLib
BaseLib定义了大量的功能性静态函数。
这是Bucky框架为了统一各个js运行时库的差异提供的基础功能库。框架会保证这些功能函数在不同的JS环境中都能工作，应用开发应该尽量使用BaseLib中提供的功能来完成需求。
如果您在开发过程中有基础功能的需求而该功能又不在BaseLib中，请给我们提Issue :)
`内测阶段BaseLib的功能函数以满足我们自己的需要为主，以后还会进一步调整和整理`

### + int BaseLib.setTimer(function func,int timeout)
创建一个timer,每隔timeout指定的毫秒的时间过去后，会执行func。
调用成功返回timerID

### + void BaseLib.killTimer(timerID)
停止一个timer。timerID由setTimer函数返回。

### + void BaseLib.setOnceTimer(function func,int timeout)
创建一个一次性的timer.经过timeout指定的毫秒时间后func被调用。

### + BaseLib.asynCall(function func)
发起一次`异步调用`，func函数会在被投递到下一个消息循环中调用。
非常有用的小函数，特别是用在处理某些事件的时候。

### + string BaseLib.hash(string method,string content,string format)  
通用hash函数，对content做method指定的hash算法，并把结果按format指定的格式返回  
目前method只支持md5  
format只支持  

### + string BaseLib.md5(string content,string format)
相当于调用 
>BaseLib.hash("md5",content,format)

### + int BaseLib.getRandomNum(min,max)
返回[min,max)之间的一个随机正数。  

### + string BaseLib.createGUID()
创建一个GUID String。 

### + bool BaseLib.isArrayContained(StringArray a,StringArray b)
判断一个字符串数组a是否被另一个字符串数组b包含。  

### + int BaseLib.inet_aton(string IP)
将一个"10.10.10.1"这样的字符串转换为32位整数  

### + string BaseLib.inet_ntoa(int num)
将一个32位整数转化为"10.10.10.1"这样的IP String  

### + FunctionInfo BaseLib.parseFunctionName(string functionName)
解析一个符合Bukcy定义的FunctionName.FunctionName看起来如下 $xarPackageID:$moudeID::$funcName@$runtimeInstanceID  
返回一个对象
```
{
  "packageInfo":"",
  "moduleID":"",
  "functionID":"",
  "instanceID":""
}
```

### + void BaseLib.loadFileFromURL(string fileURL,function onComplete)
从一个URL使用HTTP GET方法异步加载文件，结果通过onComplete回调返回。  

### + void BaseLib.loadJSONFromURL(string fileURL,function onComplete)
从一个URL使用HTTP GET方法异步加载文件，并假设该文件的内容是一个JOSN.把解析的结果通过onComplete回调返回。  

### + void BaseLib.postJSON(string postURL,Object postBody,function onComplete)
往postURL使用HTTP POST方法发送一个用json编码的postBody,通过onComplete返回服务器的结果。  

### + void BaseLib.postData(string postURL,string postBody,function onComplete)
往postURL使用HTTP POST方法发送一个postBody,通过onComplete返回服务器的结果。    

### - void BaseLib.runScriptFromURL(string fileURL,function onComplete)
私有函数

### - void BaseLib.wxHttpRequest()
私有函数，用于兼容微信小程序的HttpRequest





## Device
一般通过RuntimeInstance的getOwnerDevice得到。代表当前Runtime所在的计算设备。

### DeviceInfo 对象
代表系统中的一个可计算设备（不一定是当前的可计算设备）
当应用系统
#### `DeviceID` : 设备的唯一ID
#### `Type` : 设备的类型。目前有以下可用值  
+ "*"  可模拟任意设备（只有本地调试模式会使用）  
+ pc_server 后台服务器  
+ wx_client 微信小程序客户端  
+ browser_client 浏览器客户端  
#### `IsOnline` : 设备是否在线  
#### `Ability` : 设备的能力列表 `目前小应用云所有的设备都支持 wlan-interface,storage`
#### `Drivers` : 设备支持的驱动列表 `目前小应用云未提供任何驱动`

### + string Device.getDeviceID()
得到设备的ID   

### + Array Device.getAbility()
得到设备的能力列表 `目前小应用云所有的设备都支持 wlan-interface,storage`   

### + string Device.getDeviceType()
得到设备的类型。目前有以下可用值    
+ "*"  可模拟任意设备（只有本地调试模式会使用）  
+ pc_server 后台服务器  
+ wx_client 微信小程序客户端  
+ browser_client 浏览器客户端  

### + bool Device.isDriverInstalled(string driverID)
查询是否支持某个指定的驱动  

### + DeviceInfo Device.createDeviceInfo()
创建代表当前设备的DeviceInfo对象  



## GlobalEventManager
依赖Knowledge作为底层系统实现的全局事件系统。

### - GlobalEventManager.createEvent(string eventID, function onComplete)
创建一个事件，只有创建成功的事件才能被其他用户attach
**每一个被创建的事件都会占用一定的系统资源！请务必确定事件不再使用的时候销毁掉!**

### - GlobalEventManager.removeEvent(string eventID)
移除一个事件，被移除的事件不能被fire或attach，同时会释放event占用的资源

### - GlobalEventManager.attach(string eventID,function onEvent, function onComplete)
关注一个事件，当有事件通知到达时，调用onEvent(param), attach动作结束后调用onComplete(ret, cookie)函数，ret==0表示连接成功, cookie用来detach事件；eventID必须事先create成功

### - GlobalEventManager.detach(string eventID, integer cookie)
不再关注这个事件，cookie会在attach的onComplete里返回。只有attach成功时才需要detach事件

### - GlobalEventManager.fireEvent(string eventID, string param)
发起一次事件通知，会调用所有已经attach这个事件用户的onEvent(param)方法。我们建议param为一个json字符串，方便事件扩展

### - GlobalEventManager.attachListenerChanged(string eventID,function onEvent, function onComplete)
关注监听者改变事件，每当用户attach到这个事件，或从事件detach时，会调用onEvent(param)，其余参数与attach相同

### - GlobalEventManager.detachListenerChanged(string eventID, integer cookie)
不再关注监听者改变事件，用法与detach函数相同

### - GlobalEventManager.getListenerList(string eventID, function onComplete)
得到所有的事件监听者列表，在onComplete(ret, list)中返回

### - GlobalEventManager.isEventCreated(string eventID)
私有函数




