kitten-cloud-function
Version:
用于编程猫源码云功能(云变量、云列表等)的客户端工具
255 lines (254 loc) • 8.84 kB
JavaScript
import { __diff } from "../../kitten-cloud-function";
import { None } from "../../utils/other";
import { Signal } from "../../utils/signal";
import { KittenCloudData } from "./kitten-cloud-data";
import { KittenCloudListAddCommand } from "./update/command/kitten-cloud-list-add-command";
import { KittenCloudListEmptyCommand } from "./update/command/kitten-cloud-list-empty-command";
import { KittenCloudListPopCommand } from "./update/command/kitten-cloud-list-pop-command";
import { KittenCloudListPushCommand } from "./update/command/kitten-cloud-list-push-command";
import { KittenCloudListRemoveCommand } from "./update/command/kitten-cloud-list-remove-command";
import { KittenCloudListReplaceCommand } from "./update/command/kitten-cloud-list-replace-command";
import { KittenCloudListReplaceLastCommand } from "./update/command/kitten-cloud-list-replace-last-command";
import { KittenCloudListUnshiftCommand } from "./update/command/kitten-cloud-list-unshift-command";
import { KittenCloudDataUpdateSource } from "./update/kitten-cloud-data-update-source";
/**
* 云列表。
*/
export class KittenCloudList extends KittenCloudData {
constructor(connection, group, cvid, name, value) {
super(connection, group, cvid, name);
this.group = group;
this.value = value;
this.pushed = new Signal();
this.unshifted = new Signal();
this.added = new Signal();
this.popped = new Signal();
this.removed = new Signal();
this.emptied = new Signal();
this.replacedLast = new Signal();
this.replaced = new Signal();
this.replacedAll = new Signal();
}
update(value) {
const diff = this.compareTo(KittenCloudDataUpdateSource.CLOUD, value);
for (const command of diff) {
this.updateManager.addUpdateCommand(command);
}
}
compareTo(source, value) {
if (__diff == null) {
throw new Error("diff 未导入");
}
const diff = __diff.diffArrays(this.value, value);
let position = 0;
const result = [];
for (const change of diff) {
if (!change.removed && !change.added) {
position += change.value.length;
}
else if (change.removed) {
for (let i = 0; i < change.value.length; i++) {
result.push(new KittenCloudListRemoveCommand(source, this, position));
}
}
else if (change.added) {
let value = None;
const { length } = change.value;
while ((value = change.value.pop()) != None) {
result.push(new KittenCloudListAddCommand(source, this, position, value));
}
position += length;
}
else {
throw new Error("未预期的数组差异");
}
}
return result;
}
/**
* 添加新的项到云列表尾部。
*
* @param value 添加的新的项的值
*/
push(value) {
value = this.singleValueProcess(value);
const command = new KittenCloudListPushCommand(KittenCloudDataUpdateSource.LOCAL, this, value);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 添加新的项到云列表头部。
*
* @param value 添加的新的项的值
*/
unshift(value) {
value = this.singleValueProcess(value);
const command = new KittenCloudListUnshiftCommand(KittenCloudDataUpdateSource.LOCAL, this, value);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 添加新的项到云列表指定位置。
*
* @param index 位置索引,从 0 开始
* @param value 添加的新的项的值
*/
add(index, value) {
value = this.singleValueProcess(value);
const command = new KittenCloudListAddCommand(KittenCloudDataUpdateSource.LOCAL, this, index, value);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 移除云列表最后一项。
*/
pop() {
const command = new KittenCloudListPopCommand(KittenCloudDataUpdateSource.LOCAL, this);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 移除云列表指项。
*
* @param index 位置索引,从 0 开始
*/
remove(index) {
const command = new KittenCloudListRemoveCommand(KittenCloudDataUpdateSource.LOCAL, this, index);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 清空云列表。
*/
empty() {
const command = new KittenCloudListEmptyCommand(KittenCloudDataUpdateSource.LOCAL, this);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 替换云列表最后一项。
*
* @param value 新的值
*/
replaceLast(value) {
value = this.singleValueProcess(value);
const command = new KittenCloudListReplaceLastCommand(KittenCloudDataUpdateSource.LOCAL, this, value);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 替换云列表指定项。
*
* @param index 位置索引,从 0 开始
* @param value 新的值
*/
replace(index, value) {
value = this.singleValueProcess(value);
const command = new KittenCloudListReplaceCommand(KittenCloudDataUpdateSource.LOCAL, this, index, value);
this.updateManager.addUpdateCommand(command);
command.promise.catch((error) => {
this.connection.errored.emit(error);
});
return command.promise;
}
/**
* 从源列表复制所有项到云列表。
*
* 该操作会对比源列表和云列表,并将差异应用到云列表。
*
* @param source 源列表
*/
copyFrom(source) {
if (source instanceof KittenCloudList) {
source = source.value;
}
source = source.map((item) => this.singleValueProcess(item));
const diff = this.compareTo(KittenCloudDataUpdateSource.LOCAL, source);
for (const command of diff) {
this.updateManager.addUpdateCommand(command);
}
return Promise.all(diff).then(() => { });
}
/**
* 获取一份云列表当前状态的副本数组。
*
* @returns 云列表当前状态的副本数组
*/
copy() {
return this.value.slice();
}
/**
* 获取云列表指定位置的项。
*
* @param index 位置索引,从 0 开始
* @returns 指定位置的项,如果索引越界则返回 `None`
*/
get(index) {
return this.value[index];
}
/**
* 获取云列表的长度。
*
* @returns 云列表的长度
*/
get length() {
return this.value.length;
}
/**
* 获取指定项在云列表中第一次出现的位置。
*
* @param item 要查找的项
* @returns 指定项在云列表中第一次出现的位置,如果不存在则返回 `-1`
*/
indexOf(item) {
return this.value.indexOf(item);
}
/**
* 获取指定项在云列表中最后一次出现的位置。
*
* @param item 要查找的项
* @returns 指定项在云列表中最后一次出现的位置,如果不存在则返回 `-1`
*/
lastIndexOf(item) {
return this.value.lastIndexOf(item);
}
/**
* 判断指定项是否在云列表中。
*
* @param item 要查找的项
* @returns 指定项是否在云列表中
*/
includes(item) {
return this.value.includes(item);
}
/**
* 用指定字符串连接云列表中的所有项。
*
* @param separator 项之间的分隔符
* @returns 连接后的字符串
*/
join(separator) {
return this.value.join(separator);
}
}