Skip to content

Commit 719cfe4

Browse files
committed
feat: 新增完整初始化与历史记录标记功能
1 parent 6d6046c commit 719cfe4

File tree

3 files changed

+153
-92
lines changed

3 files changed

+153
-92
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "next-flow-interface",
3-
"version": "0.23.11",
3+
"version": "0.23.12",
44
"description": "Interface package for NEXT FlOW. You can use this package to build your own plugin that can control anything.",
55
"type": "module",
66
"module": "dist/index.js",

src/service/sync/step/node/rv-node-service-api.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ export default interface RvNodeServiceApi {
3838
forEach(callback: (node: StoredRhineVar<RvNode>, sid: string) => void, nid: string): void
3939

4040
// 遍历每个Step中的指定的多个Node
41-
forEachMulti(callback: (nodes: Map<string, RvNode>, sid: string) => void, nidList: string[]): void
41+
forEachMulti(
42+
callback: (nodes: Map<string, StoredRhineVar<RvNode>>, sid: string) => void,
43+
nidList: string[],
44+
): void
4245

4346
// 遍历每个Step中的所有Node
4447
forEachMap(callback: (nodes: RecursiveMap<RvNode>, sid: string) => void): void

src/utils/rv-utils.ts

Lines changed: 148 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,174 @@
11
import { RvPath, StoredRhineVar } from 'rhine-var'
22

3-
export function makeRvPath(path: string): RvPath {
4-
const rvPath: RvPath = []
5-
for (const item of path.split('.')) {
6-
const num = parseInt(item, 10)
7-
if (!isNaN(num) && item === num.toString()) {
8-
rvPath.push(num)
9-
} else {
10-
rvPath.push(item)
3+
/**
4+
* RvPath 路径工具类
5+
* 提供 RvPath 的创建、转换、访问和比较等功能
6+
*/
7+
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
8+
export class RvUtils {
9+
/**
10+
* 将字符串路径转换为 RvPath 数组
11+
* @param path - 以点分隔的路径字符串,如 "a.0.b"
12+
* @returns RvPath 数组,数字字符串会被转换为数字类型
13+
* @example
14+
* RvUtils.makeRvPath("a.0.b") // ['a', 0, 'b']
15+
*/
16+
static makeRvPath(path: string): RvPath {
17+
const rvPath: RvPath = []
18+
for (const item of path.split('.')) {
19+
const num = parseInt(item, 10)
20+
if (!isNaN(num) && item === num.toString()) {
21+
rvPath.push(num)
22+
} else {
23+
rvPath.push(item)
24+
}
1125
}
26+
return rvPath
1227
}
13-
return rvPath
14-
}
15-
16-
export function makeRvPathString(path: RvPath): string {
17-
return path.join('.')
18-
}
1928

20-
export function ensureRvPath(path: string | RvPath): RvPath {
21-
if (typeof path === 'string') {
22-
return makeRvPath(path)
29+
/**
30+
* 将 RvPath 数组转换为字符串路径
31+
* @param path - RvPath 数组
32+
* @returns 以点分隔的路径字符串
33+
* @example
34+
* RvUtils.makeRvPathString(['a', 0, 'b']) // "a.0.b"
35+
*/
36+
static makeRvPathString(path: RvPath): string {
37+
return path.join('.')
2338
}
24-
return path
25-
}
2639

27-
export function ensureRvPathString(path: string | RvPath): string {
28-
if (typeof path !== 'string') {
29-
return makeRvPathString(path)
40+
/**
41+
* 确保路径为 RvPath 数组格式
42+
* @param path - 字符串路径或 RvPath 数组
43+
* @returns RvPath 数组
44+
*/
45+
static ensureRvPath(path: string | RvPath): RvPath {
46+
if (typeof path === 'string') {
47+
return RvUtils.makeRvPath(path)
48+
}
49+
return path
3050
}
31-
return path
32-
}
3351

34-
export function getByRvPath(
35-
source: StoredRhineVar | Record<string | number, unknown>,
36-
path: string | RvPath,
37-
): unknown {
38-
const resolvedPath = ensureRvPath(path)
39-
let obj: unknown = source
40-
for (const key of resolvedPath) {
41-
if (obj === undefined || obj === null) {
42-
return undefined
52+
/**
53+
* 确保路径为字符串格式
54+
* @param path - 字符串路径或 RvPath 数组
55+
* @returns 字符串路径
56+
*/
57+
static ensureRvPathString(path: string | RvPath): string {
58+
if (typeof path !== 'string') {
59+
return RvUtils.makeRvPathString(path)
4360
}
44-
obj = (obj as Record<string | number, unknown>)[key]
61+
return path
4562
}
46-
return obj
47-
}
4863

49-
export function setByRvPath(source: StoredRhineVar, path: string | RvPath, value: unknown): void {
50-
const resolvedPath = ensureRvPath(path)
51-
let obj: Record<string | number, unknown> = source as Record<string | number, unknown>
52-
for (let i = 0; i < resolvedPath.length - 1; i++) {
53-
obj = obj[resolvedPath[i]] as Record<string | number, unknown>
64+
/**
65+
* 根据路径从对象中获取值
66+
* @typeParam T - 返回值的类型
67+
* @param source - 源对象
68+
* @param path - 访问路径
69+
* @returns 路径对应的值,如果路径不存在则返回 undefined
70+
* @example
71+
* RvUtils.getByRvPath({ a: { b: 1 } }, "a.b") // 1
72+
*/
73+
static getByRvPath<T = unknown>(
74+
source: StoredRhineVar | Record<string | number, unknown>,
75+
path: string | RvPath,
76+
): T | undefined {
77+
const resolvedPath = RvUtils.ensureRvPath(path)
78+
let obj: unknown = source
79+
for (const key of resolvedPath) {
80+
if (obj === undefined || obj === null) {
81+
return undefined
82+
}
83+
obj = (obj as Record<string | number, unknown>)[key]
84+
}
85+
return obj as T
5486
}
55-
obj[resolvedPath[resolvedPath.length - 1]] = value
56-
}
5787

58-
// 检查两段路径是否完全重叠,长度可不同,开头相同。指从开头开始每一项比较,直到有一方结束,是否全部相同
59-
export function checkRvPathOverlay(from: RvPath | string, target: RvPath | string): boolean {
60-
const fromPath = ensureRvPath(from)
61-
const targetPath = ensureRvPath(target)
62-
const n = fromPath.length > targetPath.length ? targetPath.length : fromPath.length
63-
for (let i = 0; i < n; i++) {
64-
if (fromPath[i] != targetPath[i]) {
65-
return false
88+
/**
89+
* 根据路径设置对象中的值
90+
* @param source - 源对象
91+
* @param path - 设置路径
92+
* @param value - 要设置的值
93+
* @example
94+
* const obj = { a: { b: 1 } }
95+
* RvUtils.setByRvPath(obj, "a.b", 2) // obj.a.b === 2
96+
*/
97+
static setByRvPath(source: StoredRhineVar, path: string | RvPath, value: unknown): void {
98+
const resolvedPath = RvUtils.ensureRvPath(path)
99+
let obj: Record<string | number, unknown> = source as Record<string | number, unknown>
100+
for (let i = 0; i < resolvedPath.length - 1; i++) {
101+
obj = obj[resolvedPath[i]] as Record<string | number, unknown>
66102
}
103+
obj[resolvedPath[resolvedPath.length - 1]] = value
67104
}
68-
return true
69-
}
70105

71-
export function checkAnyRvPathOverlay(
72-
from: RvPath | string,
73-
targetList: (RvPath | string)[],
74-
): boolean {
75-
const fromPath = ensureRvPath(from)
76-
return targetList.some((target) => checkRvPathOverlay(fromPath, target))
77-
}
106+
/**
107+
* 检查两段路径是否完全重叠
108+
* 长度可不同,从开头开始每一项比较,直到有一方结束,是否全部相同
109+
* @param from - 第一个路径
110+
* @param target - 第二个路径
111+
* @returns 如果路径重叠则返回 true
112+
* @example
113+
* RvUtils.checkRvPathOverlay("a.b", "a.b.c") // true
114+
* RvUtils.checkRvPathOverlay("a.b", "a.c") // false
115+
*/
116+
static checkRvPathOverlay(from: RvPath | string, target: RvPath | string): boolean {
117+
const fromPath = RvUtils.ensureRvPath(from)
118+
const targetPath = RvUtils.ensureRvPath(target)
119+
const n = fromPath.length > targetPath.length ? targetPath.length : fromPath.length
120+
for (let i = 0; i < n; i++) {
121+
if (fromPath[i] != targetPath[i]) {
122+
return false
123+
}
124+
}
125+
return true
126+
}
78127

79-
// 检查两段路径是否完全相同
80-
export function checkRvPathSame(from: RvPath | string, target: RvPath | string): boolean {
81-
const fromPath = ensureRvPath(from)
82-
const targetPath = ensureRvPath(target)
83-
if (fromPath.length !== targetPath.length) {
84-
return false
128+
/**
129+
* 检查路径是否与目标列表中的任意路径重叠
130+
* @param from - 要检查的路径
131+
* @param targetList - 目标路径列表
132+
* @returns 如果与任意目标路径重叠则返回 true
133+
*/
134+
static checkAnyRvPathOverlay(from: RvPath | string, targetList: (RvPath | string)[]): boolean {
135+
const fromPath = RvUtils.ensureRvPath(from)
136+
return targetList.some((target) => RvUtils.checkRvPathOverlay(fromPath, target))
85137
}
86-
for (let i = 0; i < fromPath.length; i++) {
87-
if (fromPath[i] !== targetPath[i]) {
138+
139+
/**
140+
* 检查两段路径是否完全相同
141+
* @param from - 第一个路径
142+
* @param target - 第二个路径
143+
* @returns 如果路径完全相同则返回 true
144+
* @example
145+
* RvUtils.checkRvPathSame("a.b", "a.b") // true
146+
* RvUtils.checkRvPathSame("a.b", "a.b.c") // false
147+
*/
148+
static checkRvPathSame(from: RvPath | string, target: RvPath | string): boolean {
149+
const fromPath = RvUtils.ensureRvPath(from)
150+
const targetPath = RvUtils.ensureRvPath(target)
151+
if (fromPath.length !== targetPath.length) {
88152
return false
89153
}
154+
for (let i = 0; i < fromPath.length; i++) {
155+
if (fromPath[i] !== targetPath[i]) {
156+
return false
157+
}
158+
}
159+
return true
90160
}
91-
return true
92-
}
93161

94-
export function checkAnyRvPathSame(
95-
from: RvPath | string,
96-
targetList: (RvPath | string)[],
97-
): boolean {
98-
const fromPath = ensureRvPath(from)
99-
return targetList.some((target) => checkRvPathSame(fromPath, target))
100-
}
101-
102-
// Create a namespace object for backward compatibility
103-
const RvUtils = {
104-
makeRvPath,
105-
makeRvPathString,
106-
ensureRvPath,
107-
ensureRvPathString,
108-
getByRvPath,
109-
setByRvPath,
110-
checkRvPathSame,
111-
checkAnyRvPathSame,
112-
checkRvPathOverlay,
113-
checkAnyRvPathOverlay,
162+
/**
163+
* 检查路径是否与目标列表中的任意路径完全相同
164+
* @param from - 要检查的路径
165+
* @param targetList - 目标路径列表
166+
* @returns 如果与任意目标路径相同则返回 true
167+
*/
168+
static checkAnyRvPathSame(from: RvPath | string, targetList: (RvPath | string)[]): boolean {
169+
const fromPath = RvUtils.ensureRvPath(from)
170+
return targetList.some((target) => RvUtils.checkRvPathSame(fromPath, target))
171+
}
114172
}
115173

116174
export default RvUtils

0 commit comments

Comments
 (0)