UNPKG

kitten-cloud-function

Version:

用于编程猫源码云功能(云变量、云列表等)的客户端工具

255 lines (254 loc) 8.84 kB
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); } }